#!/bin/bash

# ThrillWiki Development Server Starter
# Starts both Django backend and Vue.js frontend servers concurrently

set -e

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

# Script directory and project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../" && pwd)"

# Configuration
BACKEND_PORT=8000
FRONTEND_PORT=5174
BACKEND_DIR="$PROJECT_ROOT/backend"
FRONTEND_DIR="$PROJECT_ROOT/frontend"

# Function to print colored output
print_status() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# Function to check if a port is available
check_port() {
    local port=$1
    if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null ; then
        return 1
    else
        return 0
    fi
}

# Function to kill process on port
kill_port() {
    local port=$1
    local pid=$(lsof -ti:$port)
    if [ ! -z "$pid" ]; then
        print_warning "Killing process $pid on port $port"
        kill -9 $pid
    fi
}

# Function to wait for service to be ready
wait_for_service() {
    local url=$1
    local service_name=$2
    local max_attempts=30
    local attempt=1

    print_status "Waiting for $service_name to be ready at $url"

    while [ $attempt -le $max_attempts ]; do
        if curl -s -f "$url" > /dev/null 2>&1; then
            print_success "$service_name is ready!"
            return 0
        fi

        echo -n "."
        sleep 2
        ((attempt++))
    done

    print_error "$service_name failed to start after $max_attempts attempts"
    return 1
}

# Function to start backend server
start_backend() {
    print_status "Starting Django backend server..."

    # Kill any existing process on backend port
    kill_port $BACKEND_PORT

    # Clean up Python cache files
    find "$BACKEND_DIR" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true

    cd "$BACKEND_DIR"

    # Check if virtual environment exists
    if [ ! -d ".venv" ]; then
        print_error "Backend virtual environment not found. Please run setup-dev.sh first."
        exit 1
    fi

    # Start Django server in background
    print_status "Starting Django development server on port $BACKEND_PORT"
    uv run manage.py runserver 0.0.0.0:$BACKEND_PORT &
    BACKEND_PID=$!

    # Wait for backend to be ready
    wait_for_service "http://localhost:$BACKEND_PORT/api/" "Django backend"

    cd "$PROJECT_ROOT"
}

# Function to start frontend server
start_frontend() {
    print_status "Starting Vue.js frontend server..."

    cd "$FRONTEND_DIR"

    # Check if node_modules exists
    if [ ! -d "node_modules" ]; then
        print_error "Frontend dependencies not installed. Please run setup-dev.sh first."
        exit 1
    fi

    # Start Vue.js dev server in background
    print_status "Starting Vue.js development server on port $FRONTEND_PORT"
    pnpm run dev &
    FRONTEND_PID=$!

    # Wait for frontend to be ready
    wait_for_service "http://localhost:$FRONTEND_PORT" "Vue.js frontend"

    cd "$PROJECT_ROOT"
}

# Function to cleanup on script exit
cleanup() {
    print_warning "Shutting down development servers..."

    if [ ! -z "$BACKEND_PID" ]; then
        kill $BACKEND_PID 2>/dev/null || true
    fi

    if [ ! -z "$FRONTEND_PID" ]; then
        kill $FRONTEND_PID 2>/dev/null || true
    fi

    # Kill any remaining processes on our ports
    kill_port $BACKEND_PORT
    kill_port $FRONTEND_PORT

    print_success "Development servers stopped."
    exit 0
}

# Function to show usage
show_usage() {
    cat << EOF
Usage: $0 [OPTIONS]

Start both Django backend and Vue.js frontend development servers.

Options:
    -h, --help          Show this help message
    -b, --backend-only  Start only the backend server
    -f, --frontend-only Start only the frontend server
    -p, --production    Start in production mode (if applicable)
    --no-wait          Don't wait for services to be ready

Examples:
    $0                  # Start both servers
    $0 --backend-only   # Start only backend
    $0 --frontend-only  # Start only frontend

Environment Variables:
    BACKEND_PORT        Backend server port (default: 8000)
    FRONTEND_PORT       Frontend server port (default: 5174)

EOF
}

# Parse command line arguments
BACKEND_ONLY=false
FRONTEND_ONLY=false
PRODUCTION=false
WAIT_FOR_SERVICES=true

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            show_usage
            exit 0
            ;;
        -b|--backend-only)
            BACKEND_ONLY=true
            shift
            ;;
        -f|--frontend-only)
            FRONTEND_ONLY=true
            shift
            ;;
        -p|--production)
            PRODUCTION=true
            shift
            ;;
        --no-wait)
            WAIT_FOR_SERVICES=false
            shift
            ;;
        *)
            print_error "Unknown option: $1"
            show_usage
            exit 1
            ;;
    esac
done

# Override ports from environment if set
if [ ! -z "$BACKEND_PORT_ENV" ]; then
    BACKEND_PORT=$BACKEND_PORT_ENV
fi

if [ ! -z "$FRONTEND_PORT_ENV" ]; then
    FRONTEND_PORT=$FRONTEND_PORT_ENV
fi

# Set up signal handlers for graceful shutdown
trap cleanup SIGINT SIGTERM

# Print banner
echo -e "${GREEN}"
echo "=========================================="
echo "    ThrillWiki Development Environment"
echo "=========================================="
echo -e "${NC}"

print_status "Project root: $PROJECT_ROOT"
print_status "Backend port: $BACKEND_PORT"
print_status "Frontend port: $FRONTEND_PORT"

# Check if required tools are available
command -v uv >/dev/null 2>&1 || { print_error "uv is required but not installed. Please install uv first."; exit 1; }
command -v pnpm >/dev/null 2>&1 || { print_error "pnpm is required but not installed. Please install pnpm first."; exit 1; }
command -v curl >/dev/null 2>&1 || { print_error "curl is required but not installed."; exit 1; }

# Start services based on options
if [ "$BACKEND_ONLY" = true ]; then
    print_status "Starting backend only..."
    start_backend
    print_success "Backend server started successfully!"
    print_status "Backend URL: http://localhost:$BACKEND_PORT"
    print_status "API URL: http://localhost:$BACKEND_PORT/api/"
    wait
elif [ "$FRONTEND_ONLY" = true ]; then
    print_status "Starting frontend only..."
    start_frontend
    print_success "Frontend server started successfully!"
    print_status "Frontend URL: http://localhost:$FRONTEND_PORT"
    wait
else
    print_status "Starting both backend and frontend servers..."
    start_backend &
    BACKEND_PID=$!
    start_frontend &
    FRONTEND_PID=$!

    print_success "Development servers started successfully!"
    echo ""
    print_status "Backend URL: http://localhost:$BACKEND_PORT"
    print_status "API URL: http://localhost:$BACKEND_PORT/api/"
    print_status "Frontend URL: http://localhost:$FRONTEND_PORT"
    echo ""
    print_status "Press Ctrl+C to stop all servers"

    # Wait for both processes
    wait
fi