#!/usr/bin/env bash

wait_for_workspace_curated_entry() {
  local event_kind="$1"
  local expected="$2"
  local message="$3"
  local retries="${4:-40}"
  local sleep_seconds="${5:-2}"
  local count

  while (( retries > 0 )); do
    request_json "workspace-curated-timeline-${event_kind}" "GET" "/api/v1/ticketmanager/workspace/workspaces/${WORKSPACE_ID}/curated-timeline"
    expect_status "200"
    count="$(jq --arg event_kind "${event_kind}" '[.entries[] | select(.event_kind == $event_kind)] | length' "$LAST_BODY_FILE")"
    if (( count >= expected )); then
      return 0
    fi
    sleep "${sleep_seconds}"
    retries=$((retries - 1))
  done

  fail "${message}; last curated timeline response: $(cat "$LAST_BODY_FILE")"
}

insert_workspace_fixture() {
  WORKSPACE_NAME="ws-timeline-e2e-${RANDOM}${RANDOM}"
  WORKSPACE_OWNER="workspace-timeline-e2e@example.com"

  sql_scalar "INSERT INTO workspace_workspaces (name, description, owner, status, task_list_id, started_at, created_at, updated_at) VALUES ('${WORKSPACE_NAME}', 'workspace timeline e2e', '${WORKSPACE_OWNER}', 'active', ${TASK_LIST_ID}, NOW(3), NOW(3), NOW(3));"
  WORKSPACE_ID="$(sql_scalar "SELECT id FROM workspace_workspaces WHERE name = '${WORKSPACE_NAME}' ORDER BY id DESC LIMIT 1;")"
  assert_non_empty "${WORKSPACE_ID}" "expected workspace fixture id"
}

run_workspace_timeline_case() {
  TASK_LIST_NAME="timeline-e2e-list-${RANDOM}${RANDOM}"
  TASK_OWNER="workspace-timeline-e2e@example.com"

  request_json "create-task-list" "POST" "/api/v1/ticketmanager/task/lists" "$(jq -n \
    --arg name "${TASK_LIST_NAME}" \
    --arg owner "${TASK_OWNER}" \
    '{name: $name, owner: $owner}')"
  expect_status "200"
  TASK_LIST_ID="$(jq -r '.task_list.id' "$LAST_BODY_FILE")"
  assert_non_empty "${TASK_LIST_ID}" "expected task list id"

  insert_workspace_fixture

  request_json "create-workspace-task" "POST" "/api/v1/ticketmanager/task/tasks" "$(jq -n \
    --arg title "Validate workspace timeline recovery" \
    --arg description "created by workspace timeline e2e" \
    --arg creator "${TASK_OWNER}" \
    --argjson taskListID "${TASK_LIST_ID}" \
    '{
      title: $title,
      description: $description,
      priority: "p1",
      creator: $creator,
      task_list_id: $taskListID,
      members: [
        {MemberEmail: $creator, Role: "assignee"}
      ]
    }')"
  expect_status "200"
  TASK_ID="$(jq -r '.task.id' "$LAST_BODY_FILE")"
  assert_non_empty "${TASK_ID}" "expected task id"

  request_json "complete-workspace-task" "POST" "/api/v1/ticketmanager/task/tasks/${TASK_ID}/complete"
  expect_status "200"

  request_json "manual-workspace-timeline-sync" "POST" "/api/v1/ticketmanager/workspace/workspaces/${WORKSPACE_ID}/timeline-sync"
  expect_status "200"

  wait_for_workspace_curated_entry \
    "task_update" \
    "1" \
    "expected completed task to create a curated timeline draft"

  sleep 4
  request_json "workspace-curated-timeline-dedup-check" "GET" "/api/v1/ticketmanager/workspace/workspaces/${WORKSPACE_ID}/curated-timeline"
  expect_status "200"
  TASK_UPDATE_COUNT="$(jq --arg event_kind "task_update" '[.entries[] | select(.event_kind == $event_kind)] | length' "$LAST_BODY_FILE")"
  assert_eq "${TASK_UPDATE_COUNT}" "1" "expected workspace curated timeline entry to be deduplicated"

  if [[ "${E2E_FAKE_AGENT_GATEWAY}" == "1" ]]; then
    GATEWAY_ENTRY_COUNT="$(jq '[.entries[] | select(.title == "Gateway fixture: workspace task updated")] | length' "$LAST_BODY_FILE")"
    assert_eq "${GATEWAY_ENTRY_COUNT}" "1" "expected the Gateway result, not a rule fallback"
  fi

  CURATED_ENTRY_ID="$(jq -r --arg event_kind "task_update" '.entries[] | select(.event_kind == $event_kind) | .id' "$LAST_BODY_FILE" | head -n 1)"
  CURATED_ENTRY_VERSION="$(jq -r --argjson id "${CURATED_ENTRY_ID}" '.entries[] | select(.id == $id) | .version' "$LAST_BODY_FILE")"
  assert_non_empty "${CURATED_ENTRY_ID}" "expected curated timeline entry id"
  assert_non_empty "${CURATED_ENTRY_VERSION}" "expected curated timeline entry version"

  CURATED_DRAFT_COUNT="$(jq --arg event_kind "task_update" '[.entries[] | select(.event_kind == $event_kind and .status == "draft" and .source == "ai")] | length' "$LAST_BODY_FILE")"
  assert_ge "${CURATED_DRAFT_COUNT}" "1" "expected task_update curated entry to start as an AI draft"

  request_json "workspace-timeline-evidence-task" "GET" "/api/v1/ticketmanager/workspace/workspaces/${WORKSPACE_ID}/timeline-evidence?source=task&bound=true&actor=${TASK_OWNER}"
  expect_status "200"
  TASK_EVIDENCE_COUNT="$(jq '[.evidence[] | select(.source == "task" and .source_type == "task_update")] | length' "$LAST_BODY_FILE")"
  assert_ge "${TASK_EVIDENCE_COUNT}" "1" "expected task evidence to be persisted and bound"

  request_json "confirm-workspace-curated-timeline-entry" "POST" "/api/v1/ticketmanager/workspace/curated-timeline/${CURATED_ENTRY_ID}/confirm?updated_by=workspace-timeline-e2e@example.com"
  expect_status "200"
  CURATED_ENTRY_VERSION="$(jq -r '.entry.version' "$LAST_BODY_FILE")"
  CURATED_ENTRY_STATUS="$(jq -r '.entry.status' "$LAST_BODY_FILE")"
  assert_eq "${CURATED_ENTRY_STATUS}" "confirmed" "expected curated timeline entry to be confirmed"

  UPDATED_TITLE="Validated workspace timeline recovery"
  request_json "edit-workspace-curated-timeline-entry" "PATCH" "/api/v1/ticketmanager/workspace/curated-timeline/${CURATED_ENTRY_ID}" "$(jq -n \
    --arg title "${UPDATED_TITLE}" \
    --arg updatedBy "workspace-timeline-e2e@example.com" \
    --argjson version "${CURATED_ENTRY_VERSION}" \
    '{
      title: $title,
      updated_by: $updatedBy,
      version: $version
    }')"
  expect_status "200"
  CURATED_ENTRY_VERSION="$(jq -r '.entry.version' "$LAST_BODY_FILE")"
  CURATED_ENTRY_TITLE="$(jq -r '.entry.title' "$LAST_BODY_FILE")"
  assert_eq "${CURATED_ENTRY_TITLE}" "${UPDATED_TITLE}" "expected curated timeline entry edit to persist"

  request_json "hide-workspace-curated-timeline-entry" "POST" "/api/v1/ticketmanager/workspace/curated-timeline/${CURATED_ENTRY_ID}/hide?updated_by=workspace-timeline-e2e@example.com"
  expect_status "200"
  CURATED_ENTRY_STATUS="$(jq -r '.entry.status' "$LAST_BODY_FILE")"
  assert_eq "${CURATED_ENTRY_STATUS}" "hidden" "expected curated timeline entry to be hidden"

  request_json "workspace-curated-timeline-hidden-suppressed" "GET" "/api/v1/ticketmanager/workspace/workspaces/${WORKSPACE_ID}/curated-timeline"
  expect_status "200"
  VISIBLE_HIDDEN_COUNT="$(jq --argjson id "${CURATED_ENTRY_ID}" '[.entries[] | select(.id == $id)] | length' "$LAST_BODY_FILE")"
  assert_eq "${VISIBLE_HIDDEN_COUNT}" "0" "expected hidden curated timeline entry to be omitted by default"

  request_json "workspace-curated-timeline-include-hidden" "GET" "/api/v1/ticketmanager/workspace/workspaces/${WORKSPACE_ID}/curated-timeline?include_hidden=true"
  expect_status "200"
  INCLUDED_HIDDEN_COUNT="$(jq --argjson id "${CURATED_ENTRY_ID}" '[.entries[] | select(.id == $id and .status == "hidden")] | length' "$LAST_BODY_FILE")"
  assert_eq "${INCLUDED_HIDDEN_COUNT}" "1" "expected include_hidden to return hidden curated timeline entry"

  DB_EVIDENCE_COUNT="$(sql_scalar "SELECT COUNT(*) FROM workspace_timeline_evidence WHERE workspace_id = ${WORKSPACE_ID} AND source = 'task' AND source_type = 'task_update';")"
  assert_eq "${DB_EVIDENCE_COUNT}" "1" "expected one persisted workspace_timeline_evidence row"

  DB_ENTRY_COUNT="$(sql_scalar "SELECT COUNT(*) FROM workspace_timeline_entries WHERE workspace_id = ${WORKSPACE_ID} AND event_kind = 'task_update';")"
  assert_eq "${DB_ENTRY_COUNT}" "1" "expected one persisted workspace_timeline_entries row"

  DB_ENTRY_EVIDENCE_COUNT="$(sql_scalar "SELECT COUNT(*) FROM workspace_timeline_entry_evidence WHERE workspace_id = ${WORKSPACE_ID};")"
  assert_ge "${DB_ENTRY_EVIDENCE_COUNT}" "1" "expected persisted workspace_timeline_entry_evidence row"

  DB_SYNC_STATE_COUNT="$(sql_scalar "SELECT COUNT(*) FROM workspace_timeline_sync_states WHERE workspace_id = ${WORKSPACE_ID} AND source = 'task' AND source_type = 'task_update';")"
  assert_ge "${DB_SYNC_STATE_COUNT}" "1" "expected workspace_timeline_sync_states row for task evidence"

  DB_REVISION_COUNT="$(sql_scalar "SELECT COUNT(*) FROM workspace_timeline_entry_revisions WHERE workspace_id = ${WORKSPACE_ID} AND entry_id = ${CURATED_ENTRY_ID};")"
  assert_ge "${DB_REVISION_COUNT}" "3" "expected revision rows for confirm/edit/hide"

  log "workspace timeline case passed for workspace ${WORKSPACE_ID}, task ${TASK_ID}"
}
