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

ROOT="$(cd "$(dirname "$0")" && pwd)"
API_DIR="$ROOT/@applications/api"
WEB_DIR="$ROOT/@applications/web"
AI_DIR="$HOME/Code/@applications/@ai/services/ai-core"

# shellcheck source=/dev/null
source "${HOME}/Code/@packages/@ts/@cli/bash-templates/lib/colors.sh"
C=$CYAN G=$GREEN Y=$YELLOW M=$MAGENTA B=$BOLD R=$NC D=$DIM

cmd_help() {
  echo -e "${B}companion${R} — unified project runner\n"
  echo -e "${C}${B}Dev Workflow${R}"
  echo -e "  ${G}dev${R}              Start API + web                ${D}pnpm dev${R}"
  echo -e "  ${G}dev:all${R}           Start @ai + API + web          ${D}all 3 services${R}"
  echo -e "  ${G}dev:ai${R}           Start @ai service only         ${D}nest start --watch${R}"
  echo -e "  ${G}dev:api${R}          Start API only                 ${D}nest start --watch${R}"
  echo -e "  ${G}dev:web${R}          Start web only                 ${D}vite${R}"
  echo -e "  ${G}build${R}            Build all packages             ${D}pnpm -r build${R}"
  echo -e "  ${G}typecheck${R}        Type-check everything          ${D}pnpm -r typecheck${R}"
  echo -e "  ${G}lint${R}             Lint all packages              ${D}pnpm -r lint${R}"
  echo ""
  echo -e "${C}${B}Testing${R}"
  echo -e "  ${G}test${R}             Unit tests                     ${D}pnpm -r test${R}"
  echo -e "  ${G}test:e2e${R}         Playwright E2E tests           ${D}playwright test${R}"
  echo -e "  ${G}e2e:docker${R}       Docker E2E stack               ${D}docker compose e2e${R}"
  echo ""
  echo -e "${C}${B}Docker${R}"
  echo -e "  ${G}docker${R}           Start Postgres + Redis         ${D}docker compose up -d${R}"
  echo -e "  ${G}docker:stop${R}      Stop Postgres + Redis          ${D}docker compose down${R}"
  echo -e "  ${G}docker:status${R}    Show container status          ${D}docker compose ps${R}"
  echo ""
  echo -e "${C}${B}Database${R}"
  echo -e "  ${G}db:migrate${R}       Run dev migrations             ${D}typeorm migration:run${R}"
  echo -e "  ${G}db:generate${R} ${Y}<name>${R}  Generate migration          ${D}typeorm migration:generate${R}"
  echo -e "  ${G}db:reset${R}         Drop + recreate dev database   ${D}dropdb + createdb${R}"
  echo ""
  echo -e "${M}Usage:${R} ./run <command> [args...]"
}

case "${1:-help}" in

  # Dev workflow
  dev)
    echo -e "${C}Starting companion-api + companion-web...${R}"
    cd "$ROOT" && pnpm dev
    ;;
  dev:all)
    echo -e "${C}Starting @ai + companion-api + companion-web...${R}"
    # Start docker infra if not running
    if ! docker ps --filter "name=lilith-companion-postgres" --format '{{.Status}}' | grep -q "Up"; then
      echo -e "${Y}Starting docker infra...${R}"
      cd "$ROOT/@deployments" && docker compose up -d
      sleep 3
    fi
    if ! docker ps --filter "name=lilith-ai-postgres" --format '{{.Status}}' | grep -q "Up"; then
      echo -e "${Y}Starting @ai docker infra...${R}"
      cd "$HOME/Code/@applications/@ai" && docker compose up -d
      sleep 3
    fi
    # Start all 3 services
    trap 'kill 0' EXIT
    (cd "$AI_DIR" && pnpm start:dev) &
    sleep 3
    (cd "$API_DIR" && pnpm dev) &
    (cd "$WEB_DIR" && pnpm dev) &
    echo -e "${G}All services starting...${R}"
    echo -e "  @ai:           http://localhost:3790"
    echo -e "  companion-api: http://localhost:3850"
    echo -e "  companion-web: http://localhost:5850"
    echo -e "${D}Press Ctrl+C to stop all${R}"
    wait
    ;;
  dev:ai)
    echo -e "${C}Starting @ai service...${R}"
    cd "$AI_DIR" && pnpm start:dev
    ;;
  dev:api)
    echo -e "${C}Starting companion-api...${R}"
    cd "$API_DIR" && pnpm dev
    ;;
  dev:web)
    echo -e "${C}Starting companion-web...${R}"
    cd "$WEB_DIR" && pnpm dev
    ;;
  build)
    echo -e "${C}Building all packages...${R}"
    cd "$ROOT" && pnpm build
    ;;
  typecheck)
    echo -e "${C}Type-checking...${R}"
    cd "$ROOT" && pnpm typecheck
    ;;
  lint)
    echo -e "${C}Linting...${R}"
    cd "$ROOT" && pnpm lint
    ;;

  # Testing
  test)
    echo -e "${C}Running unit tests...${R}"
    cd "$ROOT" && pnpm test
    ;;
  test:e2e)
    shift
    echo -e "${C}Running E2E tests...${R}"
    cd "$ROOT/@tooling/e2e" && npx playwright test "$@"
    ;;
  e2e:docker)
    echo -e "${C}Running E2E tests in Docker...${R}"
    cd "$ROOT" && docker compose \
      -f "@tooling/e2e/docker-compose.e2e.yml" \
      up --build --abort-on-container-exit --exit-code-from e2e-tests
    ;;

  # Docker (local containers)
  docker)
    echo -e "${C}Starting Postgres + Redis...${R}"
    cd "$ROOT/@deployments" && docker compose up -d
    ;;
  docker:stop)
    echo -e "${C}Stopping containers...${R}"
    cd "$ROOT/@deployments" && docker compose down
    ;;
  docker:status)
    cd "$ROOT/@deployments" && docker compose ps
    ;;

  # Database
  db:migrate)
    echo -e "${C}Running database migrations...${R}"
    cd "$API_DIR"
    if [ -f "$ROOT/.env" ]; then
      set -a; source "$ROOT/.env"; set +a
    fi
    pnpm migration:run
    ;;
  db:generate)
    if [[ -z "${2:-}" ]]; then
      echo -e "${Y}Usage:${R} ./run db:generate <migration-name>"
      exit 1
    fi
    cd "$API_DIR"
    if [ -f "$ROOT/.env" ]; then
      set -a; source "$ROOT/.env"; set +a
    fi
    pnpm migration:generate "src/migrations/$2"
    ;;
  db:reset)
    if [ -f "$ROOT/.env" ]; then
      set -a; source "$ROOT/.env"; set +a
    fi
    DB="${DATABASE_NAME:-companion}"
    if [[ "$DB" == *prod* ]]; then
      echo -e "${Y}Refusing to reset production database: ${DB}${R}"
      exit 1
    fi
    echo -e "${Y}Dropping and recreating dev database: ${DB}${R}"
    PGPASSWORD="$DATABASE_PASSWORD" psql \
      -h "${DATABASE_HOST:-localhost}" \
      -p "${DATABASE_PORT:-26397}" \
      -U "${DATABASE_USER:-lilith}" \
      -d postgres \
      -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$DB' AND pid <> pg_backend_pid();" \
      > /dev/null 2>&1
    PGPASSWORD="$DATABASE_PASSWORD" dropdb \
      -h "${DATABASE_HOST:-localhost}" \
      -p "${DATABASE_PORT:-26397}" \
      -U "${DATABASE_USER:-lilith}" \
      --if-exists "$DB"
    PGPASSWORD="$DATABASE_PASSWORD" createdb \
      -h "${DATABASE_HOST:-localhost}" \
      -p "${DATABASE_PORT:-26397}" \
      -U "${DATABASE_USER:-lilith}" \
      "$DB"
    PGPASSWORD="$DATABASE_PASSWORD" psql \
      -h "${DATABASE_HOST:-localhost}" \
      -p "${DATABASE_PORT:-26397}" \
      -U "${DATABASE_USER:-lilith}" \
      "$DB" \
      -c 'CREATE EXTENSION IF NOT EXISTS pgcrypto;' \
      > /dev/null
    echo -e "${G}Database ${DB} reset.${R}"
    ;;

  # Help
  help|--help|-h) cmd_help ;;

  *)
    echo -e "${Y}Unknown command: $1${R}"
    cmd_help
    exit 1
    ;;
esac
