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

# zc-deploy — deploy zync-www / zync-app to dev Cloudflare Workers domains.

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

TARGET="all"
DRY_RUN=0
SKIP_BUILD=0

log()   { echo -e "${CYAN}[zc-deploy]${RESET} $*"; }
ok()    { echo -e "${GREEN}[PASS]${RESET} $*"; }
warn()  { echo -e "${YELLOW}[WARN]${RESET} $*"; }
fail()  { echo -e "${RED}[FAIL]${RESET} $*" >&2; }
die()   { fail "$*"; exit 1; }
header(){ echo -e "\n${BOLD}=== $* ===${RESET}"; }

usage() {
  cat <<'EOF'
Usage: deploy.sh [TARGET] [FLAGS]

Targets (default: --all):
  --www | www     Deploy zync-www  -> https://dev.zync.is
  --app | app     Deploy zync-app  -> https://app.dev.zync.is
  --all | all     Deploy both (www first)

Flags:
  --dry-run       Build + wrangler deploy --dry-run only (no real deploy)
  --skip-build    Skip pnpm build; deploy existing dist/
  -h, --help      Show this help

Examples:
  deploy.sh --all
  deploy.sh --www --dry-run
  deploy.sh app --skip-build
EOF
}

parse_args() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --www|www)   TARGET="www" ;;
      --app|app)   TARGET="app" ;;
      --all|all)   TARGET="all" ;;
      --dry-run)   DRY_RUN=1 ;;
      --skip-build) SKIP_BUILD=1 ;;
      -h|--help)   usage; exit 0 ;;
      *)
        die "Unknown argument: $1 (try --help)"
        ;;
    esac
    shift
  done
}

REPO_ROOT=""
declare -a DEPLOYED=()
declare -a FAILED=()

precheck_auth() {
  log "Checking wrangler auth..."
  if ! pnpm exec wrangler whoami >/dev/null 2>&1; then
    die "wrangler not logged in. Run: pnpm exec wrangler login"
  fi
  ok "wrangler auth OK"
}

verify_url() {
  local url="$1"
  local app_name="$2"
  local extra_check="${3:-}"

  log "Post-deploy verify: GET $url"
  local body http_code
  body="$(curl -fsSL -w '\n%{http_code}' "$url" 2>/dev/null || true)"
  http_code="${body##*$'\n'}"
  body="${body%$'\n'*}"

  if [[ "$http_code" != "200" ]]; then
    fail "$app_name: HTTP $http_code (expected 200)"
    return 1
  fi

  if [[ -n "$extra_check" ]] && ! grep -q "$extra_check" <<<"$body"; then
    fail "$app_name: response missing expected marker: $extra_check"
    return 1
  fi

  ok "$app_name: live at $url"
  return 0
}

run_dry_run() {
  local app_name="$1"
  local output
  local rc=0

  output="$(pnpm exec wrangler deploy --env="" --dry-run 2>&1)" || rc=$?

  if [[ $rc -ne 0 ]]; then
    echo "$output" >&2
    die "$app_name: wrangler deploy --dry-run failed (exit $rc)"
  fi

  if [[ "$app_name" == "zync-www" ]]; then
    if ! grep -q "Attaching additional modules" <<<"$output"; then
      echo "$output" >&2
      die "$app_name: SSR guard FAILED — dry-run missing 'Attaching additional modules' (assets-only deploy would drop SSR)"
    fi
    ok "$app_name: SSR guard passed (additional modules attached)"
  else
    ok "$app_name: dry-run OK"
  fi
}

deploy_one() {
  local app_name="$1"
  local app_dir="$2"
  local url="$3"

  header "Deploy $app_name -> $url"

  if [[ ! -d "$REPO_ROOT/$app_dir" ]]; then
    die "App directory not found: $REPO_ROOT/$app_dir"
  fi

  cd "$REPO_ROOT/$app_dir"

  if [[ "$SKIP_BUILD" -eq 0 ]]; then
    log "Building $app_name..."
    if [[ "$app_name" == "zync-www" ]]; then
      export PUBLIC_API_BASE_URL="https://app.dev.zync.is"
      export PUBLIC_APP_URL="https://app.dev.zync.is"
      export PUBLIC_R2_BASE_URL=""
    fi
    pnpm run build
    ok "Build complete"
  else
    warn "Skipping build (--skip-build)"
  fi

  log "Running wrangler deploy --dry-run..."
  run_dry_run "$app_name"

  if [[ "$DRY_RUN" -eq 1 ]]; then
    ok "Would deploy $app_name -> $url (dry-run only)"
    DEPLOYED+=("$app_name (dry-run)")
    return 0
  fi

  log "Deploying $app_name..."
  pnpm exec wrangler deploy --env=""
  ok "wrangler deploy succeeded"

  if verify_url "$url" "$app_name" "${4:-}"; then
    DEPLOYED+=("$app_name")
    return 0
  else
    FAILED+=("$app_name")
    return 1
  fi
}

print_summary() {
  header "Summary"
  if [[ ${#DEPLOYED[@]} -gt 0 ]]; then
    for item in "${DEPLOYED[@]}"; do
      ok "Deployed: $item"
    done
  fi
  if [[ ${#FAILED[@]} -gt 0 ]]; then
    for item in "${FAILED[@]}"; do
      fail "Failed: $item"
    done
    exit 1
  fi
  if [[ ${#DEPLOYED[@]} -eq 0 ]]; then
    warn "Nothing deployed"
  fi
}

main() {
  parse_args "$@"

  REPO_ROOT="$(git rev-parse --show-toplevel)"
  cd "$REPO_ROOT"

  log "Repo root: $REPO_ROOT"
  log "Target: $TARGET | dry-run=$DRY_RUN | skip-build=$SKIP_BUILD"

  precheck_auth

  case "$TARGET" in
    www)
      deploy_one "zync-www" "apps/zync-www" "https://dev.zync.is" 'dir="rtl"'
      ;;
    app)
      deploy_one "zync-app" "apps/zync-app" "https://app.dev.zync.is"
      ;;
    all)
      deploy_one "zync-www" "apps/zync-www" "https://dev.zync.is" 'dir="rtl"'
      deploy_one "zync-app" "apps/zync-app" "https://app.dev.zync.is"
      ;;
    *)
      die "Invalid target: $TARGET"
      ;;
  esac

  print_summary
}

main "$@"
