#!/bin/bash

# Configuration
SERVER_PORT=5000
CLIENT_PORT=5173
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

resolve_node_toolchain() {
  # Common install locations when login shell PATH is not loaded
  if command -v npm >/dev/null 2>&1; then
    return 0
  fi

  if [ -s "$HOME/.nvm/nvm.sh" ]; then
    # shellcheck disable=SC1090
    . "$HOME/.nvm/nvm.sh"
  elif [ -s "/usr/local/nvm/nvm.sh" ]; then
    # shellcheck disable=SC1090
    . "/usr/local/nvm/nvm.sh"
  fi

  if [ -d "$HOME/.fnm" ] && command -v fnm >/dev/null 2>&1; then
    eval "$(fnm env)"
  fi

  for candidate in \
    /usr/local/bin/npm \
    /usr/bin/npm \
    "$HOME/.local/share/fnm/current/bin/npm" \
    "$HOME/.nvm/versions/node/"*/bin/npm; do
    if [ -x "$candidate" ]; then
      export PATH="$(dirname "$candidate"):$PATH"
      break
    fi
  done

  command -v npm >/dev/null 2>&1
}

check_dev_env() {
  local env_file="$REPO_ROOT/.env"
  if [ ! -f "$env_file" ]; then
    echo "Warning: $env_file missing — copy from .env.example (RP_ID, ORIGIN, SESSION_SECRET)."
    return
  fi

  local origin_line origin_val
  origin_line=$(grep -E '^ORIGIN=' "$env_file" | tail -1 || true)
  origin_val="${origin_line#ORIGIN=}"
  origin_val="${origin_val%\"}"
  origin_val="${origin_val#\"}"
  local expected_origin="http://localhost:$CLIENT_PORT"
  if [ -n "$origin_val" ] && [ "$origin_val" != "$expected_origin" ]; then
    echo "Warning: ORIGIN=$origin_val — for Vite dev use ORIGIN=$expected_origin (session cookie + CORS)."
  fi

  local secret_line secret_val
  secret_line=$(grep -E '^SESSION_SECRET=' "$env_file" | tail -1 || true)
  secret_val="${secret_line#SESSION_SECRET=}"
  secret_val="${secret_val%\"}"
  secret_val="${secret_val#\"}"
  if [ -z "$secret_val" ]; then
    echo "Note: SESSION_SECRET is empty — backend uses a dev-only fallback (not for production)."
  elif [ "${#secret_val}" -lt 32 ]; then
    echo "Warning: SESSION_SECRET should be at least 32 characters."
  fi
}

require_node_toolchain() {
  if resolve_node_toolchain; then
    echo "Using Node $(node -v), npm $(npm -v)"
    return 0
  fi

  echo "Error: npm was not found in PATH."
  echo ""
  echo "This script starts local Vite/Express dev servers and requires Node.js 20+ with npm."
  echo "Install Node.js on this machine, or use the Docker-based stack instead:"
  echo "  ./scripts/start-dev-docker.sh"
  echo ""
  echo "On the production host, prefer updating the running stack:"
  echo "  docker compose -f docker-compose.yml up -d --build"
  echo "  # or from your workstation: ./scripts/update-remotes.sh -dest prod"
  exit 1
}

echo "========================================"
echo "   Kapteins Daagbok Dev Environment   "
echo "========================================"
echo "Preparing to (re)start services..."

require_node_toolchain
check_dev_env

# Clean up processes running on ports
cleanup_port() {
  local port=$1
  if command -v lsof >/dev/null 2>&1; then
    local pid=$(lsof -t -i:$port)
    if [ ! -z "$pid" ]; then
      echo "Port $port is currently in use by PID $pid. Stopping process..."
      kill -9 $pid 2>/dev/null
    fi
  elif command -v fuser >/dev/null 2>&1; then
    echo "Port $port is currently in use. Stopping process..."
    fuser -k $port/tcp 2>/dev/null
  fi
}

cleanup_port $SERVER_PORT
cleanup_port $CLIENT_PORT

# Clean exit handler
cleanup_all() {
  echo ""
  echo "Stopping all dev servers..."
  # Kill all child jobs
  kill $(jobs -p) 2>/dev/null
  exit 0
}

# Trap termination signals
trap cleanup_all SIGINT SIGTERM EXIT

# Manage PostgreSQL Docker container
if command -v docker >/dev/null 2>&1; then
  echo "Checking PostgreSQL Docker container (postgres-daagbox)..."
  if docker ps -a --format '{{.Names}}' | grep -Eq "^postgres-daagbox$"; then
    echo "Found existing postgres-daagbox container. Restarting..."
    docker restart postgres-daagbox >/dev/null
  else
    echo "postgres-daagbox container not found. Creating and starting a new one..."
    docker run -d \
      --name postgres-daagbox \
      -p 5432:5432 \
      -e POSTGRES_USER=postgres \
      -e POSTGRES_PASSWORD=postgres \
      -e POSTGRES_DB=daagbox \
      postgres:16 >/dev/null
  fi

  # Wait for PostgreSQL to be ready
  echo "Waiting for PostgreSQL database to be ready..."
  TIMEOUT=15
  COUNTER=0
  until docker exec postgres-daagbox pg_isready -U postgres >/dev/null 2>&1; do
    sleep 0.5
    COUNTER=$((COUNTER + 1))
    if [ $COUNTER -ge 30 ]; then
      echo "Warning: PostgreSQL did not start within $TIMEOUT seconds. Proceeding anyway..."
      break
    fi
  done
  if [ $COUNTER -lt 30 ]; then
    echo "PostgreSQL is ready!"
  fi
else
  echo "Warning: Docker command not found. Skipping PostgreSQL container management."
fi

# Sync Prisma client and database schema (dev)
sync_prisma_schema() {
  local server_dir="$REPO_ROOT/server"
  if [ ! -f "$server_dir/prisma/schema.prisma" ]; then
    return 0
  fi
  if [ ! -d "$server_dir/node_modules" ]; then
    echo "Warning: server/node_modules missing — skipping Prisma sync. Run: cd server && npm ci"
    return 0
  fi
  echo "Syncing Prisma client and database schema..."
  (
    cd "$server_dir" || exit 1
    npx prisma generate && npx prisma db push
  ) || {
    echo "Error: Prisma generate/db push failed. Check DATABASE_URL in .env and PostgreSQL."
    exit 1
  }
  echo "Prisma schema is in sync."
}

sync_prisma_schema

# Start backend server
echo "Starting backend API server..."
cd "$REPO_ROOT/server" || exit 1
if [ ! -d node_modules ]; then
  echo "Error: server/node_modules missing. Run: cd server && npm ci"
  exit 1
fi
npm run dev &
BACKEND_PID=$!
cd "$REPO_ROOT" || exit 1

# Sleep briefly to let server start up
sleep 1.5
if ! kill -0 "$BACKEND_PID" 2>/dev/null; then
  echo "Error: Backend dev server exited immediately. Check server logs above."
  exit 1
fi

# Start frontend client
echo "Starting frontend dev server..."
cd "$REPO_ROOT/client" || exit 1
if [ ! -d node_modules ]; then
  echo "Error: client/node_modules missing. Run: cd client && npm ci"
  kill "$BACKEND_PID" 2>/dev/null
  exit 1
fi
# Vite 6+ via plugin-react 4; refresh lockfile after package.json changes
if ! node -e "require.resolve('vite/package.json')" 2>/dev/null; then
  echo "Client dependencies incomplete — running npm ci..."
  npm ci || exit 1
fi
npm run dev &
CLIENT_PID=$!
cd "$REPO_ROOT" || exit 1

sleep 1.5
if ! kill -0 "$CLIENT_PID" 2>/dev/null; then
  echo "Error: Frontend dev server exited immediately. Check client logs above."
  kill "$BACKEND_PID" 2>/dev/null
  exit 1
fi

echo "========================================"
echo "Dev services are now running:"
echo " -> Backend:  http://localhost:$SERVER_PORT"
echo " -> Frontend: http://localhost:$CLIENT_PORT"
echo " -> API auth: HttpOnly session cookie (after Passkey login)"
echo " -> Health:   http://localhost:$SERVER_PORT/api/health"
echo "========================================"
echo "Press Ctrl+C to terminate both servers."
echo "========================================"

# Block to keep parent process alive
wait
