#!/bin/bash
# Tool_OCR - Unified Development Server Startup Script
# Usage:
#   ./start.sh              Start all services (backend + frontend)
#   ./start.sh backend      Start only backend
#   ./start.sh frontend     Start only frontend
#   ./start.sh --stop       Stop all services
#   ./start.sh --status     Show service status
#   ./start.sh --help       Show help

# Note: We don't use 'set -e' here because stop commands may fail gracefully

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

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PID_DIR="$SCRIPT_DIR/.pid"
BACKEND_PID_FILE="$PID_DIR/backend.pid"
FRONTEND_PID_FILE="$PID_DIR/frontend.pid"
BACKEND_PORT=${BACKEND_PORT:-8000}
FRONTEND_PORT=${FRONTEND_PORT:-5173}

# Create PID directory
mkdir -p "$PID_DIR"

# Functions
print_header() {
    echo ""
    echo -e "${BLUE}================================${NC}"
    echo -e "${BLUE}    Tool_OCR Development Server${NC}"
    echo -e "${BLUE}================================${NC}"
    echo ""
}

show_help() {
    echo "Tool_OCR - Development Server Manager"
    echo ""
    echo "Usage: ./start.sh [command]"
    echo ""
    echo "Commands:"
    echo "  (none)      Start all services (backend + frontend)"
    echo "  backend     Start only backend service"
    echo "  frontend    Start only frontend service"
    echo "  --stop      Stop all running services"
    echo "  --status    Show status of services"
    echo "  --help      Show this help message"
    echo ""
    echo "Examples:"
    echo "  ./start.sh              # Start everything"
    echo "  ./start.sh backend      # Start only backend"
    echo "  ./start.sh --stop       # Stop all services"
    echo ""
}

check_requirements() {
    local missing=0

    # Check virtual environment
    if [ ! -d "$SCRIPT_DIR/venv" ]; then
        echo -e "${RED}Error: Python virtual environment not found${NC}"
        echo "Please run: ./setup_dev_env.sh"
        missing=1
    fi

    # Check node_modules
    if [ ! -d "$SCRIPT_DIR/frontend/node_modules" ]; then
        echo -e "${RED}Error: Frontend dependencies not found${NC}"
        echo "Please run: ./setup_dev_env.sh"
        missing=1
    fi

    # Check .env.local
    if [ ! -f "$SCRIPT_DIR/.env.local" ]; then
        echo -e "${RED}Error: .env.local not found${NC}"
        echo "Please copy .env.example to .env.local and configure"
        missing=1
    fi

    return $missing
}

is_running() {
    local pid_file=$1
    if [ -f "$pid_file" ]; then
        local pid=$(cat "$pid_file")
        if ps -p "$pid" > /dev/null 2>&1; then
            return 0
        else
            # PID file exists but process is not running, clean up
            rm -f "$pid_file"
        fi
    fi
    return 1
}

get_pid() {
    local pid_file=$1
    if [ -f "$pid_file" ]; then
        cat "$pid_file"
    fi
}

start_backend() {
    if is_running "$BACKEND_PID_FILE"; then
        echo -e "${YELLOW}Backend already running (PID: $(get_pid $BACKEND_PID_FILE))${NC}"
        return 0
    fi

    echo -e "${GREEN}Starting backend server...${NC}"

    # Activate virtual environment
    source "$SCRIPT_DIR/venv/bin/activate"

    # Load environment variables
    if [ -f "$SCRIPT_DIR/.env.local" ]; then
        export $(grep -v '^#' "$SCRIPT_DIR/.env.local" | xargs)
    fi

    # Start backend in background
    cd "$SCRIPT_DIR/backend"

    # Create necessary directories
    mkdir -p uploads/{temp,processed,images}
    mkdir -p storage/{markdown,json,exports,results}
    mkdir -p models/paddleocr
    mkdir -p logs

    # Start uvicorn
    nohup uvicorn app.main:app --reload --host 0.0.0.0 --port $BACKEND_PORT > "$SCRIPT_DIR/.pid/backend.log" 2>&1 &
    local pid=$!
    echo $pid > "$BACKEND_PID_FILE"

    cd "$SCRIPT_DIR"

    # Wait a moment and verify
    sleep 2
    if is_running "$BACKEND_PID_FILE"; then
        echo -e "${GREEN}Backend started (PID: $pid)${NC}"
        echo -e "  API Docs: http://localhost:$BACKEND_PORT/docs"
        echo -e "  Health:   http://localhost:$BACKEND_PORT/health"
    else
        echo -e "${RED}Backend failed to start. Check .pid/backend.log${NC}"
        return 1
    fi
}

start_frontend() {
    if is_running "$FRONTEND_PID_FILE"; then
        echo -e "${YELLOW}Frontend already running (PID: $(get_pid $FRONTEND_PID_FILE))${NC}"
        return 0
    fi

    echo -e "${GREEN}Starting frontend server...${NC}"

    # Load nvm
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

    cd "$SCRIPT_DIR/frontend"

    # Start vite in background
    nohup npm run dev > "$SCRIPT_DIR/.pid/frontend.log" 2>&1 &
    local pid=$!
    echo $pid > "$FRONTEND_PID_FILE"

    cd "$SCRIPT_DIR"

    # Wait a moment and verify
    sleep 3
    if is_running "$FRONTEND_PID_FILE"; then
        echo -e "${GREEN}Frontend started (PID: $pid)${NC}"
        echo -e "  URL: http://localhost:$FRONTEND_PORT"
    else
        echo -e "${RED}Frontend failed to start. Check .pid/frontend.log${NC}"
        return 1
    fi
}

kill_process_tree() {
    local pid=$1
    # Kill all child processes first
    pkill -TERM -P "$pid" 2>/dev/null || true
    # Then kill the parent
    kill -TERM "$pid" 2>/dev/null || true
}

force_kill_process_tree() {
    local pid=$1
    # Force kill all child processes
    pkill -9 -P "$pid" 2>/dev/null || true
    # Force kill the parent
    kill -9 "$pid" 2>/dev/null || true
}

kill_by_port() {
    local port=$1
    local pids=$(lsof -ti :$port 2>/dev/null)
    if [ -n "$pids" ]; then
        echo "$pids" | xargs kill -TERM 2>/dev/null || true
        sleep 1
        # Force kill if still running
        pids=$(lsof -ti :$port 2>/dev/null)
        if [ -n "$pids" ]; then
            echo "$pids" | xargs kill -9 2>/dev/null || true
        fi
    fi
}

stop_service() {
    local name=$1
    local pid_file=$2
    local port=$3

    if is_running "$pid_file"; then
        local pid=$(get_pid "$pid_file")
        echo -e "${YELLOW}Stopping $name (PID: $pid)...${NC}"

        # Kill the entire process tree
        kill_process_tree "$pid"

        # Wait up to 5 seconds
        local count=0
        while [ $count -lt 5 ] && is_running "$pid_file"; do
            sleep 1
            count=$((count + 1))
        done

        # Force kill if still running
        if is_running "$pid_file"; then
            force_kill_process_tree "$pid"
        fi

        rm -f "$pid_file"
    fi

    # Also kill any orphaned processes by port (fallback)
    if [ -n "$port" ]; then
        local port_pids=$(lsof -ti :$port 2>/dev/null)
        if [ -n "$port_pids" ]; then
            echo -e "${YELLOW}Cleaning up orphaned processes on port $port...${NC}"
            kill_by_port "$port"
        fi
    fi

    echo -e "${GREEN}$name stopped${NC}"
}

stop_all() {
    echo -e "${YELLOW}Stopping all services...${NC}"
    stop_service "Backend" "$BACKEND_PID_FILE" "$BACKEND_PORT"
    stop_service "Frontend" "$FRONTEND_PID_FILE" "$FRONTEND_PORT"
    echo -e "${GREEN}All services stopped${NC}"
}

show_status() {
    echo -e "${BLUE}Service Status:${NC}"
    echo ""

    if is_running "$BACKEND_PID_FILE"; then
        local pid=$(get_pid "$BACKEND_PID_FILE")
        echo -e "  Backend:  ${GREEN}Running${NC} (PID: $pid)"
        echo -e "            http://localhost:$BACKEND_PORT"
    else
        echo -e "  Backend:  ${RED}Stopped${NC}"
    fi

    if is_running "$FRONTEND_PID_FILE"; then
        local pid=$(get_pid "$FRONTEND_PID_FILE")
        echo -e "  Frontend: ${GREEN}Running${NC} (PID: $pid)"
        echo -e "            http://localhost:$FRONTEND_PORT"
    else
        echo -e "  Frontend: ${RED}Stopped${NC}"
    fi

    echo ""
}

# Main
case "${1:-all}" in
    --help|-h)
        show_help
        ;;
    --stop)
        stop_all
        ;;
    --status)
        show_status
        ;;
    backend)
        print_header
        check_requirements || exit 1
        start_backend
        echo ""
        echo -e "${YELLOW}Press Ctrl+C to stop (or use ./start.sh --stop)${NC}"
        echo -e "${YELLOW}Logs: tail -f .pid/backend.log${NC}"
        ;;
    frontend)
        print_header
        check_requirements || exit 1
        start_frontend
        echo ""
        echo -e "${YELLOW}Press Ctrl+C to stop (or use ./start.sh --stop)${NC}"
        echo -e "${YELLOW}Logs: tail -f .pid/frontend.log${NC}"
        ;;
    all|"")
        print_header
        check_requirements || exit 1
        start_backend
        start_frontend
        echo ""
        echo -e "${GREEN}================================${NC}"
        echo -e "${GREEN}All services started!${NC}"
        echo -e "${GREEN}================================${NC}"
        echo ""
        echo "Access the application:"
        echo -e "  Frontend: ${BLUE}http://localhost:$FRONTEND_PORT${NC}"
        echo -e "  API Docs: ${BLUE}http://localhost:$BACKEND_PORT/docs${NC}"
        echo ""
        echo -e "${YELLOW}Use ./start.sh --stop to stop all services${NC}"
        echo -e "${YELLOW}Use ./start.sh --status to check status${NC}"
        echo ""
        echo "Logs:"
        echo "  Backend:  tail -f .pid/backend.log"
        echo "  Frontend: tail -f .pid/frontend.log"
        ;;
    *)
        echo -e "${RED}Unknown command: $1${NC}"
        show_help
        exit 1
        ;;
esac
