#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
ROOT_ENV_FILE="$ROOT_DIR/.env"
ROOT_ENV_EXAMPLE_FILE="$ROOT_DIR/.env.example"
VENV_DIR="$SCRIPT_DIR/.venv"
MODE="${1:-start}"

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

info()  { echo -e "${GREEN}[INFO]${NC} $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

if [ ! -f "$ROOT_ENV_FILE" ]; then
    if [ -f "$ROOT_ENV_EXAMPLE_FILE" ]; then
        warn "Root .env not found. Creating it from .env.example"
        cp "$ROOT_ENV_EXAMPLE_FILE" "$ROOT_ENV_FILE"
    else
        error "Root .env and .env.example are both missing."
    fi
fi

set -a
. "$ROOT_ENV_FILE"
set +a

SERVER_HOST="${SERVER_HOST:-127.0.0.1}"
SERVER_PORT="${SERVER_PORT:-8000}"

is_wsl() {
    grep -qi microsoft /proc/version 2>/dev/null
}

is_windows_mount() {
    case "$SCRIPT_DIR" in
        /mnt/*) return 0 ;;
        *) return 1 ;;
    esac
}

find_unix_python() {
    if command -v python >/dev/null 2>&1; then
        echo "python"
        return 0
    fi

    if command -v python3 >/dev/null 2>&1; then
        echo "python3"
        return 0
    fi

    return 1
}

find_windows_python() {
    if command -v py.exe >/dev/null 2>&1; then
        echo "py.exe -3"
        return 0
    fi

    if command -v python.exe >/dev/null 2>&1; then
        echo "python.exe"
        return 0
    fi

    return 1
}

venv_python_path() {
    if [ "${VENV_LAYOUT:-auto}" = "windows" ]; then
        if [ -x "$VENV_DIR/Scripts/python.exe" ]; then
            echo "$VENV_DIR/Scripts/python.exe"
            return 0
        fi
        return 1
    fi

    if [ "${VENV_LAYOUT:-auto}" = "unix" ]; then
        if [ -x "$VENV_DIR/bin/python" ]; then
            echo "$VENV_DIR/bin/python"
            return 0
        fi
        return 1
    fi

    if [ -x "$VENV_DIR/Scripts/python.exe" ]; then
        echo "$VENV_DIR/Scripts/python.exe"
        return 0
    fi

    if [ -x "$VENV_DIR/bin/python" ]; then
        echo "$VENV_DIR/bin/python"
        return 0
    fi

    return 1
}

run_bootstrap_python() {
    $PYTHON_BOOTSTRAP "$@"
}

dependencies_ready() {
    "$PYTHON_BIN" -c "import fastapi, uvicorn, sqlalchemy, alembic, pydantic_settings" >/dev/null 2>&1
}

pip_ready() {
    "$PYTHON_BIN" -m pip --version >/dev/null 2>&1
}

create_venv() {
    info "Creating virtual environment at ./server/.venv"
    if [ -d "$VENV_DIR" ]; then
        rm -rf "$VENV_DIR"
    fi
    run_bootstrap_python -m venv "$VENV_DIR"

    if ! PYTHON_BIN="$(venv_python_path)"; then
        error "Virtual environment was not created successfully."
    fi
}

ensure_pip() {
    if pip_ready; then
        return 0
    fi

    warn "pip is missing in .venv, attempting repair"

    if "$PYTHON_BIN" -m ensurepip --upgrade >/dev/null 2>&1 && pip_ready; then
        info "pip restored successfully"
        return 0
    fi

    warn "Recreating .venv because pip repair failed"
    rm -rf "$VENV_DIR"
    create_venv

    if "$PYTHON_BIN" -m ensurepip --upgrade >/dev/null 2>&1 && pip_ready; then
        info "pip restored after recreating .venv"
        return 0
    fi

    error "pip could not be created inside .venv. Install Python with venv and pip support, then rerun the script."
}

ensure_python_bootstrap() {
    if is_wsl && is_windows_mount; then
        if find_windows_python >/dev/null 2>&1; then
            PYTHON_BOOTSTRAP="$(find_windows_python)"
            VENV_LAYOUT="windows"
            info "Detected WSL on a Windows-mounted project"
            info "Using Windows Python directly from bash"
            return 0
        fi

        if find_unix_python >/dev/null 2>&1; then
            PYTHON_BOOTSTRAP="$(find_unix_python)"
            VENV_LAYOUT="unix"
            warn "Windows Python not found, falling back to WSL Python"
            return 0
        fi

        error "Neither Windows Python nor WSL Python is available in PATH."
    fi

    if ! PYTHON_BOOTSTRAP="$(find_unix_python)"; then
        error "Python is not installed or not available in PATH. Install Python 3.11+ first so the script can create server/.venv automatically."
    fi

    VENV_LAYOUT="unix"
}

ensure_dependencies() {
    ensure_python_bootstrap

    if ! PYTHON_BIN="$(venv_python_path)"; then
        warn "Python virtual environment not found"
        create_venv
    fi

    ensure_pip

    if dependencies_ready; then
        info "Server dependencies are ready."
        return 0
    fi

    warn "Server dependencies are missing or incomplete"
    info "Running .venv Python dependency installation"
    "$PYTHON_BIN" -m pip install --upgrade pip
    "$PYTHON_BIN" -m pip install -e ".[dev]"

    if ! dependencies_ready; then
        error "Server dependencies are still incomplete after installation."
    fi

    info "Server dependencies are ready."
}

start_server() {
    info "Starting FastAPI server..."
    info "Access: http://$SERVER_HOST:$SERVER_PORT"
    echo ""

    exec "$PYTHON_BIN" -m uvicorn app.main:app --reload --app-dir src --host "$SERVER_HOST" --port "$SERVER_PORT"
}

case "$MODE" in
    deps)
        ensure_dependencies
        ;;
    start)
        ensure_dependencies
        start_server
        ;;
    *)
        error "Unknown mode: $MODE. Use one of: deps, start"
        ;;
esac
