#!/usr/bin/env bash
# Build & start stack, ensure migration tracker, apply pending SQL from supabase/migrations.
# Postgres also runs supabase/migrations from initdb.d on first empty volume; the tracker
# avoids re-running destructive statements where possible and applies new files (e.g. 005+) on existing DBs.
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

STATE_DIR="$SCRIPT_DIR/.deploy"
STATE_FILE="$STATE_DIR/first-run-complete"
TRACKER_SQL="$SCRIPT_DIR/supabase/scripts/ensure_migration_tracker.sql"
COMPOSE="docker compose"

# Host port for ec-frontend (must match FRONTEND_PORT in .env; used only for the done message)
load_frontend_port() {
  local def=8098
  local f="$SCRIPT_DIR/.env"
  [ ! -f "$f" ] && echo "$def" && return 0
  local line
  line=$(grep -E '^[[:space:]]*FRONTEND_PORT=' "$f" 2>/dev/null | tail -n1 || true)
  [ -z "$line" ] && echo "$def" && return 0
  local val="${line#*=}"
  val="${val%%$'\r'}"
  val="${val#"${val%%[![:space:]]*}"}"
  val="${val%"${val##*[![:space:]]}"}"
  case "$val" in ''|*[!0-9]*) echo "$def" ;; *) echo "$val" ;; esac
}

mkdir -p "$STATE_DIR"

# Create migration tracker table + legacy backfill (see supabase/scripts/ensure_migration_tracker.sql)
ensure_migration_tracker() {
  if [ ! -f "$TRACKER_SQL" ]; then
    echo "Missing $TRACKER_SQL" >&2
    exit 1
  fi
  echo "Ensuring schema_migrations tracker..."
  # shellcheck disable=SC2016
  $COMPOSE exec -T ec-db sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1' < "$TRACKER_SQL"
}

# Apply each *.sql in supabase/migrations (sorted) if not already recorded
apply_pending_migrations() {
  echo "Applying pending migration SQL files from supabase/migrations (sorted)..."
  shopt -s nullglob
  local files=("$SCRIPT_DIR"/supabase/migrations/*.sql)
  if [ ${#files[@]} -eq 0 ]; then
    echo "No SQL files found under supabase/migrations." >&2
    exit 1
  fi
  IFS=$'\n' sorted=($(printf '%s\n' "${files[@]}" | sort))
  for f in "${sorted[@]}"; do
    local base
    base=$(basename "$f")
    local already
    already="$($COMPOSE exec -T ec-db sh -lc "psql -U \"\$POSTGRES_USER\" -d \"\$POSTGRES_DB\" -tAc \"SELECT EXISTS(SELECT 1 FROM public.schema_migrations WHERE filename = '$base');\"" 2>/dev/null | tr -d '[:space:]' || echo "f")"
    if [ "$already" = "t" ]; then
      echo "  (skip) $base — already applied"
      continue
    fi
    echo "  -> $base"
    # shellcheck disable=SC2016
    $COMPOSE exec -T ec-db sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1' < "$f"
    # shellcheck disable=SC2016
    $COMPOSE exec -T ec-db sh -lc "psql -U \"\$POSTGRES_USER\" -d \"\$POSTGRES_DB\" -v ON_ERROR_STOP=1 -c \"INSERT INTO public.schema_migrations (filename) VALUES ('$base') ON CONFLICT (filename) DO NOTHING;\""
  done
}

wait_for_db() {
  local i=0
  echo "Waiting for ec-db to accept connections..."
  while [ $i -lt 60 ]; do
    # shellcheck disable=SC2016
    if $COMPOSE exec -T ec-db sh -lc 'pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"' >/dev/null 2>&1; then
      echo "ec-db is ready."
      return 0
    fi
    i=$((i + 1))
    sleep 2
  done
  echo "Timeout waiting for ec-db." >&2
  exit 1
}

FIRST_RUN=0
[ ! -f "$STATE_FILE" ] && FIRST_RUN=1

if [ ! -f "$SCRIPT_DIR/.env" ] && [ -f "$SCRIPT_DIR/.env.example" ]; then
  echo "Note: .env missing — copy .env.example to .env and configure before production."
fi

# Stop and remove existing compose project so deploy starts from a clean stack
echo "Stopping stack (docker compose down)..."
$COMPOSE down

echo "Building images and starting stack (ec-api, ec-frontend, …)..."
$COMPOSE up -d --build

wait_for_db

ensure_migration_tracker
apply_pending_migrations

if [ "$FIRST_RUN" -eq 1 ]; then
  date -u +"%Y-%m-%dT%H:%M:%SZ" >"$STATE_FILE"
  echo "First deploy recorded at $STATE_FILE"
fi

FE_PORT="$(load_frontend_port)"
echo "Done. Frontend: http://localhost:${FE_PORT}  API: http://localhost:3002"
