#!/usr/bin/env bash
# Runs Phase 11 verification checks from docs/plans/phase-11-plan.md.
#
# Covers FHIR metadata, Patient/Encounter/Observation read & search,
# LOINC mapping, $everything, content-type negotiation, and 404 OperationOutcome.
#
# Prerequisites:
#   docker compose up -d          (PostgreSQL, Redis, MinIO)
#   dotnet ef database update --project VigilCareRecordsAPI
#   dotnet run --project VigilCareRecordsAPI
#   Phase 1–10 seed data (admin1)
#
# Environment overrides:
#   VIGILCARE_API_URL          default: http://localhost:5217
#   VIGILCARE_COMPOSE_FILE     default: <repo>/docker-compose.yml
#   VIGILCARE_PG_HOST          default: localhost
#   VIGILCARE_PG_PORT          default: 5437
#   VIGILCARE_PG_DB            default: vigilcare_records
#   VIGILCARE_PG_USER          default: postgres
#   VIGILCARE_PG_PASSWORD      default: password
#   VIGILCARE_SKIP_DB_CHECKS   set to 1 to skip PostgreSQL seed/assertions
#
# Usage:
#   chmod +x scripts/run-vigilcare-records-phase-11-verification.sh
#   ./scripts/run-vigilcare-records-phase-11-verification.sh

set -uo pipefail

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

API_URL="${VIGILCARE_API_URL:-http://localhost:5217}"
FHIR_URL="${API_URL}/fhir"
COMPOSE_FILE="${VIGILCARE_COMPOSE_FILE:-$REPO_ROOT/docker-compose.yml}"
COMPOSE=(docker compose -f "$COMPOSE_FILE")
PG_HOST="${VIGILCARE_PG_HOST:-localhost}"
PG_PORT="${VIGILCARE_PG_PORT:-5437}"
PG_DB="${VIGILCARE_PG_DB:-vigilcare_records}"
PG_USER="${VIGILCARE_PG_USER:-postgres}"
PG_PASSWORD="${VIGILCARE_PG_PASSWORD:-password}"
SKIP_DB_CHECKS="${VIGILCARE_SKIP_DB_CHECKS:-0}"

# Deterministic clinical IDs (match FhirClinicalSeedHelper)
PATIENT1_ID="b1000000-0000-0000-0000-000000000001"
PATIENT2_ID="b1000000-0000-0000-0000-000000000002"
ENCOUNTER1_ID="d1000000-0000-0000-0000-000000000001"
HEART_RATE_OBS_ID="e1000000-0000-0000-0000-000000000001"
WBC_OBS_ID="e1000000-0000-0000-0000-000000000002"
BATCH1_ID="c1000000-0000-0000-0000-000000000001"

ADMIN_TOKEN=""
RESOLVED_PATIENT_ID=""
RESOLVED_ENCOUNTER_ID=""
RESOLVED_HEART_RATE_OBS_ID=""

PASS_COUNT=0
FAIL_COUNT=0
FAILED_TESTS=()

log() {
  printf '%s\n' "$*"
}

section() {
  log ""
  log "== $1 =="
}

pass() {
  PASS_COUNT=$((PASS_COUNT + 1))
  log "  PASS: $1"
}

fail() {
  FAIL_COUNT=$((FAIL_COUNT + 1))
  FAILED_TESTS+=("$1")
  log "  FAIL: $1"
}

require_cmd() {
  local cmd="$1"
  if ! command -v "$cmd" >/dev/null 2>&1; then
    log "ERROR: required command not found: $cmd"
    exit 1
  fi
}

http_code() {
  curl -sS -o /dev/null -w '%{http_code}' "$@"
}

json_post() {
  local url="$1"
  local body="$2"
  curl -sS -X POST "$url" \
    -H 'Content-Type: application/json' \
    -d "$body"
}

fhir_get() {
  local path_query="$1"
  local token="${2:-}"
  if [[ -n "$token" ]]; then
    curl -sS "${FHIR_URL}${path_query}" \
      -H "Authorization: Bearer $token" \
      -H 'Accept: application/fhir+json'
  else
    curl -sS "${FHIR_URL}${path_query}" \
      -H 'Accept: application/fhir+json'
  fi
}

fhir_get_status() {
  local path_query="$1"
  local token="$2"
  local body_file http_status
  body_file="$(mktemp)"
  http_status="$(curl -sS -o "$body_file" -w '%{http_code}' \
    "${FHIR_URL}${path_query}" \
    -H "Authorization: Bearer $token" \
    -H 'Accept: application/fhir+json')"
  cat "$body_file"
  rm -f "$body_file"
  printf '\n__HTTP_STATUS__:%s' "$http_status"
}

assert_api_reachable() {
  local code
  code="$(http_code "$API_URL/swagger/index.html" || true)"
  if [[ "$code" != "200" ]]; then
    log "ERROR: API not reachable at $API_URL (HTTP $code)."
    log "Start infrastructure with: docker compose up -d"
    log "Apply migrations with: dotnet ef database update --project VigilCareRecordsAPI"
    log "Start API with: dotnet run --project VigilCareRecordsAPI"
    exit 1
  fi
}

compose_service_running() {
  local service="$1"
  "${COMPOSE[@]}" ps --status running --services 2>/dev/null | grep -qx "$service"
}

psql_available() {
  [[ "$SKIP_DB_CHECKS" == "1" ]] && return 1
  compose_service_running postgres && return 0
  command -v psql >/dev/null 2>&1 && return 0
  return 1
}

psql_query() {
  if [[ "$SKIP_DB_CHECKS" == "1" ]]; then
    return 1
  fi
  if compose_service_running postgres; then
    "${COMPOSE[@]}" exec -T postgres \
      psql -U "$PG_USER" -d "$PG_DB" -Atqc "$1"
  elif command -v psql >/dev/null 2>&1; then
    PGPASSWORD="$PG_PASSWORD" psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" -Atqc "$1"
  else
    return 1
  fi
}

psql_exec() {
  if [[ "$SKIP_DB_CHECKS" == "1" ]]; then
    return 1
  fi
  if compose_service_running postgres; then
    "${COMPOSE[@]}" exec -T postgres \
      psql -U "$PG_USER" -d "$PG_DB" -v ON_ERROR_STOP=1 -q -c "$1"
  elif command -v psql >/dev/null 2>&1; then
    PGPASSWORD="$PG_PASSWORD" psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d "$PG_DB" \
      -v ON_ERROR_STOP=1 -q -c "$1"
  else
    return 1
  fi
}

test_authentication() {
  section "0. Authentication"

  local admin_json
  admin_json="$(json_post "$API_URL/api/v1/auth/login" \
    '{"username":"admin1","password":"password"}')"

  ADMIN_TOKEN="$(jq -er '.data.token // empty' <<<"$admin_json" 2>/dev/null || true)"

  if [[ -n "$ADMIN_TOKEN" ]]; then
    pass "admin1 login returns JWT"
  else
    log "ERROR: admin1 login failed."
    log "Response: ${admin_json:-<empty>}"
    exit 1
  fi
}

verification_fixture_ready() {
  local heart_rate_count
  heart_rate_count="$(psql_query "
    SELECT count(*) FROM clinical.observations o
    JOIN clinical.patients p ON p.id = o.patient_id
    WHERE p.mrn = 'VCR-000001' AND o.observation_code = 'HEART_RATE';
  " 2>/dev/null || echo "0")"
  [[ "${heart_rate_count:-0}" -ge 1 ]]
}

seed_verification_fixture() {
  local patient_id encounter_id batch_id heart_rate_count

  patient_id="$(psql_query "SELECT id FROM clinical.patients WHERE mrn = 'VCR-000001' LIMIT 1;" 2>/dev/null || true)"

  if [[ -z "$patient_id" ]]; then
    psql_exec "
      INSERT INTO clinical.patients (
        id, mrn, full_name, date_of_birth, sex, blood_type,
        emergency_contact, allergies_json, no_known_allergies, created_at, updated_at
      ) VALUES
        ('${PATIENT1_ID}', 'VCR-000001', 'MARIA SANTOS', '1978-03-15', 'female', 'A+',
         'Juan Santos - 555-0101', '[\"Penicillin\", \"Sulfa drugs\"]', false,
         NOW() - interval '3 days', NOW() - interval '12 hours'),
        ('${PATIENT2_ID}', 'VCR-000002', 'KENJI NAKAMURA', '1952-11-08', 'male', 'O-',
         'Yuki Nakamura - 555-0202', NULL, true,
         NOW() - interval '1 day', NOW() - interval '1 day')
      ON CONFLICT (id) DO NOTHING;
    " || return 1
    patient_id="$PATIENT1_ID"
  else
    psql_exec "
      UPDATE clinical.patients SET
        full_name = 'MARIA SANTOS',
        date_of_birth = '1978-03-15',
        sex = 'female',
        blood_type = 'A+',
        emergency_contact = 'Juan Santos - 555-0101',
        allergies_json = '[\"Penicillin\", \"Sulfa drugs\"]',
        no_known_allergies = false,
        updated_at = NOW()
      WHERE id = '${patient_id}';
    " || return 1
  fi

  encounter_id="$(psql_query "
    SELECT id FROM clinical.encounters
    WHERE patient_id = '${patient_id}'
    ORDER BY created_at
    LIMIT 1;
  " 2>/dev/null || true)"

  if [[ -z "$encounter_id" ]]; then
    batch_id="$(psql_query "SELECT id FROM digitization_batches ORDER BY created_at LIMIT 1;" 2>/dev/null || true)"
    batch_id="${batch_id:-$BATCH1_ID}"
    psql_exec "
      INSERT INTO clinical.encounters (
        id, patient_id, admission_date, department, room_bed, admission_reason,
        status, source_batch_id, created_at, updated_at
      ) VALUES (
        '${ENCOUNTER1_ID}', '${patient_id}', NOW() - interval '5 days',
        'Internal Medicine', '2A-04', 'Pneumonia with elevated WBC',
        'active', '${batch_id}', NOW() - interval '3 days', NOW() - interval '12 hours'
      )
      ON CONFLICT (id) DO NOTHING;
    " || return 1
    encounter_id="$ENCOUNTER1_ID"
  fi

  batch_id="$(psql_query "
    SELECT source_batch_id FROM clinical.encounters
    WHERE id = '${encounter_id}'
    LIMIT 1;
  " 2>/dev/null || true)"
  batch_id="${batch_id:-$BATCH1_ID}"

  heart_rate_count="$(psql_query "
    SELECT count(*) FROM clinical.observations
    WHERE patient_id = '${patient_id}' AND observation_code = 'HEART_RATE';
  " 2>/dev/null || echo "0")"

  if [[ "${heart_rate_count:-0}" -lt 1 ]]; then
    psql_exec "
      INSERT INTO clinical.observations (
        id, encounter_id, patient_id, observation_code, value, unit,
        recorded_at, source, source_batch_id, created_at
      ) VALUES
        ('${HEART_RATE_OBS_ID}', '${encounter_id}', '${patient_id}',
         'HEART_RATE', 88.000, 'bpm', NOW() - interval '5 days',
         'digitization_backfill', '${batch_id}', NOW() - interval '12 hours'),
        ('${WBC_OBS_ID}', '${encounter_id}', '${patient_id}',
         'WBC_K_UL', 14.200, 'K/uL', NOW() - interval '5 days',
         'digitization_backfill', '${batch_id}', NOW() - interval '12 hours')
      ON CONFLICT (id) DO NOTHING;
    " || return 1
  fi

  return 0
}

ensure_fhir_clinical_seed() {
  section "1. Clinical seed data for FHIR endpoints"

  if ! psql_available; then
    log "  SKIP: PostgreSQL checks (set VIGILCARE_SKIP_DB_CHECKS=0 and start postgres)"
    log "  NOTE: FHIR curl tests require clinical.patients with MRN VCR-000001"
    log "        Promote a batch or run with postgres available to auto-seed."
    return
  fi

  if verification_fixture_ready; then
    pass "FHIR verification fixture (VCR-000001 + HEART_RATE) already present"
    return
  fi

  log "  Ensuring FHIR verification fixture for VCR-000001..."

  if seed_verification_fixture; then
    if verification_fixture_ready; then
      pass "FHIR verification fixture ready for VCR-000001"
    else
      fail "FHIR verification fixture ready for VCR-000001"
    fi
  else
    fail "seed FHIR verification fixture for VCR-000001"
  fi
}

test_fhir_metadata() {
  section "2. FHIR metadata — GET /fhir/metadata"

  local metadata types
  metadata="$(fhir_get '/metadata')"
  types="$(jq -r '.rest[0].resource[].type' <<<"$metadata" 2>/dev/null | sort | tr '\n' ' ')"

  if jq -e '.resourceType == "CapabilityStatement"' <<<"$metadata" >/dev/null 2>&1; then
    pass "metadata returns CapabilityStatement"
  else
    fail "metadata returns CapabilityStatement"
  fi

  if grep -q 'Patient' <<<"$types" && grep -q 'Encounter' <<<"$types" && grep -q 'Observation' <<<"$types"; then
    pass "metadata lists Patient, Encounter, Observation resources"
  else
    fail "metadata lists Patient, Encounter, Observation resources (got: $types)"
  fi
}

resolve_clinical_ids() {
  section "3. Resolve FHIR clinical resource IDs"

  local search_json encounter_search obs_search

  if psql_available; then
    RESOLVED_PATIENT_ID="$(psql_query "
      SELECT id FROM clinical.patients WHERE mrn = 'VCR-000001' LIMIT 1;
    " 2>/dev/null || true)"
    if [[ -n "$RESOLVED_PATIENT_ID" ]]; then
      RESOLVED_ENCOUNTER_ID="$(psql_query "
        SELECT id FROM clinical.encounters
        WHERE patient_id = '${RESOLVED_PATIENT_ID}'
        ORDER BY created_at
        LIMIT 1;
      " 2>/dev/null || true)"
      RESOLVED_HEART_RATE_OBS_ID="$(psql_query "
        SELECT id FROM clinical.observations
        WHERE patient_id = '${RESOLVED_PATIENT_ID}'
          AND observation_code = 'HEART_RATE'
        ORDER BY recorded_at DESC
        LIMIT 1;
      " 2>/dev/null || true)"
    fi
  fi

  if [[ -z "$RESOLVED_PATIENT_ID" ]]; then
    search_json="$(fhir_get "/Patient?identifier=VCR-000001" "$ADMIN_TOKEN")"
    RESOLVED_PATIENT_ID="$(jq -er '.entry[0].resource.id // empty' <<<"$search_json" 2>/dev/null || true)"
  fi

  if [[ -z "$RESOLVED_PATIENT_ID" ]]; then
    search_json="$(fhir_get "/Patient?name=Santos" "$ADMIN_TOKEN")"
    RESOLVED_PATIENT_ID="$(jq -er '.entry[0].resource.id // empty' <<<"$search_json" 2>/dev/null || true)"
  fi

  if [[ -z "$RESOLVED_ENCOUNTER_ID" && -n "$RESOLVED_PATIENT_ID" ]]; then
    encounter_search="$(fhir_get "/Encounter?patient=${RESOLVED_PATIENT_ID}" "$ADMIN_TOKEN")"
    RESOLVED_ENCOUNTER_ID="$(jq -er '.entry[0].resource.id // empty' <<<"$encounter_search" 2>/dev/null || true)"
  fi

  if [[ -z "$RESOLVED_HEART_RATE_OBS_ID" && -n "$RESOLVED_PATIENT_ID" ]]; then
    obs_search="$(fhir_get "/Observation?patient=${RESOLVED_PATIENT_ID}&code=8867-4" "$ADMIN_TOKEN")"
    RESOLVED_HEART_RATE_OBS_ID="$(jq -er '.entry[0].resource.id // empty' <<<"$obs_search" 2>/dev/null || true)"
  fi

  if [[ -n "$RESOLVED_PATIENT_ID" ]]; then
    pass "resolved patient ID ($RESOLVED_PATIENT_ID)"
  else
    fail "resolved patient ID"
  fi

  if [[ -n "$RESOLVED_ENCOUNTER_ID" ]]; then
    pass "resolved encounter ID ($RESOLVED_ENCOUNTER_ID)"
  else
    fail "resolved encounter ID"
  fi

  if [[ -n "$RESOLVED_HEART_RATE_OBS_ID" ]]; then
    pass "resolved HEART_RATE observation ID ($RESOLVED_HEART_RATE_OBS_ID)"
  else
    fail "resolved HEART_RATE observation ID"
  fi
}

test_fhir_patient_read() {
  section "4. FHIR Patient read & search"

  local patient_json mrn gender birth_date identifier_json
  patient_json="$(fhir_get "/Patient/${RESOLVED_PATIENT_ID}" "$ADMIN_TOKEN")"

  if jq -e '.resourceType == "Patient"' <<<"$patient_json" >/dev/null 2>&1; then
    pass "GET /fhir/Patient/{id} returns Patient resource"
  else
    fail "GET /fhir/Patient/{id} returns Patient resource"
  fi

  mrn="$(jq -er '.identifier[0].value // empty' <<<"$patient_json" 2>/dev/null || true)"
  if [[ "$mrn" == "VCR-000001" ]]; then
    pass "Patient read includes MRN identifier VCR-000001"
  else
    fail "Patient read includes MRN identifier VCR-000001 (got: ${mrn:-<empty>})"
  fi

  gender="$(jq -er '.gender // empty' <<<"$patient_json" 2>/dev/null || true)"
  birth_date="$(jq -er '.birthDate // empty' <<<"$patient_json" 2>/dev/null || true)"
  if [[ "$gender" == "female" && "$birth_date" == "1978-03-15" ]]; then
    pass "Patient read includes gender and birthDate"
  else
    fail "Patient read includes gender and birthDate (gender=$gender birthDate=$birth_date)"
  fi

  identifier_json="$(fhir_get "/Patient?identifier=VCR-000001" "$ADMIN_TOKEN")"
  if [[ "$(jq -er '.total // 0' <<<"$identifier_json")" -ge 1 ]]; then
    pass "GET /fhir/Patient?identifier=VCR-000001 returns matches"
  else
    fail "GET /fhir/Patient?identifier=VCR-000001 returns matches"
  fi
}

test_fhir_encounter() {
  section "5. FHIR Encounter read & search"

  local encounter_json status subject patient_search
  encounter_json="$(fhir_get "/Encounter/${RESOLVED_ENCOUNTER_ID}" "$ADMIN_TOKEN")"

  if jq -e '.resourceType == "Encounter"' <<<"$encounter_json" >/dev/null 2>&1; then
    pass "GET /fhir/Encounter/{id} returns Encounter resource"
  else
    fail "GET /fhir/Encounter/{id} returns Encounter resource"
  fi

  status="$(jq -er '.status // empty' <<<"$encounter_json" 2>/dev/null || true)"
  subject="$(jq -er '.subject.reference // empty' <<<"$encounter_json" 2>/dev/null || true)"
  if [[ "$status" == "in-progress" && "$subject" == "Patient/${RESOLVED_PATIENT_ID}" ]]; then
    pass "Encounter read has in-progress status and patient reference"
  else
    fail "Encounter read has in-progress status and patient reference"
  fi

  patient_search="$(fhir_get "/Encounter?patient=${RESOLVED_PATIENT_ID}" "$ADMIN_TOKEN")"
  if [[ "$(jq -er '.total // 0' <<<"$patient_search")" -ge 1 ]]; then
    pass "GET /fhir/Encounter?patient={id} returns matches"
  else
    fail "GET /fhir/Encounter?patient={id} returns matches"
  fi
}

test_fhir_observation() {
  section "6. FHIR Observation read, LOINC search, category & date"

  local obs_json loinc_code loinc_unit loinc_search category_search date_search date_filter
  obs_json="$(fhir_get "/Observation/${RESOLVED_HEART_RATE_OBS_ID}" "$ADMIN_TOKEN")"

  if jq -e '.resourceType == "Observation"' <<<"$obs_json" >/dev/null 2>&1; then
    pass "GET /fhir/Observation/{id} returns Observation resource"
  else
    fail "GET /fhir/Observation/{id} returns Observation resource"
  fi

  loinc_code="$(jq -er '.code.coding[0].code // empty' <<<"$obs_json" 2>/dev/null || true)"
  loinc_unit="$(jq -er '.valueQuantity.unit // empty' <<<"$obs_json" 2>/dev/null || true)"
  if [[ "$loinc_code" == "8867-4" && "$loinc_unit" == "bpm" ]] \
    && jq -e '.valueQuantity.value == 88' <<<"$obs_json" >/dev/null 2>&1; then
    pass "Observation read maps HEART_RATE to LOINC 8867-4 with value 88 bpm"
  else
    fail "Observation read maps HEART_RATE to LOINC 8867-4 with value 88 bpm"
  fi

  loinc_search="$(fhir_get "/Observation?patient=${RESOLVED_PATIENT_ID}&code=8867-4" "$ADMIN_TOKEN")"
  if [[ "$(jq -er '.entry | length' <<<"$loinc_search" 2>/dev/null || echo 0)" -ge 1 ]]; then
    pass "GET /fhir/Observation?code=8867-4 resolves LOINC to HEART_RATE"
  else
    fail "GET /fhir/Observation?code=8867-4 resolves LOINC to HEART_RATE"
  fi

  category_search="$(fhir_get "/Observation?patient=${RESOLVED_PATIENT_ID}&category=vital-signs" "$ADMIN_TOKEN")"
  if [[ "$(jq -er '.entry | length' <<<"$category_search" 2>/dev/null || echo 0)" -ge 1 ]]; then
    pass "GET /fhir/Observation?category=vital-signs returns vital sign observations"
  else
    fail "GET /fhir/Observation?category=vital-signs returns vital sign observations"
  fi

  date_filter="$(jq -er '.effectiveDateTime // empty' <<<"$obs_json" 2>/dev/null | cut -c1-10 || true)"
  if [[ -n "$date_filter" ]]; then
    date_filter="$(date -d "${date_filter} - 1 day" +%Y-%m-%d 2>/dev/null || echo "2026-06-20")"
  else
    date_filter="2026-06-20"
  fi

  date_search="$(fhir_get "/Observation?patient=${RESOLVED_PATIENT_ID}&date=ge${date_filter}" "$ADMIN_TOKEN")"
  if [[ "$(jq -er '.total // 0' <<<"$date_search" 2>/dev/null || echo 0)" -ge 1 ]]; then
    pass "GET /fhir/Observation?date=ge${date_filter} filters by recordedAt"
  else
    fail "GET /fhir/Observation?date=ge${date_filter} filters by recordedAt"
  fi
}

test_fhir_patient_everything() {
  section "7. FHIR Patient \$everything"

  local bundle_json total resource_types has_patient has_encounter has_observation
  bundle_json="$(fhir_get "/Patient/${RESOLVED_PATIENT_ID}/\$everything" "$ADMIN_TOKEN")"

  total="$(jq -er '.total // 0' <<<"$bundle_json" 2>/dev/null || echo 0)"
  resource_types="$(jq -r '[.entry[]?.resource.resourceType] | join(",")' <<<"$bundle_json" 2>/dev/null || true)"

  if [[ "$total" -gt 0 ]]; then
    pass "GET /fhir/Patient/{id}/\$everything returns non-empty Bundle"
  else
    fail "GET /fhir/Patient/{id}/\$everything returns non-empty Bundle"
  fi

  has_patient="$(grep -c 'Patient' <<<"$resource_types" || true)"
  has_encounter="$(grep -c 'Encounter' <<<"$resource_types" || true)"
  has_observation="$(grep -c 'Observation' <<<"$resource_types" || true)"

  if [[ "$has_patient" -ge 1 && "$has_encounter" -ge 1 && "$has_observation" -ge 1 ]]; then
    pass "\$everything Bundle contains Patient, Encounter, and Observation"
  else
    fail "\$everything Bundle contains Patient, Encounter, and Observation (types: $resource_types)"
  fi
}

test_fhir_content_type() {
  section "8. Content-Type negotiation"

  local content_type
  content_type="$(curl -sS -o /dev/null -w '%{content_type}' \
    "${FHIR_URL}/Patient/${RESOLVED_PATIENT_ID}" \
    -H "Authorization: Bearer $ADMIN_TOKEN" \
    -H 'Accept: application/fhir+json')"

  if [[ "$content_type" == application/fhir+json* ]]; then
    pass "Patient read Content-Type is application/fhir+json"
  else
    fail "Patient read Content-Type is application/fhir+json (got: $content_type)"
  fi
}

test_fhir_error_handling() {
  section "9. FHIR error handling — 404 OperationOutcome"

  local response http_status issue_code issue_severity
  response="$(fhir_get_status "/Patient/00000000-0000-0000-0000-000000000000" "$ADMIN_TOKEN")"
  http_status="${response##*__HTTP_STATUS__:}"
  response="${response%__HTTP_STATUS__:*}"

  issue_code="$(jq -er '.issue[0].code // empty' <<<"$response" 2>/dev/null || true)"
  issue_severity="$(jq -er '.issue[0].severity // empty' <<<"$response" 2>/dev/null || true)"

  if [[ "$http_status" == "404" ]]; then
    pass "unknown Patient returns HTTP 404"
  else
    fail "unknown Patient returns HTTP 404 (got HTTP $http_status)"
  fi

  if [[ "$issue_code" == "not-found" && "$issue_severity" == "error" ]]; then
    pass "404 response is OperationOutcome with not-found issue"
  else
    fail "404 response is OperationOutcome with not-found issue"
  fi
}

test_bundle_pagination() {
  section "10. Bundle pagination links"

  local bundle_json
  bundle_json="$(fhir_get "/Patient?_count=1&_offset=0" "$ADMIN_TOKEN")"

  if [[ "$(jq -er '.total // 0' <<<"$bundle_json")" -ge 2 ]]; then
    pass "Patient search total >= 2 for pagination test"
  else
    fail "Patient search total >= 2 for pagination test"
    return
  fi

  if jq -e '.link[] | select(.relation == "self")' <<<"$bundle_json" >/dev/null 2>&1; then
    pass "search Bundle includes self link"
  else
    fail "search Bundle includes self link"
  fi

  if jq -e '.link[] | select(.relation == "next")' <<<"$bundle_json" >/dev/null 2>&1; then
    pass "search Bundle includes next link"
  else
    fail "search Bundle includes next link"
  fi
}

print_manual_ui_checklist() {
  section "11. Manual Vue UI checks (plan §7)"
  log "  Login as admin1 → http://localhost:3028/fhir-explorer"
  log "    - Select Patient resource type; search by name Santos"
  log "    - Results table shows matching patients"
  log "    - Click a row to see full FHIR JSON"
  log "    - Patient \$everything: select patient, Load All Data"
  log "    - Grouped Patient summary, Encounters list, Observations timeline"
  log "    - Open CapabilityStatement link opens metadata JSON in new tab"
}

main() {
  require_cmd curl
  require_cmd jq

  log "VigilCare Records — Phase 11 verification"
  log "API: $API_URL"
  log "FHIR: $FHIR_URL"

  assert_api_reachable

  test_authentication
  ensure_fhir_clinical_seed
  test_fhir_metadata
  resolve_clinical_ids
  test_fhir_patient_read
  test_fhir_encounter
  test_fhir_observation
  test_fhir_patient_everything
  test_fhir_content_type
  test_fhir_error_handling
  test_bundle_pagination
  print_manual_ui_checklist

  log ""
  log "Results: $PASS_COUNT passed, $FAIL_COUNT failed"
  if (( FAIL_COUNT > 0 )); then
    log "Failed checks:"
    for item in "${FAILED_TESTS[@]}"; do
      log "  - $item"
    done
    exit 1
  fi

  log "All Phase 11 API verification checks passed."
  log "Complete the manual Vue FHIR Explorer checklist above if not already done."
}

main "$@"
