#!/usr/bin/env bash
#
# =============================================================================
# COMPLETE ONBOARDING WORKFLOW (narrative)
# =============================================================================
#
# 1) Authenticate as Super Admin — platform setup (orgs, admins, assignments).
# 2) Create Organization — tenant boundary for teams, cycles, and role config.
# 3) Roles — use existing app roles (seeded: "Team Leader", "Sales Agent", "Admin", …)
#    or create custom roles via POST /roles. Assign roles to the org so they can be
#    used in that tenant context (role-organization-assignments).
# 4) Team role config — for each team level (1 = top-level, 2 = child, …), define which
#    app_roles may be leaders/members (enforced when verify_team_role_config is on).
# 5) Create Admin users (sales agents / future team leads) — POST /admins (Super Admin).
# 6) Assign admins to the organization — POST /admin-organization-assignments.
# 7) Authenticate as an Admin — day-to-day operations (teams, members, cycles).
# 8) Create Teams — POST /teams (organization_id, name, optional parent_team_id).
#    Hierarchy closure (team_hierarchy) rebuilds on team save/delete.
# 9) Add Team members — POST /team-members (team_id, user_id, role_id, is_team_leader).
#    Optional: skip_role_config_check=true to bypass config checks.
# 10) Monthly cycle — POST /monthly-cycles (cycle_month = first day of month).
# 11) Plan roster — POST /monthly-cycles/{id}/roster/bulk-upsert (draft entries).
# 12) Approve roster lines — POST .../roster/bulk-approve (permission: approve monthly cycles).
# 13) Optional governance — POST .../submit → POST .../approve-cycle if
#     ONBOARDING_REQUIRE_CYCLE_APPROVAL=true in .env / config/onboarding.php.
# 14) Review change vs last month — GET .../diff?compare=roster|snapshot.
# 15) Apply roster to live team_members — POST .../apply-roster
#     (validates all rows, then one DB transaction). Use snapshot_after=true to refresh
#     team_member_cycles in the same step.
# 16) Activate cycle — POST .../activate (optional: closes other active cycles in org).
# 17) Later — POST .../close when the month is done.
# 18) Ad-hoc snapshot — POST .../snapshot or POST /team-member-cycles/snapshot.
#
# API base: Laravel serves routes under /api — full path /api/v1/...
#
# Prerequisites: curl, jq. Super Admin + seeded permissions (php artisan db:seed).
#
# Usage:
#   export BASE_URL="http://127.0.0.1:8000/api/v1"
#   export SUPER_EMAIL="superadmin@example.com"
#   export SUPER_PASSWORD="password123"
#   ./scripts/onboarding-workflow-curl.sh
#
# =============================================================================

set -euo pipefail

BASE_URL="${BASE_URL:-http://127.0.0.1:8000/api/v1}"
SUPER_EMAIL="${SUPER_EMAIL:-superadmin@example.com}"
SUPER_PASSWORD="${SUPER_PASSWORD:-password123}"

TS="$(date +%s)"
ORG_NAME="${ORG_NAME:-Onboarding Demo Org ${TS}}"
LEAD_EMAIL="${LEAD_EMAIL:-onboard-lead-${TS}@example.com}"
AGENT_EMAIL="${AGENT_EMAIL:-onboard-agent-${TS}@example.com}"
ADMIN_PASSWORD="${ADMIN_PASSWORD:-Password123!}"

if ! command -v jq &>/dev/null; then
  echo "jq is required (brew install jq)" >&2
  exit 1
fi

echo "==> 1) Super Admin login"
SUPER_RESP="$(curl -sS -X POST "${BASE_URL}/superadmin/login" \
  -H "Content-Type: application/json" \
  -d "{\"email\":\"${SUPER_EMAIL}\",\"password\":\"${SUPER_PASSWORD}\"}")"
SUPER_TOKEN="$(echo "$SUPER_RESP" | jq -r '.access_token // empty')"
if [[ -z "$SUPER_TOKEN" || "$SUPER_TOKEN" == "null" ]]; then
  echo "$SUPER_RESP" | jq . >&2
  exit 1
fi
echo "    SUPER_TOKEN obtained (${#SUPER_TOKEN} chars)"

echo "==> 2) Create organization"
ORG_RESP="$(curl -sS -X POST "${BASE_URL}/organizations" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"org_name\":\"${ORG_NAME}\",\"onboarding_date\":\"$(date -Iseconds)\",\"is_active\":true}")"
ORG_ID="$(echo "$ORG_RESP" | jq -r '.data.id // empty')"
if [[ -z "$ORG_ID" || "$ORG_ID" == "null" ]]; then
  echo "$ORG_RESP" | jq . >&2
  exit 1
fi
echo "    ORG_ID=${ORG_ID}"

echo "==> 3) Resolve Team Leader + Sales Agent role IDs (seeded roles)"
ROLES_JSON="$(curl -sS "${BASE_URL}/roles/active" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Accept: application/json")"
# Pure jq (no `head`): avoids PATH shadowing where `head` is not /usr/bin/head (e.g. curl HEAD helper).
ROLE_TL_ID="$(echo "$ROLES_JSON" | jq -r '(.data // []) | map(select(.roleName=="Team Leader")) | .[0] // empty | .id')"
ROLE_SA_ID="$(echo "$ROLES_JSON" | jq -r '(.data // []) | map(select(.roleName=="Sales Agent")) | .[0] // empty | .id')"
if [[ -z "$ROLE_TL_ID" || "$ROLE_TL_ID" == "null" ]]; then
  echo "$ROLES_JSON" | jq . >&2
  echo "Team Leader role not found. Run: php artisan db:seed --class=PermissionSeeder" >&2
  exit 1
fi
if [[ -z "$ROLE_SA_ID" || "$ROLE_SA_ID" == "null" ]]; then
  echo "$ROLES_JSON" | jq . >&2
  echo "Sales Agent role not found." >&2
  exit 1
fi
echo "    ROLE_TL_ID=${ROLE_TL_ID}"
echo "    ROLE_SA_ID=${ROLE_SA_ID}"

echo "==> 4) Assign roles to organization (role-organization-assignments)"
curl -sS -X POST "${BASE_URL}/role-organization-assignments" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"role_id\":\"${ROLE_TL_ID}\",\"organization_id\":\"${ORG_ID}\",\"is_active\":true}" | jq .
curl -sS -X POST "${BASE_URL}/role-organization-assignments" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"role_id\":\"${ROLE_SA_ID}\",\"organization_id\":\"${ORG_ID}\",\"is_active\":true}" | jq .

echo "==> 5) Team role config (level 1 = top-level teams)"
curl -sS -X POST "${BASE_URL}/team-role-configs" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"organization_id\":\"${ORG_ID}\",\"team_level\":1,\"role_id\":\"${ROLE_TL_ID}\",\"can_be_leader\":true,\"can_be_member\":true}" | jq .
curl -sS -X POST "${BASE_URL}/team-role-configs" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"organization_id\":\"${ORG_ID}\",\"team_level\":1,\"role_id\":\"${ROLE_SA_ID}\",\"can_be_leader\":false,\"can_be_member\":true}" | jq .

echo "==> 6) Create two admins (team lead + sales agent)"
LEAD_RESP="$(curl -sS -X POST "${BASE_URL}/admins" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"first_name\":\"Lead\",\"last_name\":\"${TS}\",\"email\":\"${LEAD_EMAIL}\",\"password\":\"${ADMIN_PASSWORD}\",\"is_active\":true}")"
AGENT_RESP="$(curl -sS -X POST "${BASE_URL}/admins" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"first_name\":\"Agent\",\"last_name\":\"${TS}\",\"email\":\"${AGENT_EMAIL}\",\"password\":\"${ADMIN_PASSWORD}\",\"is_active\":true}")"
LEAD_ADMIN_ID="$(echo "$LEAD_RESP" | jq -r '.data.id // empty')"
AGENT_ADMIN_ID="$(echo "$AGENT_RESP" | jq -r '.data.id // empty')"
echo "    LEAD_ADMIN_ID=${LEAD_ADMIN_ID}"
echo "    AGENT_ADMIN_ID=${AGENT_ADMIN_ID}"

echo "==> 7) Assign admins to organization"
curl -sS -X POST "${BASE_URL}/admin-organization-assignments" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"admin_id\":\"${LEAD_ADMIN_ID}\",\"organization_id\":\"${ORG_ID}\",\"is_primary\":true,\"is_active\":true}" | jq .
curl -sS -X POST "${BASE_URL}/admin-organization-assignments" \
  -H "Authorization: Bearer ${SUPER_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"admin_id\":\"${AGENT_ADMIN_ID}\",\"organization_id\":\"${ORG_ID}\",\"is_primary\":true,\"is_active\":true}" | jq .

echo "==> 8) Admin login (use lead admin for teams / cycles)"
ADMIN_LOGIN="$(curl -sS -X POST "${BASE_URL}/admin/login" \
  -H "Content-Type: application/json" \
  -d "{\"email\":\"${LEAD_EMAIL}\",\"password\":\"${ADMIN_PASSWORD}\"}")"
ADMIN_TOKEN="$(echo "$ADMIN_LOGIN" | jq -r '.data.access_token // empty')"
if [[ -z "$ADMIN_TOKEN" || "$ADMIN_TOKEN" == "null" ]]; then
  echo "$ADMIN_LOGIN" | jq . >&2
  exit 1
fi
echo "    ADMIN_TOKEN obtained"

echo "==> 9) Create team"
TEAM_RESP="$(curl -sS -X POST "${BASE_URL}/teams" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"organization_id\":\"${ORG_ID}\",\"name\":\"Field Team ${TS}\",\"description\":\"Demo\",\"is_active\":true}")"
TEAM_ID="$(echo "$TEAM_RESP" | jq -r '.data.id // empty')"
echo "    TEAM_ID=${TEAM_ID}"

echo "==> 10) Add team members (role_id = app_roles UUID; is_team_leader for single lead)"
curl -sS -X POST "${BASE_URL}/team-members" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"team_id\":\"${TEAM_ID}\",\"user_id\":\"${LEAD_ADMIN_ID}\",\"role_id\":\"${ROLE_TL_ID}\",\"is_team_leader\":true}" | jq .
curl -sS -X POST "${BASE_URL}/team-members" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"team_id\":\"${TEAM_ID}\",\"user_id\":\"${AGENT_ADMIN_ID}\",\"role_id\":\"${ROLE_SA_ID}\",\"is_team_leader\":false}" | jq .

echo "==> 11) Team hierarchy (optional explicit rebuild)"
curl -sS -X POST "${BASE_URL}/team-hierarchy/rebuild" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"organization_id\":\"${ORG_ID}\"}" | jq .

echo "==> 12) Create monthly cycle (cycle_month must be YYYY-MM-01)"
CYCLE_MONTH="${CYCLE_MONTH:-2026-06-01}"
CYCLE_RESP="$(curl -sS -X POST "${BASE_URL}/monthly-cycles" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"organization_id\":\"${ORG_ID}\",\"cycle_month\":\"${CYCLE_MONTH}\",\"status\":\"draft\"}")"
CYCLE_ID="$(echo "$CYCLE_RESP" | jq -r '.data.id // empty')"
echo "    CYCLE_ID=${CYCLE_ID}"

echo "==> 13) Roster bulk-upsert (draft)"
curl -sS -X POST "${BASE_URL}/monthly-cycles/${CYCLE_ID}/roster/bulk-upsert" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"entries\":[
    {\"team_id\":\"${TEAM_ID}\",\"user_id\":\"${LEAD_ADMIN_ID}\",\"role_id\":\"${ROLE_TL_ID}\",\"is_team_leader\":true,\"is_absent\":false},
    {\"team_id\":\"${TEAM_ID}\",\"user_id\":\"${AGENT_ADMIN_ID}\",\"role_id\":\"${ROLE_SA_ID}\",\"is_team_leader\":false,\"is_absent\":false}
  ]}" | jq .

echo "==> 14) Approve roster rows (needs: approve monthly cycles)"
curl -sS -X POST "${BASE_URL}/monthly-cycles/${CYCLE_ID}/roster/bulk-approve" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{}" | jq .

echo "==> 15) Diff vs previous month (roster mode)"
curl -sS "${BASE_URL}/monthly-cycles/${CYCLE_ID}/diff?compare=roster" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Accept: application/json" | jq .

echo "==> 16) Apply roster to live memberships + snapshot (needs: apply monthly cycle roster)"
curl -sS -X POST "${BASE_URL}/monthly-cycles/${CYCLE_ID}/apply-roster" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "{\"snapshot_after\":true,\"only_approved_entries\":true}" | jq .

echo "==> 17) Activate cycle (closes other active cycles in org if config says so)"
curl -sS -X POST "${BASE_URL}/monthly-cycles/${CYCLE_ID}/activate" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Accept: application/json" | jq .

echo "==> 18) List snapshot rows for cycle"
curl -sS "${BASE_URL}/team-member-cycles/by-cycle/${CYCLE_ID}" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Accept: application/json" | jq .

echo ""
echo "Done. Summary:"
echo "  ORG_ID=${ORG_ID}"
echo "  TEAM_ID=${TEAM_ID}"
echo "  CYCLE_ID=${CYCLE_ID}"
echo "  LEAD_EMAIL=${LEAD_EMAIL}  AGENT_EMAIL=${AGENT_EMAIL}  password=${ADMIN_PASSWORD}"

#
# =============================================================================
# OPTIONAL / EXTRA CURLS (copy-paste; replace TOKEN, IDs)
# =============================================================================
#
# --- Auth ---
# Super Admin:
#   curl -sS -X POST "${BASE_URL}/superadmin/login" -H "Content-Type: application/json" \
#     -d '{"email":"superadmin@example.com","password":"password123"}' | jq .
# Admin:
#   curl -sS -X POST "${BASE_URL}/admin/login" -H "Content-Type: application/json" \
#     -d '{"email":"YOU@example.com","password":"YOUR_PASSWORD"}' | jq .
#
# --- Organizations ---
#   curl -sS -H "Authorization: Bearer TOKEN" -H "Accept: application/json" "${BASE_URL}/organizations"
#   curl -sS -H "Authorization: Bearer TOKEN" -H "Accept: application/json" "${BASE_URL}/organizations/ORG_ID"
#
# --- Roles ---
#   curl -sS -H "Authorization: Bearer TOKEN" -H "Accept: application/json" "${BASE_URL}/roles/active"
#   curl -sS -X POST "${BASE_URL}/roles" -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
#     -d '{"roleName":"Custom Role","description":"...","isActive":true}' | jq .
#
# --- Teams ---
#   curl -sS -H "Authorization: Bearer ADMIN_TOKEN" "${BASE_URL}/teams/by-organization/ORG_ID"
#   curl -sS -X PUT "${BASE_URL}/teams/TEAM_ID" -H "Authorization: Bearer ADMIN_TOKEN" \
#     -H "Content-Type: application/json" -d '{"name":"Renamed"}' | jq .
#
# --- Team members ---
#   curl -sS "${BASE_URL}/team-members/by-team/TEAM_ID" -H "Authorization: Bearer ADMIN_TOKEN" | jq .
#   curl -sS -X POST "${BASE_URL}/team-members/ID/make-leader" -H "Authorization: Bearer ADMIN_TOKEN" | jq .
#
# --- Team hierarchy ---
#   curl -sS "${BASE_URL}/team-hierarchy?organization_id=ORG_ID" -H "Authorization: Bearer TOKEN" | jq .
#   curl -sS "${BASE_URL}/team-hierarchy/team/TEAM_ID/descendants" -H "Authorization: Bearer TOKEN" | jq .
#
# --- Monthly cycle governance (if REQUIRE_CYCLE_APPROVAL=true) ---
#   curl -sS -X POST "${BASE_URL}/monthly-cycles/CYCLE_ID/submit" -H "Authorization: Bearer ADMIN_TOKEN" | jq .
#   curl -sS -X POST "${BASE_URL}/monthly-cycles/CYCLE_ID/approve-cycle" -H "Authorization: Bearer ADMIN_TOKEN" | jq .
#   curl -sS -X POST "${BASE_URL}/monthly-cycles/CYCLE_ID/reject-cycle" -H "Authorization: Bearer ADMIN_TOKEN" | jq .
#
# --- Close cycle ---
#   curl -sS -X POST "${BASE_URL}/monthly-cycles/CYCLE_ID/close" -H "Authorization: Bearer ADMIN_TOKEN" | jq .
#
# --- Snapshot only (without apply-roster) ---
#   curl -sS -X POST "${BASE_URL}/monthly-cycles/CYCLE_ID/snapshot" -H "Authorization: Bearer ADMIN_TOKEN" \
#     -H "Content-Type: application/json" -d '{}' | jq .
#   curl -sS -X POST "${BASE_URL}/team-member-cycles/snapshot" -H "Authorization: Bearer ADMIN_TOKEN" \
#     -H "Content-Type: application/json" -d '{"cycle_id":"CYCLE_ID"}' | jq .
#
# =============================================================================
