#!/bin/bash

# ============================================================================
# POUNCE ZERO-DOWNTIME DEPLOY SCRIPT
# - Builds locally first (optional)
# - Syncs only changed files
# - Hot-reloads backend without full restart
# - Rebuilds frontend in background
# ============================================================================

set -euo pipefail

# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
RED='\033[0;31m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Server config
SERVER_USER="user"
SERVER_HOST="10.42.0.73"
SERVER_PATH="/home/user/pounce"
SERVER_PASS="user"
SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"

if ! command -v sshpass >/dev/null 2>&1; then
    echo -e "${RED}✗ sshpass is required but not installed.${NC}"
    echo -e "  Install with: ${CYAN}brew install sshpass${NC}"
    exit 1
fi

# Parse flags
QUICK_MODE=false
BACKEND_ONLY=false
FRONTEND_ONLY=false

while [[ "$#" -gt 0 ]]; do
    case $1 in
        -q|--quick) QUICK_MODE=true ;;
        -b|--backend) BACKEND_ONLY=true ;;
        -f|--frontend) FRONTEND_ONLY=true ;;
        *) COMMIT_MSG="$1" ;;
    esac
    shift
done

echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}              POUNCE ZERO-DOWNTIME DEPLOY                      ${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"

if $QUICK_MODE; then
    echo -e "${CYAN}⚡ Quick mode: Skipping git, only syncing changes${NC}"
fi

if $BACKEND_ONLY; then
    echo -e "${CYAN}🔧 Backend only mode${NC}"
fi

if $FRONTEND_ONLY; then
    echo -e "${CYAN}🎨 Frontend only mode${NC}"
fi

# Step 1: Git (unless quick mode)
if ! $QUICK_MODE; then
    echo -e "\n${YELLOW}[1/4] Git operations...${NC}"
    
    # Check for changes (including untracked)
    if [ -z "$(git status --porcelain)" ]; then
        echo "  No changes to commit"
    else
        git add -A

        if [ -z "$COMMIT_MSG" ]; then
            COMMIT_MSG="Deploy: $(date '+%Y-%m-%d %H:%M')"
        fi

        git commit -m "$COMMIT_MSG" || true
        echo "  ✓ Committed: $COMMIT_MSG"
    fi
    
    git push origin main 2>/dev/null && echo "  ✓ Pushed to git.6bit.ch" || echo "  ⚠ Push failed or nothing to push"
else
    echo -e "\n${YELLOW}[1/4] Skipping git (quick mode)${NC}"
fi

# Step 2: Sync files (only changed)
echo -e "\n${YELLOW}[2/4] Syncing changed files...${NC}"

# Using compression (-z), checksum-based detection, and bandwidth throttling for stability
RSYNC_OPTS="-avz --delete --compress-level=9 --checksum"

if ! $BACKEND_ONLY; then
    echo "  Frontend:"
    sshpass -p "$SERVER_PASS" rsync -e "ssh $SSH_OPTS" $RSYNC_OPTS \
        --exclude 'node_modules' \
        --exclude '.next' \
        --exclude '.git' \
        frontend/ $SERVER_USER@$SERVER_HOST:$SERVER_PATH/frontend/
fi

if ! $FRONTEND_ONLY; then
    echo "  Backend:"
    sshpass -p "$SERVER_PASS" rsync -e "ssh $SSH_OPTS" $RSYNC_OPTS \
        --exclude '__pycache__' \
        --exclude '.pytest_cache' \
        --exclude 'venv' \
        --exclude '.git' \
        --exclude '*.pyc' \
        --exclude '.env' \
        --exclude '*.db' \
        backend/ $SERVER_USER@$SERVER_HOST:$SERVER_PATH/backend/
fi

# Step 3: Reload backend (graceful, no restart)
if ! $FRONTEND_ONLY; then
    echo -e "\n${YELLOW}[3/4] Reloading backend (graceful)...${NC}"
    sshpass -p "$SERVER_PASS" ssh $SSH_OPTS $SERVER_USER@$SERVER_HOST << 'BACKEND_EOF'
        set -e

        cd ~/pounce/backend
        if [ -f "venv/bin/activate" ]; then
            source venv/bin/activate
        elif [ -f "../venv/bin/activate" ]; then
            source ../venv/bin/activate
        else
            echo "  ✗ venv not found (expected backend/venv or ../venv)"
            exit 1
        fi

        # Update CZDS credentials if not set
        if ! grep -q "CZDS_USERNAME=" .env 2>/dev/null; then
            echo "" >> .env
            echo "# ICANN CZDS Zone File Service" >> .env
            echo "CZDS_USERNAME=guggeryves@hotmail.com" >> .env
            echo "CZDS_PASSWORD=Achiarorocco1278!" >> .env
            echo "CZDS_DATA_DIR=/home/user/pounce_czds" >> .env
            echo "  ✓ CZDS credentials added to .env"
        else
            echo "  ✓ CZDS credentials already configured"
        fi

        echo "  Running DB migrations..."
        python -c "from app.database import init_db; import asyncio; asyncio.run(init_db())"
        echo "  ✓ DB migrations applied"

        # Restart backend process (production typically runs without --reload)
        BACKEND_PID=$(pgrep -f 'uvicorn app.main:app' | awk 'NR==1{print; exit}')
        
        if [ -n "$BACKEND_PID" ]; then
            echo "  Restarting backend (PID: $BACKEND_PID)..."
            kill "$BACKEND_PID" 2>/dev/null || true
            sleep 1
            nohup uvicorn app.main:app --host 0.0.0.0 --port 8000 > backend.log 2>&1 &
            sleep 2
            echo "  ✓ Backend restarted"
        else
            echo "  ⚠ Backend not running, starting..."
            nohup uvicorn app.main:app --host 0.0.0.0 --port 8000 > backend.log 2>&1 &
            sleep 2
            echo "  ✓ Backend started"
        fi
BACKEND_EOF
else
    echo -e "\n${YELLOW}[3/4] Skipping backend (frontend only)${NC}"
fi

# Step 4: Rebuild frontend (in background to minimize downtime)
if ! $BACKEND_ONLY; then
    echo -e "\n${YELLOW}[4/4] Rebuilding frontend...${NC}"
    sshpass -p "$SERVER_PASS" ssh $SSH_OPTS $SERVER_USER@$SERVER_HOST << 'FRONTEND_EOF'
        set -e
        cd ~/pounce/frontend

        # Check if package.json changed (skip npm ci if not)
        LOCKFILE_HASH=""
        if [ -f ".lockfile_hash" ]; then
            LOCKFILE_HASH=$(cat .lockfile_hash)
        fi
        CURRENT_HASH=$(md5sum package-lock.json 2>/dev/null | cut -d' ' -f1 || echo "none")
        
        if [ "$LOCKFILE_HASH" != "$CURRENT_HASH" ]; then
            echo "  Installing dependencies (package-lock.json changed)..."
            npm ci --prefer-offline --no-audit --no-fund
            echo "$CURRENT_HASH" > .lockfile_hash
        else
            echo "  ✓ Dependencies unchanged, skipping npm ci"
        fi
        
        # Build new version (with reduced memory for stability)
        echo "  Building..."
        NODE_OPTIONS="--max-old-space-size=2048" npm run build
        BUILD_EXIT=$?
        
        if [ $BUILD_EXIT -eq 0 ]; then
            # Next.js standalone output requires public + static inside standalone folder
            mkdir -p .next/standalone/.next
            ln -sfn ../../static .next/standalone/.next/static
            
            # Copy public folder (symlinks don't work reliably)
            rm -rf .next/standalone/public
            cp -r public .next/standalone/public
            echo "  ✓ Public files copied to standalone"

            # Gracefully restart Next.js
            NEXT_PID=$(pgrep -af 'node \\.next/standalone/server\\.js|next start|next-server|next-serv' | awk 'NR==1{print $1; exit}')
            
            if [ -n "$NEXT_PID" ]; then
                echo "  Restarting Next.js (PID: $NEXT_PID)..."
                kill $NEXT_PID 2>/dev/null
                sleep 1
            fi

            # Ensure port is free (avoid EADDRINUSE)
            lsof -ti:3000 2>/dev/null | xargs -r kill -9 2>/dev/null || true
            sleep 1
            
            # Start new instance
            if [ -f ".next/standalone/server.js" ]; then
                echo "  Starting Next.js (standalone)..."
                nohup env NODE_ENV=production HOSTNAME=0.0.0.0 PORT=3000 node .next/standalone/server.js > frontend.log 2>&1 &
            else
                echo "  Starting Next.js (npm start)..."
                nohup env NODE_ENV=production npm run start > frontend.log 2>&1 &
            fi
            sleep 2
            
            # Verify
            NEW_PID=$(pgrep -af 'node \\.next/standalone/server\\.js|next start|next-server|next-serv' | awk 'NR==1{print $1; exit}')
            if [ -n "$NEW_PID" ]; then
                echo "  ✓ Frontend running (PID: $NEW_PID)"
            else
                echo "  ⚠ Frontend may not have started correctly"
                echo "  Last 80 lines of frontend.log:"
                tail -n 80 frontend.log || true
            fi
        else
            echo "  ✗ Build failed, keeping old version"
            echo "  Last 120 lines of build output (frontend.log):"
            tail -n 120 frontend.log || true
        fi
FRONTEND_EOF
else
    echo -e "\n${YELLOW}[4/4] Skipping frontend (backend only)${NC}"
fi

# Summary
echo -e "\n${GREEN}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${GREEN}                    ✅ DEPLOY COMPLETE!                         ${NC}"
echo -e "${GREEN}═══════════════════════════════════════════════════════════════${NC}"
echo -e ""
echo -e "  Frontend: ${BLUE}https://pounce.ch${NC} / http://$SERVER_HOST:3000"
echo -e "  Backend:  ${BLUE}https://pounce.ch/api${NC} / http://$SERVER_HOST:8000"
echo -e ""
echo -e "${CYAN}Quick commands:${NC}"
echo -e "  ./deploy.sh -q          # Quick sync, no git"
echo -e "  ./deploy.sh -b          # Backend only"
echo -e "  ./deploy.sh -f          # Frontend only"
echo -e "  ./deploy.sh \"message\"   # Full deploy with commit message"
