#!/bin/bash

set -euo pipefail

########################################
# CONFIG
########################################

REPO_URL="https://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@github.com/nitishup94/chat-application.git"
BRANCH="main"

BASE_DIR="/home/www/html/deployment/gitmanager"
PROJECT_DIR="$BASE_DIR/chat-application"

ADMIN_BUILD_DIR="$PROJECT_DIR/admin"
STUDY_BUILD_DIR="$PROJECT_DIR/studyplanner"
CLIENT_BUILD_DIR="$PROJECT_DIR/client"
API_BUILD_DIR="$PROJECT_DIR/api"
PHP_STUDY_BUILD_DIR="$PROJECT_DIR/studyplaner-backend/study"

ADMIN_TARGET="/home/www/html/mainadmin"
STUDY_TARGET="/home/www/html/studyplanner"
CLIENT_TARGET="/home/www/html/chat/client"
API_TARGET="/home/www/html/chat/api"
PHP_STUDY_TARGET="/home/www/html/eplanning/backend/study"

BACKUP_DIR="/home/www/html/deployment/deployment_bkp"
LOG_DIR="/home/www/html/deployment/logs"

TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
LOG_FILE="$LOG_DIR/deploy_$TIMESTAMP.log"
DEPLOY_ADMIN=false
DEPLOY_STUDY=false
DEPLOY_CLIENT=false
DEPLOY_API=false
DEPLOY_PHP_STUDY=false
DID_DEPLOY_ADMIN=false
DID_DEPLOY_STUDY=false
DID_DEPLOY_CLIENT=false
DID_DEPLOY_API=false
DID_DEPLOY_PHP_STUDY=false

########################################
# COLOR THEME (HACKER STYLE)
########################################

CLR_RESET='\033[0m'
CLR_NEON_GREEN='\033[1;92m'
CLR_CYAN='\033[1;96m'
CLR_RED='\033[1;91m'
CLR_YELLOW='\033[1;93m'

banner() { printf "${CLR_CYAN}%s${CLR_RESET}\n" "$1"; }
step() { printf "${CLR_NEON_GREEN}%s${CLR_RESET}\n" "$1"; }
warn() { printf "${CLR_YELLOW}%s${CLR_RESET}\n" "$1"; }
err() { printf "${CLR_RED}%s${CLR_RESET}\n" "$1"; }
ok() { printf "${CLR_NEON_GREEN}%s${CLR_RESET}\n" "$1"; }

########################################
# INIT LOGGING
########################################

mkdir -p "$LOG_DIR"
exec > >(tee -a "$LOG_FILE") 2>&1

banner "==============================="
banner "DEPLOY START: $TIMESTAMP"
banner "==============================="

########################################
# ERROR HANDLER (ROLLBACK)
########################################

rollback() {
    err "❌ ERROR OCCURRED! Starting rollback..."

    ADMIN_BACKUP=$(ls -dt $BACKUP_DIR/mainadmin_* 2>/dev/null | head -n 1)
    STUDY_BACKUP=$(ls -dt $BACKUP_DIR/studyplanner_* 2>/dev/null | head -n 1)
    CLIENT_BACKUP=$(ls -dt $BACKUP_DIR/chat_client_dist_* 2>/dev/null | head -n 1)
    API_BACKUP=$(ls -dt $BACKUP_DIR/chat_api_* 2>/dev/null | head -n 1)
    PHP_STUDY_BACKUP=$(ls -dt $BACKUP_DIR/php_study_* 2>/dev/null | head -n 1)

    if [ "$DID_DEPLOY_ADMIN" = true ] && [ -n "$ADMIN_BACKUP" ]; then
        step "==> Restoring admin..."
        rm -rf "$ADMIN_TARGET"
        mkdir -p "$ADMIN_TARGET"
        cp -r "$ADMIN_BACKUP"/* "$ADMIN_TARGET"/
    fi

    if [ "$DID_DEPLOY_STUDY" = true ] && [ -n "$STUDY_BACKUP" ]; then
        step "==> Restoring studyplanner..."
        rm -rf "$STUDY_TARGET"
        mkdir -p "$STUDY_TARGET"
        cp -r "$STUDY_BACKUP"/* "$STUDY_TARGET"/
    fi

    if [ "$DID_DEPLOY_CLIENT" = true ] && [ -n "$CLIENT_BACKUP" ]; then
        step "==> Restoring chat client dist..."
        rm -rf "$CLIENT_TARGET/dist"
        mkdir -p "$CLIENT_TARGET"
        cp -r "$CLIENT_BACKUP/dist" "$CLIENT_TARGET/"
    fi

    if [ "$DID_DEPLOY_API" = true ] && [ -n "$API_BACKUP" ]; then
        step "==> Restoring chat api (except uploads)..."
        mkdir -p "$API_TARGET"
        find "$API_TARGET" -mindepth 1 -maxdepth 1 ! -name uploads -exec rm -rf {} +
        cp -r "$API_BACKUP"/* "$API_TARGET"/
        cd "$API_TARGET"
        npm install
        pm2 restart chat-api
    fi

    if [ "$DID_DEPLOY_PHP_STUDY" = true ] && [ -n "$PHP_STUDY_BACKUP" ]; then
        step "==> Restoring php study..."
        mkdir -p "$PHP_STUDY_TARGET"
        find "$PHP_STUDY_TARGET" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
        cp -r "$PHP_STUDY_BACKUP"/* "$PHP_STUDY_TARGET"/
    fi

    ok "✅ Rollback completed"
    exit 1
}

trap rollback ERR

########################################
# STEP 1: CLONE OR PULL
########################################

step "==> Checking repo..."

if [ ! -d "$PROJECT_DIR" ]; then
    step "==> Cloning repo..."
    git clone -b "$BRANCH" "$REPO_URL" "$PROJECT_DIR"
    DEPLOY_ADMIN=true
    DEPLOY_STUDY=true
    DEPLOY_CLIENT=true
    DEPLOY_API=true
    DEPLOY_PHP_STUDY=true
else
    step "==> Pulling latest code..."
    cd "$PROJECT_DIR"
    OLD_HEAD=$(git rev-parse HEAD)
    git pull origin "$BRANCH"
    NEW_HEAD=$(git rev-parse HEAD)

    if [ "$OLD_HEAD" = "$NEW_HEAD" ]; then
        warn "==> No new commits found. Nothing to deploy."
        banner "==============================="
        ok "✅ DEPLOY SUCCESS: $TIMESTAMP (no changes)"
        banner "==============================="
        exit 0
    fi

    CHANGED_FILES=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD")
    step "==> Changed files:"
    echo "$CHANGED_FILES"

    if echo "$CHANGED_FILES" | grep -Eq '^admin/'; then
        DEPLOY_ADMIN=true
    fi

    if echo "$CHANGED_FILES" | grep -Eq '^studyplanner/'; then
        DEPLOY_STUDY=true
    fi

    if echo "$CHANGED_FILES" | grep -Eq '^client/'; then
        DEPLOY_CLIENT=true
    fi

    if echo "$CHANGED_FILES" | grep -Eq '^api/'; then
        DEPLOY_API=true
    fi

    if echo "$CHANGED_FILES" | grep -Eq '^studyplaner-backend/study/'; then
        DEPLOY_PHP_STUDY=true
    fi

    if echo "$CHANGED_FILES" | grep -Evq '^(admin/|studyplanner/|client/|api/|studyplaner-backend/study/)'; then
        warn "==> Shared/root files changed. Deploying all services for safety."
        DEPLOY_ADMIN=true
        DEPLOY_STUDY=true
        DEPLOY_CLIENT=true
        DEPLOY_API=true
        DEPLOY_PHP_STUDY=true
    fi
fi

########################################
# STEP 2: ADMIN BUILD
########################################

if [ "$DEPLOY_ADMIN" = true ]; then
echo "==> Building admin..."

cd "$ADMIN_BUILD_DIR"

cat <<EOT > .env
VITE_API_BASE_URL=https://eplanning.mystudyplanner.in/backend/
EOT

npm install
npm run build

if [ ! -d "$ADMIN_BUILD_DIR/dist" ]; then
    echo "❌ Admin build failed"
    exit 1
fi

########################################
# CLEAN ADMIN NODE_MODULES
########################################

echo "==> Cleaning admin node_modules..."
rm -rf "$ADMIN_BUILD_DIR/node_modules"

########################################
# STEP 3: BACKUP ADMIN
########################################

echo "==> Backing up admin..."

mkdir -p "$BACKUP_DIR"

if [ -d "$ADMIN_TARGET" ]; then
    cp -r "$ADMIN_TARGET" "$BACKUP_DIR/mainadmin_$TIMESTAMP"
fi

########################################
# STEP 4: DEPLOY ADMIN
########################################

echo "==> Deploying admin..."

rm -rf "$ADMIN_TARGET"
mkdir -p "$ADMIN_TARGET"

cp -r "$ADMIN_BUILD_DIR/dist/"* "$ADMIN_TARGET"/
DID_DEPLOY_ADMIN=true
else
    echo "==> Skipping admin (no admin changes detected)"
fi

########################################
# STEP 5: STUDYPLANNER BUILD
########################################

if [ "$DEPLOY_STUDY" = true ]; then
echo "==> Building studyplanner..."

cd "$STUDY_BUILD_DIR"

cat <<EOT > .env
VITE_API_BASE_URL=https://eplanning.mystudyplanner.in/backend/
VITE_SERVER_IMAGE_URL=https://eplanning.mystudyplanner.in/uploads/
VITE_CHAT_APP_URL=https://chat.mystudyplanner.in
EOT

npm install
npm run build

if [ ! -d "$STUDY_BUILD_DIR/dist" ]; then
    echo "❌ Studyplanner build failed"
    exit 1
fi

########################################
# CLEAN STUDY NODE_MODULES
########################################

echo "==> Cleaning studyplanner node_modules..."
rm -rf "$STUDY_BUILD_DIR/node_modules"

########################################
# STEP 6: BACKUP STUDYPLANNER (SELECTIVE)
########################################

echo "==> Backing up studyplanner..."

mkdir -p "$BACKUP_DIR/studyplanner_$TIMESTAMP"

cp -r "$STUDY_TARGET/assets" "$BACKUP_DIR/studyplanner_$TIMESTAMP/" 2>/dev/null || true
cp -r "$STUDY_TARGET/images" "$BACKUP_DIR/studyplanner_$TIMESTAMP/" 2>/dev/null || true
cp "$STUDY_TARGET/favicon.ico" "$BACKUP_DIR/studyplanner_$TIMESTAMP/" 2>/dev/null || true
cp "$STUDY_TARGET/index.html" "$BACKUP_DIR/studyplanner_$TIMESTAMP/" 2>/dev/null || true

########################################
# STEP 7: CLEAN OLD STUDY FILES
########################################

echo "==> Cleaning studyplanner target..."

rm -rf "$STUDY_TARGET/assets"
rm -rf "$STUDY_TARGET/images"
rm -f "$STUDY_TARGET/index.html"
rm -f "$STUDY_TARGET/favicon.ico"

########################################
# STEP 8: DEPLOY STUDYPLANNER
########################################

echo "==> Deploying studyplanner..."

cp -r "$STUDY_BUILD_DIR/dist/"* "$STUDY_TARGET"/
DID_DEPLOY_STUDY=true
else
    echo "==> Skipping studyplanner (no studyplanner changes detected)"
fi

########################################
# STEP 9: CLIENT BUILD + DEPLOY DIST
########################################

if [ "$DEPLOY_CLIENT" = true ]; then
echo "==> Building chat client..."

cd "$CLIENT_BUILD_DIR"

cat <<EOT > .env
VITE_STUDY_PLANNER_URL=https://mystudyplanner.in
VITE_SERVER_IMAGE_URL=https://eplanning.mystudyplanner.in/uploads/
EOT

npm install
npm run build

if [ ! -d "$CLIENT_BUILD_DIR/dist" ]; then
    echo "❌ Chat client build failed"
    exit 1
fi

echo "==> Backing up chat client dist..."
mkdir -p "$BACKUP_DIR"

if [ -d "$CLIENT_TARGET/dist" ]; then
    mkdir -p "$BACKUP_DIR/chat_client_dist_$TIMESTAMP"
    cp -r "$CLIENT_TARGET/dist" "$BACKUP_DIR/chat_client_dist_$TIMESTAMP/"
fi

echo "==> Deploying chat client dist..."
mkdir -p "$CLIENT_TARGET"
rm -rf "$CLIENT_TARGET/dist"
cp -r "$CLIENT_BUILD_DIR/dist" "$CLIENT_TARGET/"
DID_DEPLOY_CLIENT=true
else
    echo "==> Skipping chat client (no client changes detected)"
fi

########################################
# STEP 10: API DEPLOY
########################################

# Always deploy API, even when api/ has no detected changes.
DEPLOY_API=true

if [ "$DEPLOY_API" = true ]; then
echo "==> Deploying chat api..."

mkdir -p "$BACKUP_DIR"
mkdir -p "$API_TARGET"

echo "==> Backing up chat api (excluding uploads, node_modules)..."
mkdir -p "$BACKUP_DIR/chat_api_$TIMESTAMP"
rsync -a \
  --exclude 'uploads/' \
  --exclude 'node_modules/' \
  "$API_TARGET"/ "$BACKUP_DIR/chat_api_$TIMESTAMP"/

echo "==> Cleaning chat api target (keeping uploads)..."
find "$API_TARGET" -mindepth 1 -maxdepth 1 ! -name uploads -exec rm -rf {} +

echo "==> Copying latest chat api code..."
rsync -a \
  --exclude '.git/' \
  --exclude 'uploads/' \
  --exclude 'node_modules/' \
  "$API_BUILD_DIR"/ "$API_TARGET"/

echo "==> Writing chat api .env..."
cat <<EOT > "$API_TARGET/.env"
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=123
DB_NAME=studyplanner
JWT_SECRET=mynameisnitish
PORT=4000
NODE_ENV=production
CLIENT_URL=https://chat.mystudyplanner.in
REDIS_URL=redis://127.0.0.1:6379
STUDYPLANNER_JWT_SECRET=mynameisnitish
PROFILE_UPLOAD_DIR=/home/www/html/eplanning/uploads/profile
EOT

echo "==> Installing chat api dependencies..."
cd "$API_TARGET"
npm install

export HOME=/home/www
export PM2_HOME=/home/www/.pm2

echo "==> Restarting pm2 process: chat-api"
if pm2 describe chat-api >/dev/null 2>&1; then
    pm2 restart chat-api --update-env
else
    echo "==> chat-api not found in PM2. Starting new process..."
    if [ -f "$API_TARGET/pm2.config.js" ]; then
        pm2 start "$API_TARGET/pm2.config.js" --only chat-api
    else
        pm2 start "$API_TARGET/server.js" --name chat-api
    fi
fi

echo "==> Verifying pm2 status..."
PM2_STATUS=$(
    pm2 jlist | node -e '
let input = "";
process.stdin.on("data", c => input += c);
process.stdin.on("end", () => {
  try {
    const list = JSON.parse(input);
    const app = list.find(x => x.name === "chat-api");
    const status = app && app.pm2_env ? app.pm2_env.status : "unknown";
    process.stdout.write(status || "unknown");
  } catch (e) {
    process.stdout.write("unknown");
  }
});
'
)
if [ "$PM2_STATUS" != "online" ]; then
    echo "❌ chat-api is not online after restart (status: ${PM2_STATUS:-unknown})"
    pm2 list
    exit 1
fi
pm2 list
DID_DEPLOY_API=true
else
    echo "==> Skipping chat api (no api changes detected)"
fi

########################################
# STEP 11: PHP STUDY DEPLOY
########################################

if [ "$DEPLOY_PHP_STUDY" = true ]; then
echo "==> Deploying php study..."

mkdir -p "$BACKUP_DIR"
mkdir -p "$PHP_STUDY_TARGET"

echo "==> Backing up php study..."
cp -r "$PHP_STUDY_TARGET" "$BACKUP_DIR/php_study_$TIMESTAMP"

echo "==> Cleaning php study target..."
find "$PHP_STUDY_TARGET" -mindepth 1 -maxdepth 1 -exec rm -rf {} +

echo "==> Copying latest php study code..."
cp -r "$PHP_STUDY_BUILD_DIR"/. "$PHP_STUDY_TARGET"/
DID_DEPLOY_PHP_STUDY=true
else
    echo "==> Skipping php study (no studyplaner-backend/study changes detected)"
fi

########################################
# OPTIONAL: CLEAN OLD BACKUPS (KEEP LAST 5)
########################################

step "==> Cleaning old backups..."

ls -dt $BACKUP_DIR/mainadmin_* 2>/dev/null | tail -n +6 | xargs rm -rf || true
ls -dt $BACKUP_DIR/studyplanner_* 2>/dev/null | tail -n +6 | xargs rm -rf || true
ls -dt $BACKUP_DIR/chat_client_dist_* 2>/dev/null | tail -n +6 | xargs rm -rf || true
ls -dt $BACKUP_DIR/chat_api_* 2>/dev/null | tail -n +6 | xargs rm -rf || true
ls -dt $BACKUP_DIR/php_study_* 2>/dev/null | tail -n +6 | xargs rm -rf || true

########################################
# SUCCESS
########################################

banner "==============================="
ok "✅ DEPLOY SUCCESS: $TIMESTAMP"
banner "==============================="

