#!/usr/bin/env zsh
# onboard.sh — VSR Replatform: Full macOS onboarding script
# Checks, installs, and configures all tools required to run the VSR demo.
# Safe to re-run — skips anything already installed.
#
# Usage:
#   chmod +x onboard.sh && ./onboard.sh
#
# Requirements: macOS with internet access.
set -euo pipefail

# ── Colours ───────────────────────────────────────────────────────────────────

CYAN='\033[0;36m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'

ROOT="$(cd "$(dirname "$0")" && pwd)"
REQUIRED_NODE=24
REQUIRED_PNPM=10

# ── Utilities ─────────────────────────────────────────────────────────────────

step()    { echo "\n${BOLD}${CYAN}==> $1${NC}"; }
ok()      { echo "  ${GREEN}✓${NC} $1"; }
warn()    { echo "  ${YELLOW}⚠${NC} $1"; }
fail()    { echo "  ${RED}✗${NC} $1"; }
info()    { echo "  ${DIM}$1${NC}"; }

prompt_yn() {
  printf "  ${CYAN}$1 [Y/n]: ${NC}"
  read -r yn
  yn="${yn:-y}"
  [[ "$yn" =~ ^[Yy] ]]
}

# ── Banner ────────────────────────────────────────────────────────────────────

echo ""
echo "${BOLD}${CYAN}╔════════════════════════════════════════════════════════╗${NC}"
echo "${BOLD}${CYAN}║   VSR Replatform — macOS Onboarding & Environment Setup  ║${NC}"
echo "${BOLD}${CYAN}╠════════════════════════════════════════════════════════╣${NC}"
echo "${BOLD}${CYAN}║  This script will check and install all tools needed  ║${NC}"
echo "${BOLD}${CYAN}║  to run the Virtual Sales Rep development demo.       ║${NC}"
echo "${BOLD}${CYAN}╚════════════════════════════════════════════════════════╝${NC}"
echo ""

# ══════════════════════════════════════════════════════════════════════════════
# STEP 1: Xcode Command Line Tools
# ══════════════════════════════════════════════════════════════════════════════

step "1/8 — Xcode Command Line Tools"

if xcode-select -p &>/dev/null; then
  ok "Xcode CLT installed ($(xcode-select -p))"
else
  warn "Xcode CLT not found — installing..."
  info "A system dialog may appear. Click 'Install' and wait for it to finish."
  xcode-select --install 2>/dev/null || true
  echo ""
  echo "  ${YELLOW}⏳ Waiting for Xcode CLT installation to complete...${NC}"
  echo "  ${DIM}(Press Enter once the installer finishes)${NC}"
  read -r
  if xcode-select -p &>/dev/null; then
    ok "Xcode CLT installed"
  else
    fail "Xcode CLT installation failed. Please install manually and re-run."
    exit 1
  fi
fi

# ══════════════════════════════════════════════════════════════════════════════
# STEP 2: Homebrew
# ══════════════════════════════════════════════════════════════════════════════

step "2/8 — Homebrew"

if command -v brew &>/dev/null; then
  ok "Homebrew installed ($(brew --version | head -1))"
else
  warn "Homebrew not found — installing..."
  /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  # Add to PATH for Apple Silicon
  if [[ -f /opt/homebrew/bin/brew ]]; then
    eval "$(/opt/homebrew/bin/brew shellenv)"
    echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile
  fi
  ok "Homebrew installed"
fi

# ══════════════════════════════════════════════════════════════════════════════
# STEP 3: Git
# ══════════════════════════════════════════════════════════════════════════════

step "3/8 — Git"

if command -v git &>/dev/null; then
  ok "git $(git --version | awk '{print $3}')"
else
  warn "git not found — installing via Homebrew..."
  brew install git
  ok "git installed"
fi

# ══════════════════════════════════════════════════════════════════════════════
# STEP 4: NVM + Node.js
# ══════════════════════════════════════════════════════════════════════════════

step "4/8 — NVM + Node.js (v${REQUIRED_NODE}+)"

export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"

if [[ -s "$NVM_DIR/nvm.sh" ]]; then
  source "$NVM_DIR/nvm.sh"
  ok "nvm installed ($(nvm --version))"
else
  warn "nvm not found — installing..."
  curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
  export NVM_DIR="$HOME/.nvm"
  source "$NVM_DIR/nvm.sh"
  ok "nvm installed ($(nvm --version))"
  info "nvm has been added to your shell profile (~/.zshrc)"
fi

# Check Node version
CURRENT_NODE=""
if command -v node &>/dev/null; then
  CURRENT_NODE=$(node --version | sed 's/v//' | cut -d. -f1)
fi

if [[ -n "$CURRENT_NODE" && "$CURRENT_NODE" -ge "$REQUIRED_NODE" ]]; then
  ok "Node.js v$(node --version | sed 's/v//') (meets ≥${REQUIRED_NODE} requirement)"
else
  warn "Node.js v${REQUIRED_NODE}+ required (current: ${CURRENT_NODE:-none})"
  info "Installing Node ${REQUIRED_NODE} via nvm..."
  nvm install "$REQUIRED_NODE"
  nvm use "$REQUIRED_NODE"
  nvm alias default "$REQUIRED_NODE"
  ok "Node.js v$(node --version | sed 's/v//') installed and set as default"
fi

# ══════════════════════════════════════════════════════════════════════════════
# STEP 5: pnpm
# ══════════════════════════════════════════════════════════════════════════════

step "5/8 — pnpm (v${REQUIRED_PNPM}+)"

if command -v pnpm &>/dev/null; then
  PNPM_CURRENT=$(pnpm --version | cut -d. -f1)
  if [[ "$PNPM_CURRENT" -ge "$REQUIRED_PNPM" ]]; then
    ok "pnpm $(pnpm --version)"
  else
    warn "pnpm $(pnpm --version) found but v${REQUIRED_PNPM}+ required — upgrading..."
    npm install -g "pnpm@${REQUIRED_PNPM}"
    ok "pnpm $(pnpm --version) installed"
  fi
else
  warn "pnpm not found — installing..."
  npm install -g "pnpm@${REQUIRED_PNPM}"
  ok "pnpm $(pnpm --version) installed"
fi

# ══════════════════════════════════════════════════════════════════════════════
# STEP 6: Docker Desktop
# ══════════════════════════════════════════════════════════════════════════════

step "6/8 — Docker Desktop"

if command -v docker &>/dev/null && docker info &>/dev/null 2>&1; then
  ok "Docker running ($(docker --version | awk '{print $3}' | tr -d ','))"
else
  if command -v docker &>/dev/null; then
    warn "Docker CLI found but daemon not running."
    info "Please open Docker Desktop and wait for it to start."
  else
    warn "Docker not found — installing via Homebrew..."
    brew install --cask docker
    info "Docker Desktop installed. Please open it from Applications."
  fi
  echo ""
  echo "  ${YELLOW}⏳ Waiting for Docker daemon to become available...${NC}"
  echo "  ${DIM}(Open Docker Desktop, wait for the whale icon to settle, then press Enter)${NC}"
  read -r
  if docker info &>/dev/null 2>&1; then
    ok "Docker is running"
  else
    fail "Docker daemon not reachable. Start Docker Desktop and re-run this script."
    exit 1
  fi
fi

# ══════════════════════════════════════════════════════════════════════════════
# STEP 7: GitHub CLI (gh)
# ══════════════════════════════════════════════════════════════════════════════

step "7/8 — GitHub CLI (gh)"

if command -v gh &>/dev/null; then
  ok "gh $(gh --version | head -1 | awk '{print $3}')"
  # Check auth status
  if gh auth status &>/dev/null 2>&1; then
    ok "gh authenticated"
  else
    warn "gh not authenticated — run 'gh auth login' to authenticate"
    info "You can do this after onboarding. It's needed for PR creation."
  fi
else
  warn "gh not found — installing via Homebrew..."
  brew install gh
  ok "gh $(gh --version | head -1 | awk '{print $3}') installed"
  info "Run 'gh auth login' after onboarding to authenticate."
fi

# ══════════════════════════════════════════════════════════════════════════════
# STEP 8: Project Setup
# ══════════════════════════════════════════════════════════════════════════════

step "8/8 — Project dependencies & environment"

cd "$ROOT"

# ── GITHUB_NPM_TOKEN check ────────────────────────────────────────────────────
# Required to install @theorchard/* private packages from GitHub Packages.
# pnpm install will fail without this.
if [[ -z "${GITHUB_NPM_TOKEN:-}" ]]; then
  echo ""
  fail "GITHUB_NPM_TOKEN is not set — pnpm install will fail."
  echo "  ${BOLD}How to fix:${NC}"
  echo "  1. Create a GitHub Classic token with ${CYAN}read:packages${NC} scope"
  echo "     https://github.com/settings/tokens/new?scopes=read:packages"
  echo "  2. Authorize it for the ${CYAN}theorchard${NC} org (SAML SSO → Authorize)"
  echo "  3. Add to your shell profile (${DIM}~/.zshrc or ~/.zprofile${NC}):"
  echo "     ${CYAN}export GITHUB_NPM_TOKEN=ghp_yourTokenHere${NC}"
  echo "  4. Re-run this script: ${CYAN}./onboard.sh${NC}"
  echo ""
  exit 1
else
  ok "GITHUB_NPM_TOKEN is set"
fi

# pnpm install
if [[ ! -f "node_modules/.modules.yaml" ]]; then
  info "Installing project dependencies (pnpm install)..."
  pnpm install
  ok "Dependencies installed"
else
  ok "Dependencies already installed"
fi

# Docker Postgres
info "Starting PostgreSQL container..."
POSTGRES_STATUS=$(docker inspect --format '{{.State.Status}}' vsr-postgres 2>/dev/null || echo "missing")
if [[ "$POSTGRES_STATUS" == "running" ]]; then
  ok "vsr-postgres already running"
else
  (cd docker && docker compose up -d)
  ok "vsr-postgres started on :5432"
fi

# Frontend .env.local
if [[ ! -f "apps/vsr/.env.local" ]]; then
  if [[ -f "apps/vsr/.env.shadow" ]]; then
    cp "apps/vsr/.env.shadow" "apps/vsr/.env.local"
    ok "Created apps/vsr/.env.local from .env.shadow (VITE_DEV_MODE=true)"
  else
    warn "No apps/vsr/.env.shadow found — create apps/vsr/.env.local manually"
  fi
else
  ok "apps/vsr/.env.local exists"
fi

# Server .env.local
if [[ ! -f "packages/vsr-graphql-server/.env.local" ]]; then
  if [[ -f "packages/vsr-graphql-server/.env.shadow" ]]; then
    cp "packages/vsr-graphql-server/.env.shadow" "packages/vsr-graphql-server/.env.local"
    ok "Created packages/vsr-graphql-server/.env.local from .env.shadow"
    warn "Edit packages/vsr-graphql-server/.env.local: set DATABASE_URL password, SNOWFLAKE_USER, and SNOWFLAKE key path"
  else
    warn "No packages/vsr-graphql-server/.env.shadow found — create .env.local manually"
  fi
else
  ok "packages/vsr-graphql-server/.env.local exists"
fi

# Docker .env.docker
if [[ ! -f "docker/.env.docker" ]]; then
  if [[ -f "docker/.env.shadow" ]]; then
    cp "docker/.env.shadow" "docker/.env.docker"
    ok "Created docker/.env.docker from .env.shadow"
    warn "Edit docker/.env.docker: replace POSTGRES_PASSWORD with a local password, then update DATABASE_URL in the server .env.local to match"
  else
    warn "No docker/.env.shadow found — create docker/.env.docker manually"
  fi
else
  ok "docker/.env.docker exists"
fi

# ══════════════════════════════════════════════════════════════════════════════
# SUMMARY
# ══════════════════════════════════════════════════════════════════════════════

echo ""
echo "${BOLD}${GREEN}╔════════════════════════════════════════════════╗${NC}"
echo "${BOLD}${GREEN}║         ✓ Onboarding Complete!                 ║${NC}"
echo "${BOLD}${GREEN}╚════════════════════════════════════════════════╝${NC}"
echo ""
echo "  ${BOLD}Your environment:${NC}"
echo "    Node.js:  $(node --version)"
echo "    pnpm:     $(pnpm --version)"
echo "    Docker:   $(docker --version | awk '{print $3}' | tr -d ',')"
echo "    gh:       $(gh --version 2>/dev/null | head -1 | awk '{print $3}' || echo 'not installed')"
echo "    Postgres: :5432 (Docker)"
echo ""
echo "  ${BOLD}Project:${NC}"
echo "    Root:     $ROOT"
echo "    Branch:   $(git branch --show-current 2>/dev/null || echo 'unknown')"
echo "    Frontend: http://localhost:3000"
echo "    Stub GQL: http://localhost:4000/graphql"
echo ""

# ══════════════════════════════════════════════════════════════════════════════
# OFFER TO START DEMO
# ══════════════════════════════════════════════════════════════════════════════

if prompt_yn "Would you like to start the VSR demo now?"; then
  echo ""
  step "Starting VSR demo (stub mode)..."

  LOG_DIR="$ROOT/tmp/dev-logs"
  mkdir -p "$LOG_DIR"

  # Start stub server
  info "Starting stub GraphQL server on :4000..."
  (cd "$ROOT" && pnpm --filter vsr-graphql-stub dev > "$LOG_DIR/stub-server.log" 2>&1) &
  STUB_PID=$!
  sleep 2

  # Verify stub
  if curl -sf http://localhost:4000/graphql -X POST -H "Content-Type: application/json" -d '{"query":"{ ping }"}' &>/dev/null; then
    ok "Stub server running on :4000 (PID: $STUB_PID)"
  else
    warn "Stub server may still be starting (PID: $STUB_PID)"
  fi

  # Start frontend
  info "Starting frontend on :3000..."
  (cd "$ROOT/apps/vsr" && pnpm dev > "$LOG_DIR/frontend.log" 2>&1) &
  FRONTEND_PID=$!
  sleep 3

  # Verify frontend
  if curl -sf http://localhost:3000/ &>/dev/null; then
    ok "Frontend running on :3000 (PID: $FRONTEND_PID)"
  else
    warn "Frontend may still be starting (PID: $FRONTEND_PID)"
  fi

  echo ""
  echo "${BOLD}${GREEN}  ✓ VSR Demo is running!${NC}"
  echo ""
  echo "  ${BOLD}Open in browser:${NC}  http://localhost:3000"
  echo "  ${BOLD}GraphQL playground:${NC} http://localhost:4000/graphql"
  echo ""
  echo "  ${BOLD}Logs:${NC}"
  echo "    Frontend:  tail -f tmp/dev-logs/frontend.log"
  echo "    Stub:      tail -f tmp/dev-logs/stub-server.log"
  echo ""
  echo "  ${BOLD}To stop the demo:${NC}"
  echo "    ${CYAN}kill $STUB_PID $FRONTEND_PID${NC}"
  echo "    — or press Ctrl+C in this terminal"
  echo "    — or use Activity Monitor: filter by 'node', kill the vite/ts-node processes"
  echo ""
  echo "  ${BOLD}To restart later:${NC}"
  echo "    ${CYAN}./start-dev.sh${NC}"
  echo ""

  # Keep script alive so Ctrl+C cleanup works
  echo "${DIM}  (Press Ctrl+C to stop all services)${NC}"
  trap "kill $STUB_PID $FRONTEND_PID 2>/dev/null; echo '\n${GREEN}Demo stopped.${NC}'; exit 0" INT TERM
  wait
else
  echo ""
  echo "  ${BOLD}To start the demo later:${NC}"
  echo "    ${CYAN}./start-dev.sh${NC}      (interactive mode selector)"
  echo "    ${CYAN}pnpm dev${NC}            (all workspaces in parallel)"
  echo ""
  echo "  ${BOLD}Useful commands:${NC}"
  echo "    pnpm test         — run all tests"
  echo "    pnpm lint         — biome lint check"
  echo "    pnpm build        — production build"
  echo ""
fi
