#!/usr/bin/env bash
# IT0 API Comprehensive Curl Test Suite
# Usage: bash scripts/api-test.sh [BASE_URL]
# Default BASE_URL: https://it0api.szaiai.com

set -uo pipefail

BASE="${1:-https://it0api.szaiai.com}"
PASS=0
FAIL=0
TOKEN=""
REFRESH_TOKEN=""
TENANT_ID=""

# ─── colors ───────────────────────────────────────────────────────────────────
GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'

ok()   { echo -e "${GREEN}[PASS]${NC} $1"; PASS=$((PASS + 1)); }
fail() { echo -e "${RED}[FAIL]${NC} $1"; FAIL=$((FAIL + 1)); }
info() { echo -e "${CYAN}[INFO]${NC} $1"; }
section() { echo -e "\n${YELLOW}══ $1 ══${NC}"; }

# ─── helpers ──────────────────────────────────────────────────────────────────
get_status() {
  curl -s -o /dev/null -w "%{http_code}" "$@"
}

post_json() {
  local url="$1"; shift
  curl -s -w "\n__STATUS__%{http_code}" -X POST \
    -H "Content-Type: application/json" \
    "$@" "$url"
}

auth_header() {
  echo "-H Authorization: Bearer ${TOKEN}"
}

# ─── Unique test values ────────────────────────────────────────────────────────
TS=$(date +%s)
TEST_EMAIL="apitest_${TS}@example.com"
TEST_PHONE="+861380${TS: -7}"
TEST_COMPANY="TestCo${TS}"
TEST_PASS="Test@12345"

# ══════════════════════════════════════════════════════════════════════════════
section "1. Health Checks"

# Kong gateway is healthy if auth routes respond (no /health route on Kong)
STATUS=$(get_status "${BASE}/api/v1/auth/profile")
[[ "$STATUS" == "401" ]] && ok "Kong gateway reachable (auth/profile returns 401 without token)" \
  || fail "Kong gateway unreachable → ${STATUS}"

# ══════════════════════════════════════════════════════════════════════════════
section "2. Auth — Register (Email)"

RESP=$(post_json "${BASE}/api/v1/auth/register" \
  -d "{\"email\":\"${TEST_EMAIL}\",\"password\":\"${TEST_PASS}\",\"name\":\"Test User\",\"companyName\":\"${TEST_COMPANY}\"}")
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
BODY=$(echo "$RESP" | sed 's/__STATUS__[0-9]*//')

if [[ "$STATUS" == "201" || "$STATUS" == "200" ]]; then
  ok "POST /api/v1/auth/register (email) → ${STATUS}"
  TOKEN=$(echo "$BODY" | grep -o '"accessToken":"[^"]*"' | cut -d'"' -f4)
  REFRESH_TOKEN=$(echo "$BODY" | grep -o '"refreshToken":"[^"]*"' | cut -d'"' -f4)
  TENANT_ID=$(echo "$BODY" | grep -o '"tenantId":"[^"]*"' | cut -d'"' -f4)
  info "Tenant: ${TENANT_ID}"
else
  fail "POST /api/v1/auth/register (email) → ${STATUS}: ${BODY}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "3. Auth — Register (Phone)"

PHONE_COMPANY="PhoneCo${TS}"
RESP=$(post_json "${BASE}/api/v1/auth/register" \
  -d "{\"phone\":\"${TEST_PHONE}\",\"password\":\"${TEST_PASS}\",\"name\":\"Phone User\",\"companyName\":\"${PHONE_COMPANY}\"}")
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
BODY=$(echo "$RESP" | sed 's/__STATUS__[0-9]*//')

if [[ "$STATUS" == "201" || "$STATUS" == "200" ]]; then
  ok "POST /api/v1/auth/register (phone) → ${STATUS}"
else
  fail "POST /api/v1/auth/register (phone) → ${STATUS}: ${BODY}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "4. Auth — Duplicate registration should fail"

# Same company name → 409 on slug conflict
RESP=$(post_json "${BASE}/api/v1/auth/register" \
  -d "{\"email\":\"dup_${TS}@example.com\",\"password\":\"${TEST_PASS}\",\"name\":\"Dup\",\"companyName\":\"${TEST_COMPANY}\"}")
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
[[ "$STATUS" == "409" ]] && ok "Duplicate company name → 409 Conflict" || fail "Duplicate company → expected 409, got ${STATUS}"

# ══════════════════════════════════════════════════════════════════════════════
section "5. Auth — Login (email)"

RESP=$(post_json "${BASE}/api/v1/auth/login" \
  -d "{\"email\":\"${TEST_EMAIL}\",\"password\":\"${TEST_PASS}\"}")
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
BODY=$(echo "$RESP" | sed 's/__STATUS__[0-9]*//')

if [[ "$STATUS" == "200" || "$STATUS" == "201" ]]; then
  ok "POST /api/v1/auth/login (email) → ${STATUS}"
  TOKEN=$(echo "$BODY" | grep -o '"accessToken":"[^"]*"' | cut -d'"' -f4)
  REFRESH_TOKEN=$(echo "$BODY" | grep -o '"refreshToken":"[^"]*"' | cut -d'"' -f4)
else
  fail "POST /api/v1/auth/login (email) → ${STATUS}: ${BODY}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "6. Auth — Login (phone)"

RESP=$(post_json "${BASE}/api/v1/auth/login" \
  -d "{\"phone\":\"${TEST_PHONE}\",\"password\":\"${TEST_PASS}\"}")
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
[[ "$STATUS" == "200" || "$STATUS" == "201" ]] && ok "POST /api/v1/auth/login (phone) → ${STATUS}" \
  || fail "POST /api/v1/auth/login (phone) → ${STATUS}"

# ══════════════════════════════════════════════════════════════════════════════
section "7. Auth — Login (identifier field)"

RESP=$(post_json "${BASE}/api/v1/auth/login" \
  -d "{\"identifier\":\"${TEST_EMAIL}\",\"password\":\"${TEST_PASS}\"}")
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
[[ "$STATUS" == "200" || "$STATUS" == "201" ]] && ok "POST /api/v1/auth/login (identifier) → ${STATUS}" \
  || fail "POST /api/v1/auth/login (identifier) → ${STATUS}"

# ══════════════════════════════════════════════════════════════════════════════
section "8. Auth — Wrong password should be 401"

RESP=$(post_json "${BASE}/api/v1/auth/login" \
  -d "{\"email\":\"${TEST_EMAIL}\",\"password\":\"wrongpass\"}")
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
[[ "$STATUS" == "401" ]] && ok "Wrong password → 401" || fail "Wrong password → expected 401, got ${STATUS}"

# ══════════════════════════════════════════════════════════════════════════════
section "9. Auth — Get profile (JWT required)"

if [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/auth/profile" \
    -H "Authorization: Bearer ${TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/auth/profile → 200" || fail "GET /api/v1/auth/profile → ${STATUS}"
else
  fail "GET /api/v1/auth/profile — no token available"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "10. Auth — Profile without token should be 401"

STATUS=$(get_status "${BASE}/api/v1/auth/profile")
[[ "$STATUS" == "401" ]] && ok "GET /api/v1/auth/profile (no token) → 401" \
  || fail "GET /api/v1/auth/profile (no token) → expected 401, got ${STATUS}"

# ══════════════════════════════════════════════════════════════════════════════
section "11. Auth — Refresh token"

if [[ -n "$REFRESH_TOKEN" ]]; then
  RESP=$(post_json "${BASE}/api/v1/auth/refresh" \
    -d "{\"refreshToken\":\"${REFRESH_TOKEN}\"}")
  STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
  [[ "$STATUS" == "200" || "$STATUS" == "201" ]] && ok "POST /api/v1/auth/refresh → ${STATUS}" \
    || fail "POST /api/v1/auth/refresh → ${STATUS}"
else
  fail "POST /api/v1/auth/refresh — no refresh token"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "12. Auth — Platform admin login (ops@it0.com)"

RESP=$(post_json "${BASE}/api/v1/auth/login" \
  -d '{"email":"ops@it0.com","password":"it0ops2024"}')
STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
BODY=$(echo "$RESP" | sed 's/__STATUS__[0-9]*//')

if [[ "$STATUS" == "200" || "$STATUS" == "201" ]]; then
  ok "Platform admin login → ${STATUS}"
  ADMIN_TOKEN=$(echo "$BODY" | grep -o '"accessToken":"[^"]*"' | cut -d'"' -f4)
  info "Admin token: ${ADMIN_TOKEN:0:40}..."
else
  fail "Platform admin login → ${STATUS}: ${BODY}"
  ADMIN_TOKEN=""
fi

# ══════════════════════════════════════════════════════════════════════════════
section "13. Tenants — List (platform admin via /api/v1/admin/tenants)"

if [[ -n "${ADMIN_TOKEN:-}" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/admin/tenants" \
    -H "Authorization: Bearer ${ADMIN_TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/admin/tenants → 200" || fail "GET /api/v1/admin/tenants → ${STATUS}"
else
  info "Skipped — no admin token"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "14. Users — List (platform admin via /api/v1/auth/users)"

if [[ -n "${ADMIN_TOKEN:-}" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/auth/users" \
    -H "Authorization: Bearer ${ADMIN_TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/auth/users → 200" || fail "GET /api/v1/auth/users → ${STATUS}"
else
  info "Skipped — no platform admin token"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "15. Billing — Plans (JWT required per Kong config)"

if [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/billing/plans" \
    -H "Authorization: Bearer ${TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/billing/plans (JWT) → 200" \
    || fail "GET /api/v1/billing/plans (JWT) → ${STATUS}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "16. Billing — Subscription (JWT required)"

if [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/billing/subscription" \
    -H "Authorization: Bearer ${TOKEN}")
  # 200 = has subscription, 404 = new tenant with no subscription yet (both acceptable)
  [[ "$STATUS" == "200" || "$STATUS" == "404" ]] \
    && ok "GET /api/v1/billing/subscription → ${STATUS} (200=active, 404=no subscription)" \
    || fail "GET /api/v1/billing/subscription → ${STATUS}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "17. Billing — Invoices (JWT required)"

if [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/billing/invoices" \
    -H "Authorization: Bearer ${TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/billing/invoices → 200" \
    || fail "GET /api/v1/billing/invoices → ${STATUS}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "18. App Version — Public check endpoint"

STATUS=$(get_status "${BASE}/api/app/version/check?platform=android&current_version_code=0")
[[ "$STATUS" == "200" ]] && ok "GET /api/app/version/check → 200" \
  || fail "GET /api/app/version/check → ${STATUS}"

RESP=$(curl -s "${BASE}/api/app/version/check?platform=android&current_version_code=0")
if echo "$RESP" | grep -q '"needUpdate"'; then
  ok "Version check response has needUpdate field"
else
  fail "Version check response missing needUpdate field: ${RESP}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "19. App Versions — Admin list (JWT required)"

if [[ -n "${ADMIN_TOKEN:-}" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/versions" \
    -H "Authorization: Bearer ${ADMIN_TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/versions → 200" || fail "GET /api/v1/versions → ${STATUS}"
elif [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/versions" \
    -H "Authorization: Bearer ${TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/versions → 200" || fail "GET /api/v1/versions → ${STATUS}"
else
  info "Skipped — no token"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "20. Inventory — Servers (JWT required)"

if [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/inventory/servers" \
    -H "Authorization: Bearer ${TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/inventory/servers → 200" || fail "GET /api/v1/inventory/servers → ${STATUS}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "21. Agent Sessions — List (JWT required)"

if [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/agent/sessions" \
    -H "Authorization: Bearer ${TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/agent/sessions → 200" \
    || fail "GET /api/v1/agent/sessions → ${STATUS}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "22. Roles — List (JWT required via /api/v1/auth/roles)"

if [[ -n "$TOKEN" ]]; then
  STATUS=$(get_status "${BASE}/api/v1/auth/roles" \
    -H "Authorization: Bearer ${TOKEN}")
  [[ "$STATUS" == "200" ]] && ok "GET /api/v1/auth/roles → 200" || fail "GET /api/v1/auth/roles → ${STATUS}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "23. API Keys — Create (JWT required)"

if [[ -n "$TOKEN" ]]; then
  RESP=$(post_json "${BASE}/api/v1/auth/api-keys" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d "{\"name\":\"test-key-${TS}\"}")
  STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
  [[ "$STATUS" == "200" || "$STATUS" == "201" ]] && ok "POST /api/v1/auth/api-keys → ${STATUS}" \
    || fail "POST /api/v1/auth/api-keys → ${STATUS}"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "24. Invite flow — Create + validate invite"

# Uses TOKEN (tenant admin, 'admin' role) to create invite for their own tenant
if [[ -n "${TOKEN:-}" && -n "${TENANT_ID:-}" ]]; then
  INVITE_EMAIL="invite_${TS}@example.com"
  RESP=$(post_json "${BASE}/api/v1/admin/tenants/${TENANT_ID}/invites" \
    -H "Authorization: Bearer ${TOKEN}" \
    -d "{\"email\":\"${INVITE_EMAIL}\",\"role\":\"viewer\"}")
  STATUS=$(echo "$RESP" | grep -o '__STATUS__[0-9]*' | sed 's/__STATUS__//')
  BODY=$(echo "$RESP" | sed 's/__STATUS__[0-9]*//')
  if [[ "$STATUS" == "200" || "$STATUS" == "201" ]]; then
    ok "POST /api/v1/admin/tenants/:id/invites → ${STATUS}"
    INVITE_TOKEN=$(echo "$BODY" | grep -o '"token":"[^"]*"' | cut -d'"' -f4)
    if [[ -n "$INVITE_TOKEN" ]]; then
      STATUS2=$(get_status "${BASE}/api/v1/auth/invite/${INVITE_TOKEN}")
      [[ "$STATUS2" == "200" ]] && ok "GET /api/v1/auth/invite/:token → 200" \
        || fail "GET /api/v1/auth/invite/:token → ${STATUS2}"
    fi
  else
    fail "POST /api/v1/admin/tenants/:id/invites → ${STATUS}: ${BODY}"
  fi
else
  info "Skipped invite flow — need token + tenantId"
fi

# ══════════════════════════════════════════════════════════════════════════════
section "Summary"

TOTAL=$((PASS + FAIL))
echo -e "\nTotal: ${TOTAL}  ${GREEN}Pass: ${PASS}${NC}  ${RED}Fail: ${FAIL}${NC}"

if [[ $FAIL -gt 0 ]]; then
  exit 1
fi
