#!/bin/bash

set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
TMP_DIR="$(mktemp -d)"
MOCK_BIN="$TMP_DIR/mockbin"
MOCK_LOG="$TMP_DIR/mock-curl.log"

cleanup() {
  rm -rf "$TMP_DIR"
}
trap cleanup EXIT

mkdir -p "$MOCK_BIN"
touch "$MOCK_LOG"

cat > "$MOCK_BIN/curl" <<'MOCK_CURL'
#!/bin/bash
set -euo pipefail

method="GET"
url=""
data=""
cookie_out=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    -X)
      method="$2"
      shift 2
      ;;
    --data|-d)
      data="$2"
      shift 2
      ;;
    -c)
      cookie_out="$2"
      shift 2
      ;;
    -b|-H|-w)
      shift 2
      ;;
    -s|-sS)
      shift
      ;;
    http://*|https://*)
      url="$1"
      shift
      ;;
    *)
      shift
      ;;
  esac
done

if [[ -n "$cookie_out" ]]; then
  mkdir -p "$(dirname "$cookie_out")"
  touch "$cookie_out"
fi

echo "${method} ${url} ${data}" >> "${MOCK_CURL_LOG:?}"

respond() {
  printf '%s\n%s\n' "$1" "$2"
}

case "${method} ${url}" in
  "GET http://localhost:3000/api/projects")
    respond '{"projects":[{"id":"p1","name":"Proj","description":"Demo","color":"#3b82f6"}]}' 200
    ;;
  "GET http://localhost:3000/api/projects/p1")
    respond '{"project":{"id":"p1","name":"Proj","description":"Demo","color":"#3b82f6"}}' 200
    ;;
  "POST http://localhost:3000/api/projects")
    respond '{"success":true,"project":{"id":"p2","name":"New Proj"}}' 200
    ;;
  "PATCH http://localhost:3000/api/projects")
    respond '{"success":true}' 200
    ;;
  "DELETE http://localhost:3000/api/projects")
    respond '{"success":true}' 200
    ;;
  "GET http://localhost:3000/api/auth/users")
    respond '{"users":[{"id":"u1","name":"Max","email":"max@example.com"}]}' 200
    ;;
  "POST http://localhost:3000/api/auth/login")
    respond '{"success":true}' 200
    ;;
  "POST http://localhost:3000/api/auth/logout")
    respond '{"success":true}' 200
    ;;
  "GET http://localhost:3000/api/auth/session")
    respond '{"authenticated":true}' 200
    ;;
  "POST http://localhost:3000/api/auth/register")
    respond '{"success":true}' 200
    ;;
  "POST http://localhost:3000/api/auth/forgot-password")
    respond '{"success":true}' 200
    ;;
  "POST http://localhost:3000/api/auth/reset-password")
    respond '{"success":true}' 200
    ;;
  "PATCH http://localhost:3000/api/auth/account")
    respond '{"success":true}' 200
    ;;
  "GET http://localhost:3000/api/sprints"|\
  "GET http://localhost:3000/api/sprints?inProgress=true")
    respond '{"sprints":[{"id":"s1","name":"Sprint 1","status":"active","startDate":"2026-02-20","endDate":"2026-03-01"}]}' 200
    ;;
  "GET http://localhost:3000/api/sprints/s1")
    respond '{"sprint":{"id":"s1","name":"Sprint 1","status":"active","startDate":"2026-02-20","endDate":"2026-03-01"}}' 200
    ;;
  "POST http://localhost:3000/api/sprints")
    respond '{"success":true,"sprint":{"id":"s2","name":"Sprint 2"}}' 200
    ;;
  "PATCH http://localhost:3000/api/sprints")
    respond '{"success":true}' 200
    ;;
  "DELETE http://localhost:3000/api/sprints")
    respond '{"success":true}' 200
    ;;
  "GET http://localhost:3000/api/sprints/current")
    respond '{"sprint":{"id":"s1","name":"Sprint 1"}}' 200
    ;;
  "POST http://localhost:3000/api/sprints/close")
    respond '{"success":true}' 200
    ;;
  "GET http://localhost:3000/api/tasks"|\
  "GET http://localhost:3000/api/tasks?scope=active-sprint")
    respond '{"tasks":[{"id":"t1","title":"Demo Task","status":"open","priority":"medium","type":"task","projectId":"p1","assigneeId":"u1","sprintId":"s1","comments":[],"tags":[],"attachments":[]}]}' 200
    ;;
  "GET http://localhost:3000/api/tasks?taskId=t1&include=detail")
    respond '{"tasks":[{"id":"t1","title":"Demo Task","status":"open","priority":"medium","type":"task","projectId":"p1","assigneeId":"u1","sprintId":"s1","comments":[],"tags":[],"attachments":[]}]}' 200
    ;;
  "POST http://localhost:3000/api/tasks")
    respond '{"success":true,"task":{"id":"t1"}}' 200
    ;;
  "DELETE http://localhost:3000/api/tasks")
    respond '{"success":true}' 200
    ;;
  "POST http://localhost:3000/api/tasks/natural")
    respond '{"success":true,"task":{"id":"t2","title":"Natural"}}' 200
    ;;
  "GET http://localhost:3000/api/debug")
    respond '{"ok":true}' 200
    ;;
  *)
    respond "{\"error\":\"Unhandled mock request: ${method} ${url}\"}" 500
    ;;
esac
MOCK_CURL

chmod +x "$MOCK_BIN/curl"

assert_log_contains() {
  local expected="$1"
  if ! grep -F "$expected" "$MOCK_LOG" >/dev/null 2>&1; then
    echo "Expected mock curl log to contain: $expected" >&2
    echo "Actual log:" >&2
    cat "$MOCK_LOG" >&2
    exit 1
  fi
}

export HOME="$TMP_DIR/home"
export PATH="$MOCK_BIN:$PATH"
export MOCK_CURL_LOG="$MOCK_LOG"
export API_URL="http://localhost:3000/api"

ATTACH_FILE="$TMP_DIR/attachment.txt"
BULK_FILE="$TMP_DIR/tasks.json"
cat > "$ATTACH_FILE" <<'ATTACH_EOF'
refactor-test
ATTACH_EOF
cat > "$BULK_FILE" <<'BULK_EOF'
[
  {
    "title": "Bulk task",
    "project": "Proj",
    "assignee": "Max",
    "sprint": "Sprint 1"
  }
]
BULK_EOF

"$ROOT_DIR/scripts/task.sh" list --json >/dev/null
task_csv_status_json=$("$ROOT_DIR/scripts/task.sh" list --status open,todo,in-progress --json)
if [[ "$(echo "$task_csv_status_json" | jq 'length')" -ne 1 ]]; then
  echo "Expected comma-separated --status filter to match task list output" >&2
  echo "$task_csv_status_json" >&2
  exit 1
fi
"$ROOT_DIR/scripts/task.sh" get t1 >/dev/null
"$ROOT_DIR/scripts/task.sh" current-sprint >/dev/null
"$ROOT_DIR/scripts/task.sh" create --title "API Task" --project "Proj" --assignee "Max" --sprint current --status todo --priority high >/dev/null
"$ROOT_DIR/scripts/task.sh" update t1 --status done --tags "api,refactor" --add-comment "done" >/dev/null
"$ROOT_DIR/scripts/task.sh" delete t1 >/dev/null
"$ROOT_DIR/scripts/task.sh" bulk-create "$BULK_FILE" >/dev/null

"$ROOT_DIR/scripts/project.sh" list --json >/dev/null
"$ROOT_DIR/scripts/project.sh" get "Proj" >/dev/null
"$ROOT_DIR/scripts/project.sh" create --name "New Proj" --description "Desc" --color "#ffffff" >/dev/null
"$ROOT_DIR/scripts/project.sh" update "Proj" --name "Renamed Proj" >/dev/null
"$ROOT_DIR/scripts/project.sh" delete "Proj" >/dev/null

"$ROOT_DIR/scripts/sprint.sh" list --json >/dev/null
"$ROOT_DIR/scripts/sprint.sh" list --active --json >/dev/null
"$ROOT_DIR/scripts/sprint.sh" get "Sprint 1" >/dev/null
"$ROOT_DIR/scripts/sprint.sh" create --name "Sprint 2" --goal "Ship" --start-date "2026-02-24" --end-date "2026-03-03" >/dev/null
"$ROOT_DIR/scripts/sprint.sh" update "Sprint 1" --goal "Updated Goal" >/dev/null
"$ROOT_DIR/scripts/sprint.sh" close "Sprint 1" >/dev/null
"$ROOT_DIR/scripts/sprint.sh" delete "Sprint 1" >/dev/null

"$ROOT_DIR/scripts/gantt.sh" task list open >/dev/null
"$ROOT_DIR/scripts/gantt.sh" task get t1 >/dev/null
"$ROOT_DIR/scripts/gantt.sh" task create "From wrapper" todo high p1 >/dev/null
"$ROOT_DIR/scripts/gantt.sh" task natural "Create natural task" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" task update t1 status done >/dev/null
"$ROOT_DIR/scripts/gantt.sh" task comment t1 "Looks good" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" task attach t1 "$ATTACH_FILE" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" task delete t1 >/dev/null

"$ROOT_DIR/scripts/gantt.sh" project list >/dev/null
"$ROOT_DIR/scripts/gantt.sh" project get p1 >/dev/null
"$ROOT_DIR/scripts/gantt.sh" project create "Wrapper Project" "Desc" "#111111" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" project update p1 name "Renamed" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" project delete p1 >/dev/null

"$ROOT_DIR/scripts/gantt.sh" sprint list >/dev/null
"$ROOT_DIR/scripts/gantt.sh" sprint get s1 >/dev/null
"$ROOT_DIR/scripts/gantt.sh" sprint create "Wrapper Sprint" "2026-02-24" "2026-03-03" "Goal" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" sprint update s1 goal "Updated Goal" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" sprint close s1 >/dev/null
"$ROOT_DIR/scripts/gantt.sh" sprint delete s1 >/dev/null

"$ROOT_DIR/scripts/gantt.sh" auth login "max@example.com" "secret" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" auth logout >/dev/null
"$ROOT_DIR/scripts/gantt.sh" auth session >/dev/null
"$ROOT_DIR/scripts/gantt.sh" auth register "new@example.com" "secret" "New User" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" auth forgot-password "new@example.com" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" auth reset-password "tok123" "newsecret" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" auth account name "Renamed User" >/dev/null
"$ROOT_DIR/scripts/gantt.sh" auth users >/dev/null
"$ROOT_DIR/scripts/gantt.sh" debug >/dev/null

if [[ ! -f "$HOME/.config/gantt-board/cookies.txt" ]]; then
  echo "Expected cookie file to be created at $HOME/.config/gantt-board/cookies.txt" >&2
  exit 1
fi

assert_log_contains "GET http://localhost:3000/api/projects"
assert_log_contains "POST http://localhost:3000/api/projects"
assert_log_contains "PATCH http://localhost:3000/api/projects"
assert_log_contains "DELETE http://localhost:3000/api/projects"
assert_log_contains "GET http://localhost:3000/api/projects/p1"

assert_log_contains "GET http://localhost:3000/api/sprints"
assert_log_contains "GET http://localhost:3000/api/sprints?inProgress=true"
assert_log_contains "GET http://localhost:3000/api/sprints/s1"
assert_log_contains "GET http://localhost:3000/api/sprints/current"
assert_log_contains "POST http://localhost:3000/api/sprints"
assert_log_contains "PATCH http://localhost:3000/api/sprints"
assert_log_contains "POST http://localhost:3000/api/sprints/close"
assert_log_contains "DELETE http://localhost:3000/api/sprints"

assert_log_contains "GET http://localhost:3000/api/tasks"
assert_log_contains "GET http://localhost:3000/api/tasks?scope=active-sprint"
assert_log_contains "GET http://localhost:3000/api/tasks?taskId=t1&include=detail"
assert_log_contains "POST http://localhost:3000/api/tasks"
assert_log_contains "DELETE http://localhost:3000/api/tasks"
assert_log_contains "POST http://localhost:3000/api/tasks/natural"

assert_log_contains "POST http://localhost:3000/api/auth/login"
assert_log_contains "POST http://localhost:3000/api/auth/logout"
assert_log_contains "GET http://localhost:3000/api/auth/session"
assert_log_contains "POST http://localhost:3000/api/auth/register"
assert_log_contains "POST http://localhost:3000/api/auth/forgot-password"
assert_log_contains "POST http://localhost:3000/api/auth/reset-password"
assert_log_contains "PATCH http://localhost:3000/api/auth/account"
assert_log_contains "GET http://localhost:3000/api/auth/users"
assert_log_contains "GET http://localhost:3000/api/debug"

if rg -n --hidden -S "rest/v1|SUPABASE_URL|SERVICE_KEY|ANON_KEY|qnatchrjlpehiijwtreh" "$ROOT_DIR/scripts" --glob "!scripts/tests/*" >/dev/null 2>&1; then
  echo "Direct Supabase references were found in scripts/" >&2
  rg -n --hidden -S "rest/v1|SUPABASE_URL|SERVICE_KEY|ANON_KEY|qnatchrjlpehiijwtreh" "$ROOT_DIR/scripts" --glob "!scripts/tests/*" >&2
  exit 1
fi

echo "CLI API passthrough tests passed"
