#!/bin/bash
# Stop both backend and frontend services
# Enhanced to kill entire process trees, clean up orphans, and verify shutdown

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="$SCRIPT_DIR/logs"
BACKEND_PORT=8000
FRONTEND_PORT=3000

# Parse arguments
QUIET_MODE=false
FORCE_MODE=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --quiet|-q)
            QUIET_MODE=true
            shift
            ;;
        --force|-f)
            FORCE_MODE=true
            shift
            ;;
        --help|-h)
            echo "Usage: $0 [OPTIONS]"
            echo ""
            echo "Options:"
            echo "  --quiet, -q   Minimal output"
            echo "  --force, -f   Skip graceful shutdown, kill immediately"
            echo "  --help, -h    Show this help message"
            exit 0
            ;;
        *)
            echo "Unknown option: $1"
            exit 1
            ;;
    esac
done

log() {
    if [ "$QUIET_MODE" = false ]; then
        echo "$@"
    fi
}

log "========================================"
log "🛑 Stopping SBA Gameplay Services"
log "========================================"
log ""

# Function to kill process tree
kill_tree() {
    local pid=$1
    local sig=${2:-TERM}

    # Get all child PIDs
    local children=$(pgrep -P "$pid" 2>/dev/null || true)

    # Kill children first (depth-first)
    for child in $children; do
        kill_tree "$child" "$sig"
    done

    # Kill the parent
    if ps -p "$pid" > /dev/null 2>&1; then
        kill -"$sig" "$pid" 2>/dev/null || true
    fi
}

# Function to stop a service gracefully
stop_service() {
    local name=$1
    local pid_file=$2
    local icon=$3

    if [ -f "$pid_file" ]; then
        local pid=$(cat "$pid_file")
        if ps -p "$pid" > /dev/null 2>&1; then
            log "$icon Stopping $name (PID: $pid)..."

            if [ "$FORCE_MODE" = true ]; then
                # Force mode: kill immediately
                kill_tree "$pid" KILL
                log "   ✓ $name killed (force mode)"
            else
                # Graceful mode: SIGTERM first, then SIGKILL
                kill_tree "$pid" TERM

                # Wait up to 5 seconds for graceful shutdown
                local wait_count=0
                while [ $wait_count -lt 5 ]; do
                    if ! ps -p "$pid" > /dev/null 2>&1; then
                        break
                    fi
                    sleep 1
                    wait_count=$((wait_count + 1))
                done

                # Force kill if still running
                if ps -p "$pid" > /dev/null 2>&1; then
                    log "   → Graceful shutdown timed out, forcing..."
                    kill_tree "$pid" KILL
                    sleep 1
                fi

                if ps -p "$pid" > /dev/null 2>&1; then
                    log "   ⚠️  $name may still be running"
                else
                    log "   ✓ $name stopped"
                fi
            fi
        else
            log "   ⚠️  $name process not found (stale PID file)"
        fi
        rm -f "$pid_file"
    else
        log "   ℹ️  No $name PID file found"
    fi
}

# Stop Backend
stop_service "Backend" "$LOG_DIR/backend.pid" "📡"
log ""

# Stop Frontend
stop_service "Frontend" "$LOG_DIR/frontend.pid" "🎨"
log ""

# ============================================
# AGGRESSIVE CLEANUP: Kill orphaned processes
# ============================================
log "🔍 Checking for orphaned processes..."

ORPHANS_FOUND=false

# Kill all backend processes for this specific app
# Use more specific pattern to avoid killing unrelated processes
BACKEND_PATTERN="python.*app\.main"
BACKEND_PIDS=$(pgrep -f "$BACKEND_PATTERN" 2>/dev/null || true)

# Also check for uvicorn processes
UVICORN_PATTERN="uvicorn.*app\.main"
UVICORN_PIDS=$(pgrep -f "$UVICORN_PATTERN" 2>/dev/null || true)

# Combine and deduplicate
ALL_BACKEND_PIDS=$(echo "$BACKEND_PIDS $UVICORN_PIDS" | tr ' ' '\n' | sort -u | tr '\n' ' ' | xargs)

if [ -n "$ALL_BACKEND_PIDS" ]; then
    ORPHANS_FOUND=true
    log "   Found orphaned backend processes: $ALL_BACKEND_PIDS"
    for pid in $ALL_BACKEND_PIDS; do
        kill_tree "$pid" KILL
    done
    log "   ✓ Killed orphaned backend processes"
fi

# Kill processes on backend port
PORT_BACKEND_PIDS=$(lsof -ti :$BACKEND_PORT 2>/dev/null || true)
if [ -n "$PORT_BACKEND_PIDS" ]; then
    ORPHANS_FOUND=true
    log "   Found processes on port $BACKEND_PORT: $PORT_BACKEND_PIDS"
    for pid in $PORT_BACKEND_PIDS; do
        kill -9 "$pid" 2>/dev/null || true
    done
    log "   ✓ Killed processes on port $BACKEND_PORT"
fi

# Kill processes on frontend port
PORT_FRONTEND_PIDS=$(lsof -ti :$FRONTEND_PORT 2>/dev/null || true)
if [ -n "$PORT_FRONTEND_PIDS" ]; then
    ORPHANS_FOUND=true
    log "   Found processes on port $FRONTEND_PORT: $PORT_FRONTEND_PIDS"
    for pid in $PORT_FRONTEND_PIDS; do
        kill -9 "$pid" 2>/dev/null || true
    done
    log "   ✓ Killed processes on port $FRONTEND_PORT"
fi

# Kill nuxt dev processes specifically for this project
# Check if process command line contains our project path
NUXT_PIDS=""
for pid in $(pgrep -f "nuxt.*dev" 2>/dev/null || true); do
    # Verify this is for our project by checking cwd or command
    if ps -p "$pid" -o args= 2>/dev/null | grep -q "$SCRIPT_DIR" 2>/dev/null; then
        NUXT_PIDS="$NUXT_PIDS $pid"
    fi
done
NUXT_PIDS=$(echo "$NUXT_PIDS" | xargs)

if [ -n "$NUXT_PIDS" ]; then
    ORPHANS_FOUND=true
    log "   Found orphaned frontend processes: $NUXT_PIDS"
    for pid in $NUXT_PIDS; do
        kill_tree "$pid" KILL
    done
    log "   ✓ Killed orphaned frontend processes"
fi

# Kill any node processes that might be related to our frontend
# Be more conservative here - only kill if definitely ours
NODE_PIDS=""
for pid in $(pgrep -f "node.*$SCRIPT_DIR/frontend" 2>/dev/null || true); do
    NODE_PIDS="$NODE_PIDS $pid"
done
NODE_PIDS=$(echo "$NODE_PIDS" | xargs)

if [ -n "$NODE_PIDS" ]; then
    ORPHANS_FOUND=true
    log "   Found orphaned node processes: $NODE_PIDS"
    for pid in $NODE_PIDS; do
        kill -9 "$pid" 2>/dev/null || true
    done
    log "   ✓ Killed orphaned node processes"
fi

if [ "$ORPHANS_FOUND" = false ]; then
    log "   ✓ No orphaned processes found"
fi

log ""

# ============================================
# VERIFICATION: Confirm services are stopped
# ============================================
log "🔍 Verification..."

# Give processes a moment to fully release ports
sleep 1

VERIFICATION_OK=true

# Check backend port
if lsof -ti :$BACKEND_PORT > /dev/null 2>&1; then
    log "   ⚠️  Port $BACKEND_PORT still in use!"
    VERIFICATION_OK=false
else
    log "   ✓ Port $BACKEND_PORT is free"
fi

# Check frontend port
if lsof -ti :$FRONTEND_PORT > /dev/null 2>&1; then
    log "   ⚠️  Port $FRONTEND_PORT still in use!"
    VERIFICATION_OK=false
else
    log "   ✓ Port $FRONTEND_PORT is free"
fi

# Check for any remaining processes
REMAINING_BACKEND=$(pgrep -f "$BACKEND_PATTERN" 2>/dev/null || true)
if [ -n "$REMAINING_BACKEND" ]; then
    log "   ⚠️  Backend processes still running: $REMAINING_BACKEND"
    VERIFICATION_OK=false
fi

log ""

# ============================================
# SUMMARY
# ============================================
if [ "$VERIFICATION_OK" = true ]; then
    log "========================================"
    log "✅ Services Stopped Successfully!"
    log "========================================"
else
    log "========================================"
    log "⚠️  Services Stopped (with warnings)"
    log "========================================"
    log ""
    log "Some processes may still be running. Try:"
    log "   $0 --force"
    log ""
    log "Or manually check:"
    log "   lsof -ti :$BACKEND_PORT"
    log "   lsof -ti :$FRONTEND_PORT"
fi

log ""
