#!/usr/bin/env bash
# Start Agnet frontend + mpgis core-api with PostgreSQL and Prisma schema sync.
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BACKEND_ROOT="${MPGIS_BACKEND_ROOT:-$ROOT_DIR/../mpgis-farmer-platform}"
COMPOSE_FILE="$ROOT_DIR/scripts/docker-postgres-dev.yml"
CORE_API_PORT="${CORE_API_PORT:-4000}"
FRONTEND_PORT="${FRONTEND_PORT:-3000}"
START_DOCKER="${START_DOCKER:-true}"

DATABASE_URL="${DATABASE_URL:-}"

CORE_API_PID=""

log() {
  printf '\n[%s] %s\n' "$(date '+%H:%M:%S')" "$*"
}

fail() {
  printf '\n[error] %s\n' "$*" >&2
  exit 1
}

cleanup() {
  if [[ -n "$CORE_API_PID" ]] && kill -0 "$CORE_API_PID" 2>/dev/null; then
    log "Stopping core-api (pid $CORE_API_PID)"
    kill "$CORE_API_PID" 2>/dev/null || true
    wait "$CORE_API_PID" 2>/dev/null || true
  fi
}

trap cleanup EXIT INT TERM

port_in_use() {
  nc -z localhost "$1" >/dev/null 2>&1
}

find_free_port() {
  local port
  for port in 5432 5433 5434 5435 5436 5437 5438 5439 5440; do
    if ! port_in_use "$port"; then
      echo "$port"
      return 0
    fi
  done
  return 1
}

ensure_postgres() {
  local host_port

  if [[ -n "${DATABASE_URL}" ]]; then
    log "Using DATABASE_URL from environment"
    return
  fi

  if [[ "$START_DOCKER" != "true" ]]; then
    fail "PostGIS is required. Set START_DOCKER=true (default) or provide a PostGIS DATABASE_URL"
  fi

  host_port="$(find_free_port)" || fail "No free port found between 5432-5440 for PostGIS"
  log "Starting PostGIS via Docker on :$host_port"

  POSTGRES_HOST_PORT="$host_port" docker compose -f "$COMPOSE_FILE" up -d postgres \
    || fail "Failed to start PostGIS container"

  DATABASE_URL="postgresql://mpgis:mpgis_dev@localhost:${host_port}/mpgis_farmer?schema=public"

  log "Waiting for PostGIS on :$host_port"
  for _ in $(seq 1 45); do
    if docker compose -f "$COMPOSE_FILE" exec -T postgres pg_isready -U mpgis >/dev/null 2>&1; then
      break
    fi
    sleep 1
  done
  docker compose -f "$COMPOSE_FILE" exec -T postgres pg_isready -U mpgis >/dev/null \
    || fail "PostGIS did not become ready"

  docker compose -f "$COMPOSE_FILE" exec -T postgres \
    psql -U mpgis -d mpgis_farmer -c "CREATE EXTENSION IF NOT EXISTS postgis;" >/dev/null 2>&1 \
    || true
}

[[ -d "$BACKEND_ROOT" ]] || fail "Backend not found at $BACKEND_ROOT (set MPGIS_BACKEND_ROOT to override)"
[[ -f "$COMPOSE_FILE" ]] || fail "Docker compose file not found at $COMPOSE_FILE"
command -v docker >/dev/null || fail "docker is required"
command -v pnpm >/dev/null || fail "pnpm is required (install in mpgis-farmer-platform)"
command -v nc >/dev/null || fail "nc (netcat) is required"
command -v curl >/dev/null || fail "curl is required"

ensure_postgres
export DATABASE_URL

log "Syncing database schema (prisma db push)"
(
  cd "$BACKEND_ROOT"
  pnpm --filter @mpgis/database db:generate
  pnpm --filter @mpgis/database exec prisma db push --skip-generate --accept-data-loss
)

log "Seeding reference data and platform config"
(
  cd "$BACKEND_ROOT"
  pnpm --filter @mpgis/database db:seed
)

log "Starting core-api on :$CORE_API_PORT"
(
  cd "$BACKEND_ROOT"
  export JWT_SECRET="${JWT_SECRET:-dev-jwt-secret}"
  export PORT="$CORE_API_PORT"
  pnpm --filter @mpgis/core-api dev
) &
CORE_API_PID=$!

log "Waiting for core-api health check"
for _ in $(seq 1 90); do
  if curl -sf "http://localhost:$CORE_API_PORT/health" >/dev/null; then
    break
  fi
  if ! kill -0 "$CORE_API_PID" 2>/dev/null; then
    fail "core-api exited before becoming healthy"
  fi
  sleep 1
done
curl -sf "http://localhost:$CORE_API_PORT/health" >/dev/null \
  || fail "core-api did not respond on http://localhost:$CORE_API_PORT/health"

log "Starting Agnet frontend on :$FRONTEND_PORT"
cd "$ROOT_DIR"
export CORE_API_URL="http://localhost:$CORE_API_PORT"
export CORE_API_USE_MOCK=false
exec npm run dev -- --port "$FRONTEND_PORT"
