#!/bin/bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
BACKEND_DIR="$SCRIPT_DIR/backend"
FRONTEND_DIR="$SCRIPT_DIR/frontend"
ROOT_ENV="$SCRIPT_DIR/.env"
BACKEND_ENV="$BACKEND_DIR/.env"
BACKEND_ENV_EXAMPLE="$BACKEND_DIR/.env.example"
FRONTEND_ENV_LOCAL="$FRONTEND_DIR/.env.local"
HOST_OS="$(uname -s)"
USE_WINDOWS_TOOLS=false

if command -v cmd.exe >/dev/null 2>&1 || command -v powershell.exe >/dev/null 2>&1; then
  USE_WINDOWS_TOOLS=true
fi

if [[ "$USE_WINDOWS_TOOLS" == true ]]; then
  BACKEND_PYTHON="$BACKEND_DIR/.venv/Scripts/python.exe"
  FRONTEND_NPM="npm.cmd"
else
  BACKEND_PYTHON="$BACKEND_DIR/.venv/bin/python"
  FRONTEND_NPM="npm"
fi

print_header() {
  echo "=========================================="
  echo "  Jarvis - Setup"
  echo "=========================================="
  echo
}

require_command() {
  local command_name="$1"
  local hint="$2"
  if ! command -v "$command_name" >/dev/null 2>&1; then
    echo "[ERROR] $command_name was not found."
    echo "[ERROR] $hint"
    exit 1
  fi
}

ensure_backend_env() {
  if [[ -f "$BACKEND_ENV" ]]; then
    echo "[OK] Backend env file exists: $BACKEND_ENV"
    return 0
  fi

  if [[ -f "$ROOT_ENV" ]]; then
    cp "$ROOT_ENV" "$BACKEND_ENV"
    echo "[INFO] Created backend/.env from root .env"
    return 0
  fi

  if [[ -f "$BACKEND_ENV_EXAMPLE" ]]; then
    cp "$BACKEND_ENV_EXAMPLE" "$BACKEND_ENV"
    echo "[INFO] Created backend/.env from backend/.env.example"
    echo "[INFO] Edit $BACKEND_ENV before running start.sh if needed."
    return 0
  fi

  echo "[ERROR] Could not create backend/.env"
  exit 1
}

sync_frontend_env() {
  local backend_host
  local backend_port

  backend_host="$(grep '^HOST=' "$BACKEND_ENV" | cut -d'=' -f2- | tr -d '\r' || true)"
  backend_port="$(grep '^PORT=' "$BACKEND_ENV" | cut -d'=' -f2- | tr -d '\r' || true)"

  [[ -z "$backend_host" ]] && backend_host="127.0.0.1"
  [[ -z "$backend_port" ]] && backend_port="3337"

  printf 'VITE_API_URL=http://%s:%s\n' "$backend_host" "$backend_port" > "$FRONTEND_ENV_LOCAL"
  echo "[OK] Synced frontend/.env.local -> http://$backend_host:$backend_port"
}

print_header

require_command npm "Install Node.js and npm first."

if [[ "$USE_WINDOWS_TOOLS" == true ]]; then
  if command -v py.exe >/dev/null 2>&1; then
    if py.exe -3.13 --version >/dev/null 2>&1; then
      PYTHON_BOOTSTRAP=("py.exe" "-3.13")
    elif py.exe -3.12 --version >/dev/null 2>&1; then
      PYTHON_BOOTSTRAP=("py.exe" "-3.12")
    elif py.exe -3 --version >/dev/null 2>&1; then
      PYTHON_BOOTSTRAP=("py.exe" "-3")
    else
      echo "[ERROR] Python 3 was not found via py.exe."
      echo "[ERROR] Install Python 3.12+ for Windows first."
      exit 1
    fi
  elif command -v python.exe >/dev/null 2>&1; then
    PYTHON_BOOTSTRAP=("python.exe")
  elif command -v python >/dev/null 2>&1; then
    PYTHON_BOOTSTRAP=("python")
  else
    echo "[ERROR] Python was not found."
    echo "[ERROR] Install Python 3.12+ for Windows first."
    exit 1
  fi
else
  if command -v python3 >/dev/null 2>&1; then
    PYTHON_BOOTSTRAP=("python3")
  elif command -v python >/dev/null 2>&1; then
    PYTHON_BOOTSTRAP=("python")
  else
    echo "[ERROR] python3/python was not found."
    echo "[ERROR] Install Python 3.12+ first."
    exit 1
  fi
fi

install_backend_dependencies() {
  if command -v uv >/dev/null 2>&1; then
    echo "[INFO] Using uv to install backend dependencies..."
    (
      cd "$BACKEND_DIR"
      uv sync
    )
    return 0
  fi

  echo "[INFO] uv was not found. Falling back to venv + pip..."
  (
    cd "$BACKEND_DIR"
    if ! "${PYTHON_BOOTSTRAP[@]}" -m venv .venv; then
      echo "[WARN] python -m venv failed. Trying virtualenv fallback..."
      "${PYTHON_BOOTSTRAP[@]}" -m pip install --user virtualenv
      "${PYTHON_BOOTSTRAP[@]}" -m virtualenv .venv
    fi
    if [[ "$USE_WINDOWS_TOOLS" == true ]]; then
      .venv/Scripts/python.exe -m pip install --upgrade pip
      .venv/Scripts/python.exe -m pip install -e .
    else
      .venv/bin/python -m pip install --upgrade pip
      .venv/bin/python -m pip install -e .
    fi
  )
}

install_frontend_dependencies() {
  if [[ "$USE_WINDOWS_TOOLS" == true ]]; then
    (
      cd "$FRONTEND_DIR"
      if [[ -f "package-lock.json" ]]; then
        cmd.exe /c npm ci
      else
        cmd.exe /c npm install
      fi
    )
  else
    (
      cd "$FRONTEND_DIR"
      if [[ -f "package-lock.json" ]]; then
        npm ci
      else
        npm install
      fi
    )
  fi

  if [[ -f "$FRONTEND_DIR/node_modules/.bin/vite" || -f "$FRONTEND_DIR/node_modules/.bin/vite.cmd" ]]; then
    return 0
  fi

  echo "[ERROR] Frontend dependencies were installed, but vite was not found."
  echo "[ERROR] Check frontend/node_modules and npm output."
  exit 1
}

echo "[1/4] Prepare backend environment file..."
ensure_backend_env

echo
echo "[2/4] Install backend dependencies..."
install_backend_dependencies

if [[ "$USE_WINDOWS_TOOLS" == true ]]; then
  if [[ ! -f "$BACKEND_PYTHON" ]]; then
    echo "[ERROR] Backend virtual environment Python was not found after setup: $BACKEND_PYTHON"
    exit 1
  fi
else
  if [[ ! -x "$BACKEND_PYTHON" ]]; then
    echo "[ERROR] Backend virtual environment Python was not found after setup: $BACKEND_PYTHON"
    exit 1
  fi
fi

echo "[OK] Backend dependencies installed."

echo
echo "[3/4] Install frontend dependencies..."
install_frontend_dependencies
echo "[OK] Frontend dependencies installed."

echo
echo "[4/4] Sync frontend API configuration..."
sync_frontend_env

echo
echo "=========================================="
echo "  Setup complete"
echo
echo "  Backend env:   $BACKEND_ENV"
echo "  Frontend env:  $FRONTEND_ENV_LOCAL"
echo
echo "  Next: bash start.sh"
echo "=========================================="
