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

DIR="$(cd "$(dirname "$0")" && pwd)"
DASHBOARD="$DIR/apps/dashboard"

# `./aeon` with no args launches the web dashboard (below). `./aeon <command> …`
# is the non-interactive CLI — delegate straight to it (it has its own, lighter
# preflight, so read-only commands work without gh). See apps/cli/.
if [ "$#" -gt 0 ]; then
  exec "$DIR/apps/cli/aeon" "$@"
fi

# Preflight: the dashboard's /api/* routes shell out to `gh` for secrets,
# workflow runs, and auth. Without an authenticated gh CLI nothing works,
# and the failure shows up much later as a 503 in the Connect modal.
if ! command -v gh >/dev/null 2>&1; then
  cat >&2 <<'EOF'
GitHub CLI (`gh`) not found.

The dashboard uses `gh` to manage repo secrets, dispatch workflows, and
read your repo. Install it before launching:

  macOS:        brew install gh   (or download the arm64/amd64 binary from
                                   https://github.com/cli/cli/releases and
                                   put it on PATH — no sudo required)
  Linux:        see https://github.com/cli/cli#installation
  Windows:      winget install --id GitHub.cli

Then run: gh auth login

No terminal setup wanted? Aeon Connect runs the same dashboard in your
browser, nothing to install: https://www.aeon.fun/connect
EOF
  exit 1
fi

if ! gh auth status >/dev/null 2>&1; then
  cat >&2 <<'EOF'
GitHub CLI is installed but not authenticated.

Run:  gh auth login

Then re-run ./aeon. The dashboard also needs a default repo — once you've
created/cloned your own copy, set it with:

  gh repo set-default <owner>/<repo>

No terminal setup wanted? Aeon Connect runs the same dashboard in your
browser, nothing to install: https://www.aeon.fun/connect
EOF
  exit 1
fi

cd "$DASHBOARD"

# Install deps on first run. Quietly: the raw npm output is pages of peer
# warnings (eslint plugin ranges) and an audit of dev-only lint deps, which
# reads like an error to a first-time user. It goes to a log that is shown
# only when the install fails. `npm ci` when the lockfile exists, so the
# install is exactly what CI tested.
if [ ! -d node_modules ]; then
  echo "Installing dashboard dependencies (first run only)..."
  NPM_LOG="$(mktemp "${TMPDIR:-/tmp}/aeon-npm-install.XXXXXX")"
  NPM_CMD=install
  [ -f package-lock.json ] && NPM_CMD=ci
  if ! npm "$NPM_CMD" --no-audit --no-fund --loglevel=error >"$NPM_LOG" 2>&1; then
    echo "npm $NPM_CMD failed. Last lines (full log: $NPM_LOG):" >&2
    tail -n 30 "$NPM_LOG" >&2
    exit 1
  fi
  rm -f "$NPM_LOG"
fi

PORT="${PORT:-5555}"

# Kill any existing next dev server in this directory
LOCKFILE="$DASHBOARD/.next/dev/lock"
if [ -f "$LOCKFILE" ]; then
  OLD_PID=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1]))['pid'])" "$LOCKFILE" 2>/dev/null || true)
  if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then
    echo "Stopping existing dev server (PID $OLD_PID)..."
    kill "$OLD_PID" 2>/dev/null || true
    sleep 1
  fi
  rm -f "$LOCKFILE"
fi

# Find an open port starting from $PORT
while lsof -iTCP:"$PORT" -sTCP:LISTEN -t >/dev/null 2>&1; do
  PORT=$((PORT + 1))
done

# Banner. Plain one-column characters only inside the box (an emoji is two
# columns wide in most terminals and breaks the right edge), and every row is
# padded to the same inner width, whatever the port length.
URL="http://127.0.0.1:$PORT"
INNER=38
[ $((${#URL} + 6)) -gt "$INNER" ] && INNER=$((${#URL} + 6))
bar="$(printf '%*s' "$INNER" '' | sed 's/ /═/g')"
row() { printf '  ║%-*s║\n' "$INNER" "$1"; }
TITLE="Aeon Dashboard"
pad=$(((INNER - ${#TITLE}) / 2))
echo ""
echo "  ╔${bar}╗"
row "$(printf '%*s%s' "$pad" '' "$TITLE")"
row ""
row "   -> $URL"
row ""
echo "  ╚${bar}╝"
echo ""

# Bind loopback only. The /api/* routes can set/delete repo secrets and
# dispatch runs; the Host/Origin gate in lib/security/api-gate.ts only stops
# browsers, so a LAN peer must not be able to reach the port at all.
npm run dev -- -H 127.0.0.1 -p "$PORT"
