// API client for Mossad backend.
// Falls back gracefully to static demo data if backend is unreachable or unauthenticated.

const API_BASE = "/api/v1";

let _token = localStorage.getItem("mossad_token");
let _tenantId = localStorage.getItem("mossad_tenant");

function headers() {
  const h = { "Content-Type": "application/json" };
  if (_token) h["Authorization"] = `Bearer ${_token}`;
  if (_tenantId) h["X-Tenant-ID"] = _tenantId;
  return h;
}

async function api(path, options = {}) {
  const url = `${API_BASE}${path}`;
  const res = await fetch(url, {
    ...options,
    headers: { ...headers(), ...(options.headers || {}) },
  });
  if (res.status === 401) {
    clearAuth();
    throw new Error("UNAUTHORIZED");
  }
  if (!res.ok) {
    const text = await res.text().catch(() => "");
    throw new Error(`HTTP ${res.status}: ${text}`);
  }
  return res.status === 204 ? null : res.json();
}

function setAuth(token, tenantId) {
  _token = token;
  _tenantId = tenantId;
  localStorage.setItem("mossad_token", token);
  localStorage.setItem("mossad_tenant", tenantId);
}

function clearAuth() {
  _token = null;
  _tenantId = null;
  localStorage.removeItem("mossad_token");
  localStorage.removeItem("mossad_tenant");
}

function isAuthenticated() {
  return !!(_token && _tenantId);
}

async function login(email, password) {
  const data = await api("/auth/login", {
    method: "POST",
    body: JSON.stringify({ email, password }),
  });
  // Temporarily set the token so /auth/me can authenticate and return tenant_id.
  _token = data.access_token;
  const me = await api("/auth/me");
  setAuth(data.access_token, me.tenant_id);
  return { ...data, tenant_id: me.tenant_id };
}

async function fetchDashboard() {
  return api("/analytics/dashboard");
}

// Pages through the full alert set — the backend paginates via limit/offset and has no
// server-side cap, so a single fixed-limit request silently drops alerts once the tenant
// has more open alerts than that limit (seen live: 15,937 open alerts vs. a hardcoded 10,000).
async function fetchAlerts(params = "") {
  const pageSize = 5000;
  const safetyCap = 100000; // stop paging if something is very wrong, rather than looping forever
  let offset = 0;
  let all = [];
  while (true) {
    const page = await api(`/alerts?limit=${pageSize}&offset=${offset}${params ? "&" + params : ""}`);
    all = all.concat(page);
    if (page.length < pageSize || all.length >= safetyCap) break;
    offset += pageSize;
  }
  return all;
}

async function fetchCases(params = "") {
  return api(`/cases?limit=50${params ? "&" + params : ""}`);
}

async function fetchRules() {
  return api("/rules");
}

async function fetchRiskProfiles() {
  return api("/analytics/risk-profiles?limit=76");
}

async function fetchCustomers(limit = 500, q = "") {
  const params = new URLSearchParams({ limit: String(limit) });
  if (q) params.set("q", q);
  return api(`/customers?${params.toString()}`);
}

async function fetchCustomer(customerId) {
  return api(`/customers/${customerId}`);
}

async function fetchCustomerTransactions(customerId, limit = 100) {
  return api(`/customers/${customerId}/transactions?limit=${limit}`);
}

async function fetchCustomerAlerts(customerId, limit = 100) {
  return api(`/customers/${customerId}/alerts?limit=${limit}`);
}

async function fetchCustomerCases(customerId, limit = 100) {
  return api(`/customers/${customerId}/cases?limit=${limit}`);
}

async function fetchTenants() {
  return api("/tenants");
}

async function fetchTransactions(limit = 1000) {
  return api(`/transactions?limit=${limit}`);
}

async function updateAlert(id, body) {
  return api(`/alerts/${id}`, { method: "PUT", body: JSON.stringify(body) });
}

async function convertAlertToCase(id) {
  return api(`/alerts/${id}/convert-to-case`, { method: "POST" });
}

async function addAlertToCase(caseId, alertId) {
  return api(`/cases/${caseId}/alerts/${alertId}`, { method: "POST" });
}

async function fetchCaseAlerts(caseId) {
  return api(`/cases/${caseId}/alerts`);
}

async function fetchAlertNetwork(alertId) {
  return api(`/alerts/${alertId}/network`);
}

async function fetchAlertTransactions(alertId) {
  return api(`/alerts/${alertId}/transactions`);
}

async function addCaseComment(caseId, content) {
  return api(`/cases/${caseId}/comments`, { method: "POST", body: JSON.stringify({ content, is_internal: true }) });
}

async function addAlertNote(id, content) {
  return api(`/alerts/${id}/notes`, { method: "POST", body: JSON.stringify({ content }) });
}

async function fetchSARs(params = "") {
  return api(`/sars?limit=1000${params ? "&" + params : ""}`);
}

async function createSAR(body) {
  return api("/sars", { method: "POST", body: JSON.stringify(body) });
}

async function fetchSAR(id) {
  return api(`/sars/${id}`);
}

async function updateSAR(id, body) {
  return api(`/sars/${id}`, { method: "PUT", body: JSON.stringify(body) });
}

async function fileSAR(id) {
  return api(`/sars/${id}/file`, { method: "POST" });
}

async function addSARNote(id, content) {
  return api(`/sars/${id}/notes`, { method: "POST", body: JSON.stringify({ content }) });
}

async function createRule(body) {
  return api("/rules", { method: "POST", body: JSON.stringify(body) });
}

async function updateRule(id, body) {
  return api(`/rules/${id}`, { method: "PUT", body: JSON.stringify(body) });
}

async function activateRule(id) {
  return api(`/rules/${id}/activate`, { method: "POST" });
}

async function deactivateRule(id) {
  return api(`/rules/${id}/deactivate`, { method: "POST" });
}

async function deleteRule(id) {
  return api(`/rules/${id}`, { method: "DELETE" });
}

async function simulateRules(body) {
  return api("/rules/simulate", { method: "POST", body: JSON.stringify(body) });
}

async function createManualAlerts(body) {
  return api("/alerts/manual", { method: "POST", body: JSON.stringify(body) });
}

// Map backend alert schema to the UI's expected shape.
function mapAlert(a) {
  const typology = a.matched_patterns?.[0]?.rule_type || "Unknown";
  const rule = a.matched_patterns?.[0]?.rule_name || "R-000 · Unknown rule";
  return {
    id: a.id,
    external_id: a.external_id,
    case: a.case_id ? `CSE-${a.external_id.split("-")[1]}` : "—",
    risk: Math.round(Number(a.risk_score || 0)),
    severity: a.severity || "low",
    typology: typologyToName(typology),
    rule: rule,
    subject: a.primary_entity_id || "Unknown",
    subjectType: a.primary_entity_type === "business" ? "business" : "person",
    subjectCountry: a.primary_entity_country || "US",
    counterparty: a.counterparty_name || "—",
    cpCountry: a.counterparty_country || "—",
    amount: Number(a.amount || 0),
    currency: a.currency || "USD",
    customerId: a.customer_id || a.primary_entity_id || "—",
    ruleIds: a.rule_ids || [],
    txnCount: a.txn_count || 1,
    opened: a.created_at,
    sla: "—",
    slaWarn: false,
    assignee: a.assignee_name || "Unassigned",
    status: a.status || "open",
    channel: a.channel || "—",
    notes: a.notes || [],
    score: {
      volume: Math.min(99, Math.round(Number(a.risk_score || 0) * 0.9)),
      velocity: Math.min(99, Math.round(Number(a.risk_score || 0) * 0.8)),
      geo: Math.min(99, Math.round(Number(a.risk_score || 0) * 0.5)),
      peer: Math.min(99, Math.round(Number(a.risk_score || 0) * 0.7)),
    },
    flagged: a.severity === "high" || a.severity === "critical",
    _raw: a,
  };
}

function typologyToName(ruleType) {
  const map = {
    threshold: "Structuring",
    velocity: "Velocity anomaly",
    anomaly: "Mule activity",
    list_match: "PEP/Sanctions",
    composite: "Round-tripping",
  };
  return map[ruleType] || "Other";
}

// Map backend case schema to UI shape.
function mapCase(c) {
  return {
    id: c.external_id,
    title: c.title,
    status: c.status,
    priority: c.priority,
    entity: c.primary_entity_id,
    risk: Math.round(Number(c.risk_score || 0)),
    alerts: c.alert_count,
    amount: Number(c.total_amount || 0),
    customerId: c.customer_id || c.primary_entity_id || "—",
    assignee: c.assignee_name || "Unassigned",
    opened: c.created_at,
    _raw: c,
  };
}

Object.assign(window, {
  mossadApi: {
    login,
    logout: clearAuth,
    isAuthenticated,
    fetchDashboard,
    fetchAlerts,
    fetchCases,
    fetchRules,
    fetchRiskProfiles,
    fetchCustomers,
    fetchCustomer,
    fetchCustomerTransactions,
    fetchCustomerAlerts,
    fetchCustomerCases,
    fetchTenants,
    fetchTransactions,
    updateAlert,
    convertAlertToCase,
    addAlertToCase,
    fetchCaseAlerts,
    fetchAlertNetwork,
    fetchAlertTransactions,
    addCaseComment,
    addAlertNote,
    fetchSARs,
    createSAR,
    fetchSAR,
    updateSAR,
    fileSAR,
    addSARNote,
    createRule,
    updateRule,
    activateRule,
    deactivateRule,
    deleteRule,
    simulateRules,
    createManualAlerts,
    mapAlert,
    mapCase,
  },
});
