#!/bin/bash
# Multi-agent task management CLI

set -e

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

# Track if defaults are being used
PROJECT_SPECIFIED=false
CLI_SPECIFIED=false

# Default project to current directory, can override with --project
PROJECT_DIR="${PROJECT_DIR:-$(pwd)}"
TASKS_DIR="${PROJECT_DIR}/tasks"
REGISTRY="${PROJECT_DIR}/.task-registry.json"

# Task creation options
TASK_FILE=""
TASK_GOAL=""

# Parse all arguments - flags can appear anywhere
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
  case $1 in
    --project)
      PROJECT_DIR="$2"
      TASKS_DIR="${PROJECT_DIR}/tasks"
      REGISTRY="${PROJECT_DIR}/.task-registry.json"
      PROJECT_SPECIFIED=true
      shift 2
      ;;
    --cli)
      CLI="$2"
      CLI_SPECIFIED=true
      shift 2
      ;;
    --goal)
      TASK_GOAL="$2"
      shift 2
      ;;
    --task-file)
      TASK_FILE="$2"
      shift 2
      ;;
    -*)
      echo "Error: Unknown flag '$1'"
      exit 1
      ;;
    *)
      POSITIONAL_ARGS+=("$1")
      shift
      ;;
  esac
done

# Restore positional args
set -- "${POSITIONAL_ARGS[@]}"

# CLI is mandatory
if [[ -z "$CLI" ]]; then
  echo "Error: --cli is required. Specify --cli claude or --cli kiro"
  exit 1
fi

# Show warning if using defaults
show_defaults_warning() {
  if [[ "$PROJECT_SPECIFIED" == "false" ]]; then
    echo "⚠️  Using default project: $(pwd)"
    echo ""
  fi
}

# Initialize registry if it doesn't exist
init_registry() {
  mkdir -p "$PROJECT_DIR"
  if [[ ! -f "$REGISTRY" ]]; then
    echo '{}' > "$REGISTRY"
  fi
}

# Check if running interactively
is_interactive() {
  [[ -t 0 && -t 1 ]]
}

cmd_create() {
  local TASK_NAME=$1

  if [[ -z "$TASK_NAME" ]]; then
    echo "Usage: $0 create <task-name> [--goal <text>] [--task-file <path>]"
    exit 1
  fi

  # Validate task name
  if [[ ! "$TASK_NAME" =~ ^[a-zA-Z0-9_-]+$ ]]; then
    echo "Error: Task name must contain only alphanumeric characters, hyphens, and underscores"
    exit 1
  fi

  show_defaults_warning

  init_registry
  local TASK_DIR="${TASKS_DIR}/${TASK_NAME}"

  if [[ -d "$TASK_DIR" ]]; then
    echo "Error: Task '${TASK_NAME}' already exists at ${TASK_DIR}"
    exit 1
  fi

  echo "Creating task: ${TASK_NAME}"
  echo "Project: ${PROJECT_DIR}"
  echo ""

  # Create structure
  mkdir -p "${TASK_DIR}"/{handoffs,artifacts,scratchpad}

  # Determine how to create task.md
  if [[ -n "$TASK_FILE" ]]; then
    # Use provided task file
    if [[ ! -f "$TASK_FILE" ]]; then
      echo "Error: Task file not found: ${TASK_FILE}"
      exit 1
    fi
    cp "$TASK_FILE" "${TASK_DIR}/task.md"
    echo "Copied task file: ${TASK_FILE}"
  elif [[ -n "$TASK_GOAL" ]]; then
    # Non-interactive: create task.md from goal
    cat > "${TASK_DIR}/task.md" <<EOF
# Task: ${TASK_NAME}

## Goal
${TASK_GOAL}

## Acceptance Criteria
- [ ] Complete the goal

## Context
No additional context provided.

## Validation
\`\`\`bash
# Add validation commands here
\`\`\`

## Agent Config
\`\`\`yaml
# Uncomment and configure as needed:
# dev:
#   cwd: user@host:/remote/path    # Remote coding via SSH
#   skills: [skill-name]
#
# architect:
#   cwd: user@host:/remote/path
#
# test:
#   cwd: /local/path               # Device access is always local
#   skills: [device-access]
\`\`\`

## Agent Guidance (Optional)

### explore
focus: ""
done_when: ""

### plan
constraints: ""

### dev
style_guide: ""
validation: ""

### review
critical_checks: ["correctness", "completeness"]
EOF
    echo "Created task with goal: ${TASK_GOAL}"
  elif is_interactive; then
    # Interactive mode: prompt for details
    echo "=== Task Setup ==="
    echo ""
    read -p "Goal (one line): " TASK_GOAL
    echo ""
    echo "Acceptance criteria (one per line, empty line to finish):"
    CRITERIA=""
    while IFS= read -r line; do
      [[ -z "$line" ]] && break
      CRITERIA="${CRITERIA}- [ ] ${line}\n"
    done
    echo ""
    read -p "Any context/background? (optional): " TASK_CONTEXT
    echo ""

    # Generate task.md
    cat > "${TASK_DIR}/task.md" <<EOF
# Task: ${TASK_NAME}

## Goal
${TASK_GOAL}

## Acceptance Criteria
$(echo -e "$CRITERIA")

## Context
${TASK_CONTEXT:-No additional context provided.}

## Validation
\`\`\`bash
# Add validation commands here
\`\`\`

## Agent Config
\`\`\`yaml
# Uncomment and configure as needed:
# dev:
#   cwd: user@host:/remote/path    # Remote coding via SSH
#   skills: [skill-name]
#
# architect:
#   cwd: user@host:/remote/path
#
# test:
#   cwd: /local/path               # Device access is always local
#   skills: [device-access]
\`\`\`

## Agent Guidance (Optional)

### explore
focus: ""
done_when: ""

### plan
constraints: ""

### dev
style_guide: ""
validation: ""

### review
critical_checks: ["correctness", "completeness"]
EOF
  else
    # Non-interactive without --goal: error
    echo "Error: Non-interactive mode requires --goal or --task-file"
    echo ""
    echo "Examples:"
    echo "  $0 --goal 'Fix the login bug' create my-task"
    echo "  $0 --task-file /path/to/task.md create my-task"
    exit 1
  fi

  # Initialize pm_state.json
  cat > "${TASK_DIR}/pm_state.json" <<EOF
{
  "status": "CREATED",
  "current_phase": "init",
  "spawned_agents": [],
  "iteration": 0,
  "last_checkin": null,
  "cli": "${CLI}"
}
EOF

  # Register task
  local CREATED=$(date -u +%Y-%m-%dT%H:%M:%SZ)
  jq --arg name "$TASK_NAME" \
     --arg status "CREATED" \
     --arg created "$CREATED" \
     --arg project "$PROJECT_DIR" \
     '.[$name] = {status: $status, created: $created, project: $project}' \
     "$REGISTRY" > "${REGISTRY}.tmp" && mv "${REGISTRY}.tmp" "$REGISTRY"

  echo ""
  echo "Task created: ${TASK_DIR}"
  echo ""
  echo "Next steps:"
  echo "  1. Edit task.md to refine goal, criteria, and agent config"
  echo "     vi ${TASK_DIR}/task.md"
  echo ""
  echo "  2. Start the PM agent:"
  echo "     $0 start ${TASK_NAME}"
}

cmd_start() {
  local TASK_NAME=$1

  if [[ -z "$TASK_NAME" ]]; then
    echo "Usage: $0 start <task-name> [--project <path>] [--cli claude|kiro]"
    exit 1
  fi

  # Validate task name
  if [[ ! "$TASK_NAME" =~ ^[a-zA-Z0-9_-]+$ ]]; then
    echo "Error: Task name must contain only alphanumeric characters, hyphens, and underscores"
    exit 1
  fi

  show_defaults_warning

  init_registry
  local TASK_DIR="${TASKS_DIR}/${TASK_NAME}"

  # Task must exist (created via 'create' command)
  if [[ ! -d "$TASK_DIR" ]]; then
    echo "Error: Task '${TASK_NAME}' not found at ${TASK_DIR}"
    echo ""
    echo "Create the task first:"
    echo "  $0 create ${TASK_NAME}"
    exit 1
  fi

  if [[ ! -f "${TASK_DIR}/task.md" ]]; then
    echo "Error: task.md not found in ${TASK_DIR}"
    exit 1
  fi

  echo "Starting task: ${TASK_NAME}"
  echo "Project: ${PROJECT_DIR}"
  echo ""

  # Update pm_state.json status
  jq '.status = "ACTIVE"' "${TASK_DIR}/pm_state.json" > "${TASK_DIR}/pm_state.json.tmp" \
    && mv "${TASK_DIR}/pm_state.json.tmp" "${TASK_DIR}/pm_state.json"

  # Update registry
  local STARTED=$(date -u +%Y-%m-%dT%H:%M:%SZ)
  jq --arg name "$TASK_NAME" \
     --arg status "ACTIVE" \
     --arg started "$STARTED" \
     '.[$name].status = $status | .[$name].started = $started' \
     "$REGISTRY" > "${REGISTRY}.tmp" && mv "${REGISTRY}.tmp" "$REGISTRY"

  # Check if agents exist
  if [[ "$CLI" == "kiro" ]]; then
    AGENT_DIR="${PROJECT_DIR}/.kiro/agents"
  else
    AGENT_DIR="${PROJECT_DIR}/.claude/agents"
  fi

  if [[ ! -f "${AGENT_DIR}/pm.md" ]] && [[ ! -f "${AGENT_DIR}/pm.json" ]]; then
    echo ""
    echo "Agents not found. Running setup-agents..."
    bash "${SCRIPT_DIR}/setup-agents" "$PROJECT_DIR"
  fi

  echo ""
  echo "Starting PM session..."

  # Spawn PM
  bash "${SCRIPT_DIR}/spawn_pm.sh" "$TASK_NAME" --project "$PROJECT_DIR" --cli "$CLI"

  echo ""
  echo "Task '${TASK_NAME}' started!"
  echo ""
  echo "Commands:"
  echo "  $0 status ${TASK_NAME}    # Check status"
  echo "  $0 attach ${TASK_NAME}    # Attach to PM"
  echo "  $0 stop ${TASK_NAME}      # Stop task"
}

cmd_list() {
  init_registry
  echo "═══════════════════════════════════════════════════════════"
  echo " TASKS (Project: ${PROJECT_DIR})"
  echo "═══════════════════════════════════════════════════════════"
  echo ""

  local active_count=0
  while IFS= read -r task; do
    if [[ -n "$task" ]]; then
      local started=$(jq -r ".\"${task}\".started" "$REGISTRY")
      local project=$(jq -r ".\"${task}\".project // \"unknown\"" "$REGISTRY")
      echo "  ● ${task}"
      echo "      Started: ${started}"
      echo "      Project: ${project}"

      local task_dir="${TASKS_DIR}/${task}"
      if [[ -f "${task_dir}/pm_state.json" ]]; then
        local phase=$(jq -r '.current_phase // "unknown"' "${task_dir}/pm_state.json")
        echo "      Phase: ${phase}"
      fi
      echo ""
      ((active_count++))
    fi
  done < <(jq -r 'to_entries[] | select(.value.status == "ACTIVE") | .key' "$REGISTRY" 2>/dev/null)

  if [[ $active_count -eq 0 ]]; then
    echo "  No active tasks"
    echo ""
  fi

  echo "───────────────────────────────────────────────────────────"
  echo " COMPLETED"
  echo "───────────────────────────────────────────────────────────"

  local complete_count=0
  while IFS= read -r task; do
    if [[ -n "$task" ]]; then
      echo "  ✓ ${task}"
      ((complete_count++))
    fi
  done < <(jq -r 'to_entries[] | select(.value.status == "COMPLETE") | .key' "$REGISTRY" 2>/dev/null)

  if [[ $complete_count -eq 0 ]]; then
    echo "  No completed tasks"
  fi
  echo ""
}

cmd_status() {
  local TASK_NAME=$1
  if [[ -z "$TASK_NAME" ]]; then
    echo "Usage: $0 status <task-name>"
    exit 1
  fi

  init_registry
  local TASK_DIR="${TASKS_DIR}/${TASK_NAME}"

  if [[ ! -d "$TASK_DIR" ]]; then
    echo "Error: Task not found: ${TASK_NAME}"
    exit 1
  fi

  echo "═══════════════════════════════════════════════════════════"
  echo " Task: ${TASK_NAME}"
  echo "═══════════════════════════════════════════════════════════"
  echo ""

  # Show progress.md if exists (from scribe)
  if [[ -f "${TASK_DIR}/progress.md" ]]; then
    cat "${TASK_DIR}/progress.md"
    echo ""
  else
    # Fallback to pm_state.json
    local phase=$(jq -r '.current_phase // "unknown"' "${TASK_DIR}/pm_state.json" 2>/dev/null)
    local iteration=$(jq -r '.iteration // 0' "${TASK_DIR}/pm_state.json" 2>/dev/null)
    local last_checkin=$(jq -r '.last_checkin // "never"' "${TASK_DIR}/pm_state.json" 2>/dev/null)

    echo "Phase: ${phase}"
    echo "Iteration: ${iteration}"
    echo "Last Check-in: ${last_checkin}"
    echo ""

    # List recent handoffs
    echo "Recent Handoffs:"
    ls -lt "${TASK_DIR}/handoffs" 2>/dev/null | head -5 | awk '{print "  " $NF}'
    echo ""
  fi

  # Show tmux session info
  local SESSION="task-${TASK_NAME}-pm"
  if tmux has-session -t "$SESSION" 2>/dev/null; then
    echo "Tmux Session: ${SESSION}"
    echo "Windows:"
    tmux list-windows -t "$SESSION" -F "  #{window_index}: #{window_name}" 2>/dev/null
    echo ""
  fi

  echo "───────────────────────────────────────────────────────────"
  echo "Commands:"
  echo "  $0 attach ${TASK_NAME}    # Attach to PM"
  echo "  $0 logs ${TASK_NAME}      # View handoffs"
  echo "  $0 stop ${TASK_NAME}      # Stop task"
}

cmd_attach() {
  local TASK_NAME=$1
  if [[ -z "$TASK_NAME" ]]; then
    echo "Usage: $0 attach <task-name>"
    exit 1
  fi

  local SESSION="task-${TASK_NAME}-pm"
  if ! tmux has-session -t "$SESSION" 2>/dev/null; then
    echo "Error: PM session not found: ${SESSION}"
    exit 1
  fi

  tmux attach-session -t "$SESSION"
}

cmd_stop() {
  local TASK_NAME=$1
  if [[ -z "$TASK_NAME" ]]; then
    echo "Usage: $0 stop <task-name>"
    exit 1
  fi

  init_registry
  local SESSION="task-${TASK_NAME}-pm"

  # Kill tmux session
  if tmux has-session -t "$SESSION" 2>/dev/null; then
    tmux kill-session -t "$SESSION"
    echo "Stopped tmux session: ${SESSION}"
  fi

  # Remove rsync cron entries for this task
  if crontab -l 2>/dev/null | grep -q "${TASK_NAME}"; then
    crontab -l 2>/dev/null | grep -v "${TASK_NAME}" | crontab -
    echo "Removed rsync cron jobs for: ${TASK_NAME}"
  fi

  # Update registry
  jq --arg name "$TASK_NAME" \
     --arg stopped "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
     '.[$name].status = "STOPPED" | .[$name].stopped = $stopped' \
     "$REGISTRY" > "${REGISTRY}.tmp" && mv "${REGISTRY}.tmp" "$REGISTRY"

  echo "Task '${TASK_NAME}' stopped"
}

cmd_logs() {
  local TASK_NAME=$1
  if [[ -z "$TASK_NAME" ]]; then
    echo "Usage: $0 logs <task-name>"
    exit 1
  fi

  local TASK_DIR="${TASKS_DIR}/${TASK_NAME}"
  if [[ ! -d "$TASK_DIR" ]]; then
    echo "Error: Task not found: ${TASK_NAME}"
    exit 1
  fi

  echo "Handoffs:"
  ls -lt "${TASK_DIR}/handoffs" 2>/dev/null | tail -n +2 | awk '{print "  " $NF " (" $6 " " $7 " " $8 ")"}'
  echo ""
  echo "Artifacts:"
  find "${TASK_DIR}/artifacts" -type f 2>/dev/null | sed 's/^/  /'
  echo ""
  echo "View: cat ${TASK_DIR}/handoffs/<filename>"
}

cmd_cleanup() {
  local TASK_NAME=$1
  if [[ -z "$TASK_NAME" ]]; then
    echo "Usage: $0 cleanup <task-name>"
    exit 1
  fi

  local TASK_DIR="${TASKS_DIR}/${TASK_NAME}"
  if [[ ! -d "$TASK_DIR" ]]; then
    echo "Error: Task not found: ${TASK_NAME}"
    exit 1
  fi

  # Stop if running
  local SESSION="task-${TASK_NAME}-pm"
  if tmux has-session -t "$SESSION" 2>/dev/null; then
    tmux kill-session -t "$SESSION"
    echo "Stopped tmux session: ${SESSION}"
  fi

  # Clean handoffs and scratchpad
  rm -rf "${TASK_DIR}/handoffs/"* "${TASK_DIR}/scratchpad/"*
  
  # Reset pm_state.json
  cat > "${TASK_DIR}/pm_state.json" <<EOF
{"status":"CREATED","current_phase":"init","spawned_agents":[],"iteration":0,"last_checkin":null,"cli":"${CLI}"}
EOF

  # Remove progress.md if exists
  rm -f "${TASK_DIR}/progress.md"

  echo "Cleaned up task '${TASK_NAME}' - handoffs, scratchpad, and pm_state reset"
}

cmd_ui() {
  bash "${SCRIPT_DIR}/tui"
}

cmd_help() {
  cat <<EOF
Multi-Agent Task Management CLI

Usage: $0 [global-flags] <command> [args]

Global Flags:
  --project <path>      Project directory (default: current directory)
  --cli claude|kiro     CLI to use (default: kiro)

Create Command Flags:
  --goal <text>         Quick task creation with just a goal (non-interactive)
  --task-file <path>    Use existing task.md file (non-interactive)

Commands:
  create <name>  Create task directory and task.md (does NOT start PM)
  start <name>   Start PM for existing task
  list           List all tasks
  status <name>  Show task status
  attach <name>  Attach to PM tmux session
  stop <name>    Stop task and cleanup
  cleanup <name> Reset task state (clear handoffs, scratchpad, pm_state)
  logs <name>    View handoffs and artifacts
  ui             Launch TUI dashboard
  help           Show this help

Workflow:
  1. Create task:    $0 create my-feature
  2. Edit task.md:   vi tasks/my-feature/task.md  (add agent config, refine goal)
  3. Start PM:       $0 start my-feature

Examples:
  # Interactive task creation
  $0 create my-feature

  # Non-interactive with goal (agent creates task.md)
  $0 --goal "Fix login bug" create fix-login

  # Non-interactive with existing task file
  $0 --task-file ./my-task.md create my-feature

  # Start PM for existing task
  $0 start my-feature

  # Specify project and CLI
  $0 --project /path/to/project --cli claude start my-feature
EOF
}

# Main dispatch
case "$1" in
  create)  cmd_create "$2" ;;
  start)   cmd_start "$2" ;;
  list)    cmd_list ;;
  status)  cmd_status "$2" ;;
  attach)  cmd_attach "$2" ;;
  stop)    cmd_stop "$2" ;;
  cleanup) cmd_cleanup "$2" ;;
  logs)    cmd_logs "$2" ;;
  ui)      cmd_ui ;;
  help|--help|-h) cmd_help ;;
  *)
    echo "Error: Unknown command '$1'"
    cmd_help
    exit 1
    ;;
esac
