#!/usr/bin/env bash
###############################################################################
# run.sh — Proxym Simple Example: 3 Tickets with Sequential Analysis
#
# The simplest proxym workflow:
#   1. Register a project
#   2. Create 3 tickets
#   3. Dispatch each one to an AI tool
#   4. Analyze each ticket's result after completion
#
# Usage:
#   bash examples/simple-3-tickets/run.sh
#   bash examples/simple-3-tickets/run.sh --dry-run
#   bash examples/simple-3-tickets/run.sh --tool claude-code
#
# Prerequisites:
#   - proxym server running (proxym serve)
###############################################################################
set -euo pipefail

# ── Configuration ────────────────────────────────────────────────────────────

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROXYM_URL="${PROXYM_URL:-${DEFAULT_PROXY_URL:-http://localhost:4000}}"
PROJECT_DIR="${PROJECT_DIR:-$HOME/projects/simple-demo}"
PROJECT_NAME="simple-demo"
TOOL="${TOOL:-aider}"
DRY_RUN=false
WAIT_TIMEOUT=120  # seconds per job

while [[ $# -gt 0 ]]; do
  case "$1" in
    --dry-run)       DRY_RUN=true; shift ;;
    --project-dir)   PROJECT_DIR="$2"; shift 2 ;;
    --tool)          TOOL="$2"; shift 2 ;;
    --proxy)         PROXYM_URL="$2"; shift 2 ;;
    --help|-h)
      sed -n '2,/^###/p' "$0" | head -n -1 | sed 's/^# \?//'
      exit 0
      ;;
    *) echo "Unknown option: $1"; exit 1 ;;
  esac
done

CLI="proxym --proxy $PROXYM_URL"

# ── Helpers ──────────────────────────────────────────────────────────────────

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

_hdr()  { echo -e "\n${BOLD}${CYAN}═══ $1 ═══${RESET}"; }
_ok()   { echo -e "  ${GREEN}✓${RESET} $1"; }
_warn() { echo -e "  ${YELLOW}⚠${RESET} $1"; }
_fail() { echo -e "  ${RED}✗${RESET} $1"; }
_info() { echo -e "  ${DIM}$1${RESET}"; }

# Extract ticket ID from proxym output
_extract_tid() {
  grep -oE 'TKT-[A-F0-9]+' | head -1
}

# ── Load .env from repo root ────────────────────────────────────────────────

_load_env() {
  local env_file
  env_file="$(cd "$SCRIPT_DIR" && git rev-parse --show-toplevel 2>/dev/null)/.env"
  [[ -z "$env_file" ]] && env_file="${SCRIPT_DIR}/../../.env"
  if [[ -f "$env_file" ]]; then
    set -a
    # shellcheck disable=SC1090
    source <(grep -E '^[A-Z_]+=.+' "$env_file" | grep -v '^#')
    set +a
    _ok "Loaded .env from ${env_file}"
  else
    _warn "No .env found (looked for ${env_file})"
  fi
}

# ── API Key helpers ──────────────────────────────────────────────────────────

_required_api_key_for_tool() {
  local tool="$1"
  case "$tool" in
    aider|claude-code|cline)  echo "ANTHROPIC_API_KEY" ;;
    cursor|windsurf|vscode)   echo "OPENAI_API_KEY" ;;
    *)                        echo "ANTHROPIC_API_KEY" ;;
  esac
}

_ensure_api_key() {
  local tool="$1"
  local key_name
  key_name=$(_required_api_key_for_tool "$tool")
  local key_val="${!key_name:-}"

  if [[ -n "$key_val" ]]; then
    _ok "${key_name} is set (${#key_val} chars)"
    return 0
  fi

  _warn "${key_name} is not set — required by tool '${tool}'"

  # Option A: Interactive terminal — prompt directly
  if [[ -t 0 ]]; then
    echo ""
    echo -e "  ${BOLD}The tool '${tool}' needs ${key_name} to generate code.${RESET}"
    echo -e "  You can paste it now, or press Enter to create a human ticket instead."
    echo ""
    read -rp "  ${key_name}= " user_key
    if [[ -n "$user_key" ]]; then
      export "${key_name}=${user_key}"
      _ok "${key_name} set from interactive input"
      return 0
    fi
  fi

  # Option B: Create a human ticket and wait for the response
  _info "Creating a human ticket to collect ${key_name}..."

  local ticket_out
  ticket_out=$($CLI ticket add \
    "Provide ${key_name} for tool '${tool}'" \
    -t human \
    --priority high --type task 2>&1)
  local human_tid
  human_tid=$(echo "$ticket_out" | _extract_tid)

  if [[ -z "$human_tid" ]]; then
    _fail "Could not create human ticket. Please set ${key_name} manually."
    echo "    export ${key_name}=sk-..."
    echo "    Or add it to .env and re-run."
    exit 1
  fi

  $CLI ticket comment "$human_tid" \
    --author system \
    --content "Please reply with the API key value for ${key_name}. Add a comment to this ticket with just the key (e.g. sk-ant-...). The script will pick it up automatically and continue." \
    2>/dev/null || true

  _ok "Human ticket created: ${human_tid}"
  echo ""
  echo -e "  ${BOLD}Waiting for human input...${RESET}"
  echo -e "  Add the API key as a comment to ticket ${human_tid}:"
  echo -e "    ${DIM}proxym ticket comment ${human_tid} --author human --content 'sk-ant-...'${RESET}"
  echo -e "    ${DIM}Or use the Dashboard → Tickets → ${human_tid} → Add Comment${RESET}"
  echo ""

  local poll_elapsed=0
  local poll_max=600  # 10 minutes
  while [[ $poll_elapsed -lt $poll_max ]]; do
    local comments
    comments=$($CLI ticket show "$human_tid" 2>&1 | grep -A1 '\\[human\\]' | tail -1 || true)
    if [[ -z "$comments" ]]; then
      comments=$($CLI ticket show "$human_tid" --yaml 2>&1 \
        | grep -oP '(?<=content: ).*' \
        | grep -vE '^(Please reply|Auto-assigned)' \
        | head -1 || true)
    fi

    local found_key
    found_key=$(echo "$comments" | grep -oE 'sk-[A-Za-z0-9_-]{20,}' | head -1 || true)
    if [[ -n "$found_key" ]]; then
      export "${key_name}=${found_key}"
      _ok "${key_name} received from human ticket ${human_tid}"
      $CLI ticket update "$human_tid" --status done 2>/dev/null || true
      return 0
    fi

    sleep 5
    poll_elapsed=$((poll_elapsed + 5))
    printf "\r  ${DIM}⏳ Waiting for API key... (%ds/${poll_max}s) — add comment to ${human_tid}${RESET}" "$poll_elapsed"
  done

  echo ""
  _fail "Timeout waiting for ${key_name} via ticket ${human_tid}"
  echo "    Set it manually and re-run:"
  echo "    export ${key_name}=sk-..."
  exit 1
}

# Wait for all running/queued jobs to finish
_wait_for_jobs() {
  local max_wait="$1"
  local elapsed=0
  while [[ $elapsed -lt $max_wait ]]; do
    local active
    active=$($CLI q 2>&1 | grep -cE "\s(running|queued)\s*$" || true)
    [[ "$active" -eq 0 ]] && return 0
    sleep 3
    elapsed=$((elapsed + 3))
    printf "\r  ${DIM}⏳ Waiting for job... (%ds/${max_wait}s)${RESET}" "$elapsed"
  done
  echo ""
  _warn "Timeout after ${max_wait}s"
  return 1
}

# ── Main flow ────────────────────────────────────────────────────────────────

echo -e "${BOLD}${CYAN}"
echo "  ╔═══════════════════════════════════════════════════════════╗"
echo "  ║  Proxym: Simple 3-Ticket Example                        ║"
echo "  ║  Create → Dispatch → Analyze (one by one)               ║"
echo "  ╚═══════════════════════════════════════════════════════════╝"
echo -e "${RESET}"

# ── Step 1: Check prerequisites ──────────────────────────────────────────────

_hdr "Step 1 · Prerequisites"

if $DRY_RUN; then
  _info "[dry-run] Would check server at ${PROXYM_URL}"
  _info "[dry-run] Would load .env and check API keys"
else
  # Load .env first — provides API keys and DEFAULT_PROXY_URL
  _load_env

  if ! $CLI status >/dev/null 2>&1; then
    _fail "Proxym server not reachable at ${PROXYM_URL}"
    echo "    Start it with: proxym serve"
    exit 1
  fi
  _ok "Proxym server running at ${PROXYM_URL}"

  $CLI tools show "$TOOL" >/dev/null 2>&1 \
    && _ok "Tool '${TOOL}' available" \
    || _warn "Tool '${TOOL}' not found — will use LLM fallback"

  # Ensure the required API key is available before we start creating tickets
  _ensure_api_key "$TOOL"
fi

# ── Step 2: Create project directory & register ──────────────────────────────

_hdr "Step 2 · Register Project"

if $DRY_RUN; then
  _info "[dry-run] Would create ${PROJECT_DIR} and register as '${PROJECT_NAME}'"
else
  mkdir -p "${PROJECT_DIR}"
  _ok "Directory: ${PROJECT_DIR}"

  $CLI project add "${PROJECT_DIR}" --name "$PROJECT_NAME" --tool "$TOOL" 2>&1 \
    && _ok "Project registered: ${PROJECT_NAME}" \
    || _warn "Project may already exist (continuing)"
fi

# ── Step 3: Create and process 3 tickets sequentially ────────────────────────

# Define the 3 tickets
TICKET_1_DESC="Create a Python module utils.py with three string helper functions: slugify(text) that converts text to URL-friendly slugs, truncate(text, max_len) that truncates with ellipsis, and snake_case(text) that converts to snake_case. Include type hints and docstrings."
TICKET_2_DESC="Write pytest tests for utils.py in test_utils.py. Test each function (slugify, truncate, snake_case) with at least 3 test cases each, including edge cases like empty strings and special characters."
TICKET_3_DESC="Create a CLI entry point cli.py using argparse that exposes the utils.py functions as subcommands: slugify, truncate, snake-case. Each reads from stdin or accepts a positional argument. Include --help for each subcommand."

TICKET_1_TITLE="Create utils.py with string helper functions"
TICKET_2_TITLE="Write pytest tests for utils.py"
TICKET_3_TITLE="Add CLI entry point cli.py using argparse"

declare -a ALL_TITLES=("$TICKET_1_TITLE" "$TICKET_2_TITLE" "$TICKET_3_TITLE")
declare -a ALL_DESCS=("$TICKET_1_DESC" "$TICKET_2_DESC" "$TICKET_3_DESC")
declare -a ALL_TYPES=("feature" "test" "feature")
declare -a ALL_PRIORITIES=("high" "high" "medium")
declare -a ALL_TIDS=()

for i in 0 1 2; do
  local_num=$((i + 1))
  _hdr "Ticket ${local_num}/3 · ${ALL_TITLES[$i]}"

  if $DRY_RUN; then
    _info "[dry-run] Would create: ${ALL_TITLES[$i]}"
    _info "[dry-run] Would dispatch to ${TOOL}"
    _info "[dry-run] Would analyze result"
    continue
  fi

  # ── Create ticket ──
  _info "Creating ticket..."
  local_output=$($CLI ticket add "${ALL_TITLES[$i]}" \
    -p "$PROJECT_NAME" \
    -t "$TOOL" \
    --priority "${ALL_PRIORITIES[$i]}" \
    --type "${ALL_TYPES[$i]}" 2>&1)
  local_tid=$(echo "$local_output" | _extract_tid)

  if [[ -z "$local_tid" ]]; then
    _fail "Failed to create ticket: ${ALL_TITLES[$i]}"
    _info "Output: ${local_output}"
    continue
  fi
  ALL_TIDS+=("$local_tid")
  _ok "Created: ${local_tid}"

  # ── Dispatch ──
  _info "Dispatching ${local_tid} to ${TOOL}..."
  if $CLI tools dispatch --ticket "$local_tid" --tool "$TOOL" --project-dir "$PROJECT_DIR" 2>&1; then
    _ok "Dispatched to ${TOOL}"
  else
    _warn "Dispatch failed — skipping to next ticket"
    continue
  fi

  # ── Wait for completion ──
  _info "Waiting for job to complete..."
  if _wait_for_jobs "$WAIT_TIMEOUT"; then
    echo ""
    _ok "Job completed"
  else
    _warn "Job may still be running"
  fi

  # ── Analyze ──
  echo ""
  _info "Analyzing ticket ${local_tid}..."
  echo ""
  $CLI analyze "$local_tid" 2>/dev/null || _warn "Could not analyze ${local_tid}"
done

# ── Final summary ────────────────────────────────────────────────────────────

_hdr "Summary"

if $DRY_RUN; then
  _info "[dry-run] Would have created and analyzed 3 tickets"
  _info "Run without --dry-run to execute"
else
  echo ""
  _ok "All 3 tickets processed"
  echo ""

  # Show the board
  $CLI board 2>/dev/null || true

  echo ""
  echo -e "${BOLD}Useful commands:${RESET}"
  echo -e "  proxym board                     ${DIM}# kanban board${RESET}"
  echo -e "  proxym ticket list               ${DIM}# all tickets${RESET}"
  for tid in "${ALL_TIDS[@]}"; do
    echo -e "  proxym analyze ${tid}       ${DIM}# check result${RESET}"
  done
  echo -e "  proxym q                         ${DIM}# job queue${RESET}"
  echo ""

  # Show project files if any were created
  if ls "${PROJECT_DIR}"/*.py 2>/dev/null | head -1 >/dev/null 2>&1; then
    _ok "Files created in ${PROJECT_DIR}:"
    ls -la "${PROJECT_DIR}"/*.py 2>/dev/null | sed 's/^/    /'
  fi
fi

echo ""
_ok "Done!"
