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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKEND_DIR="$ROOT_DIR/backend"
WORKER_DIR="$BACKEND_DIR/worker"
WEB_DIR="$BACKEND_DIR/web"

PIDS=()

cleanup() {
  local pid
  for pid in "${PIDS[@]:-}"; do
    if kill -0 "$pid" 2>/dev/null; then
      kill "$pid" 2>/dev/null || true
    fi
  done
  wait 2>/dev/null || true
}
trap cleanup EXIT INT TERM

load_env() {
  if [[ -f "$BACKEND_DIR/.env" ]]; then
    set -a
    # shellcheck disable=SC1091
    source "$BACKEND_DIR/.env"
    set +a
  fi

  export HAIXUN_MONGO_URI="${HAIXUN_MONGO_URI:-mongodb://haixun:CHANGE_ME@127.0.0.1:27017/?authSource=admin}"
  export HAIXUN_MONGO_DB="${HAIXUN_MONGO_DB:-haixun}"
  export HAIXUN_REDIS_ADDR="${HAIXUN_REDIS_ADDR:-127.0.0.1:6379}"
  export HAIXUN_REDIS_PASSWORD="${HAIXUN_REDIS_PASSWORD:-CHANGE_ME}"
  export HAIXUN_JWT_ACCESS_SECRET="${HAIXUN_JWT_ACCESS_SECRET:-dev-access-secret-change-me}"
  export HAIXUN_JWT_REFRESH_SECRET="${HAIXUN_JWT_REFRESH_SECRET:-dev-refresh-secret-change-me}"
  export HAIXUN_WORKER_SECRET="${HAIXUN_WORKER_SECRET:-dev-worker-secret-change-me}"
  export HAIXUN_SECRETS_KEY="${HAIXUN_SECRETS_KEY:-}"
  export HAIXUN_BACKEND_URL="${HAIXUN_BACKEND_URL:-http://127.0.0.1:8890}"
  export HAIXUN_WORKER_POLL_MS="${HAIXUN_WORKER_POLL_MS:-3000}"
  export HAIXUN_8D_TARGET_SAMPLES="${HAIXUN_8D_TARGET_SAMPLES:-4}"
  export PLAYWRIGHT_HEADLESS="${PLAYWRIGHT_HEADLESS:-true}"
}

start() {
  local name="$1"
  shift
  echo "[dev-all] starting $name"
  "$@" &
  PIDS+=("$!")
}

wait_for_http() {
  local name="$1"
  local url="$2"
  local i
  for i in {1..40}; do
    if curl -fsS "$url" >/dev/null 2>&1; then
      echo "[dev-all] ready $name"
      return 0
    fi
    sleep 0.5
  done
  echo "[dev-all] $name did not become ready: $url" >&2
  return 1
}

pick_web_port() {
  python3 - <<'PY'
import socket

for port in range(5173, 5200):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.settimeout(0.1)
        if sock.connect_ex(('127.0.0.1', port)) != 0:
            print(port)
            raise SystemExit(0)
raise SystemExit('no free Vite port found in 5173..5199')
PY
}

load_env

cd "$BACKEND_DIR"
mkdir -p bin
go build -o bin/gateway gateway.go
go build -o bin/worker ./cmd/worker

cd "$WORKER_DIR"
npm install

cd "$WEB_DIR"
npm install

cd "$BACKEND_DIR"
start "gateway" ./bin/gateway -f etc/gateway.yaml
wait_for_http "gateway" "http://127.0.0.1:8890/api/v1/health"

GO_WORKER_TYPES=(
  go-demo
  go-expand-graph
  go-placement-scan
  go-scan-viral
  go-analyze-copy-mission
  go-expand-copy-mission-graph
  go-generate-copy-matrix
  go-generate-copy-draft
  go-generate-outreach-draft
  go-generate-topic-matrix
  go-generate-formula-draft
  go-generate-rewrite-draft
  go-refresh-threads-token
  go-publish-analytics
  go-refill-publish-inventory
)

for worker_type in "${GO_WORKER_TYPES[@]}"; do
  start "worker:$worker_type" env \
    HAIXUN_JOB_WORKER_TYPE="$worker_type" \
    HAIXUN_JOB_WORKER_ID="local-$worker_type" \
    ./bin/worker -f etc/gateway.worker.yaml
done

cd "$WORKER_DIR"
start "node-tool:keyword-search" env PORT=9101 npm run keyword-search-server
start "node-tool:resolve-media" env PORT=9102 npm run resolve-media-server
start "node-worker:style-8d" env \
  HAIXUN_NODE_WORKER_TYPE=node-style-8d \
  HAIXUN_NODE_WORKER_ID=local-node-style-8d \
  npm run style-8d

wait_for_http "keyword-search tool" "http://127.0.0.1:9101/health"
wait_for_http "resolve-media tool" "http://127.0.0.1:9102/health"

cd "$WEB_DIR"
WEB_PORT="${WEB_PORT:-$(pick_web_port)}"
start "web" npm run dev -- --host 0.0.0.0 --port "$WEB_PORT" --strictPort
wait_for_http "web" "http://127.0.0.1:$WEB_PORT/"

echo
echo "[dev-all] all services are running"
echo "[dev-all] API: http://127.0.0.1:8890/api/v1/health"
echo "[dev-all] Web: http://127.0.0.1:$WEB_PORT/"
echo "[dev-all] Press Ctrl+C to stop"

wait -n
