// BoU/NPS regulatory-return serializer — the "real data, never fabricated" bar.
//
// The load-bearing assertion is that the return counts ONLY real, period-scoped rows: seed 2 SARs
// inside the period and 1 outside, and the return must report 2 — not 3, and not a hardcoded number
// (the deleted fabrication signed hardcoded "23 SARs / UGX 4.2 quadrillion"). Plus: MM-DAILY-SETTLE
// is refused (NOT_ASSESSED — no real settlement source), an empty period is honestly zero, and every
// generated return is submittable:false / PENDING_ACTUAL_BOU_TEMPLATE (never a fabricated "ready").
//
// Full-DB integration test (like tenant-isolation-probes): requires DATABASE_URL + boot secrets +
// initialised RLS. Seeds under a unique test tenant and cleans up via the superuser pool in `after`.

import { test, describe, before, after } from "node:test";
import assert from "node:assert/strict";
import { sql } from "drizzle-orm";

const { db, ddlPool } = await import("../server/db.js");
const { runWithTenantContext } = await import("../server/lib/tenant-context.js");
const { serializeBouReturn } = await import("../server/lib/regulatory/bou-return-serializer.js");

const RUN = `bou-test-${Date.now()}`;
const EMPTY = `${RUN}-empty`;
const periodStart = new Date("2026-04-01T00:00:00.000Z");
const periodEnd = new Date("2026-06-30T23:59:59.000Z");
const inPeriod = "2026-05-15T10:00:00.000Z";
const outOfPeriod = "2026-01-15T10:00:00.000Z"; // before the period

function sarRaised(r: any): number {
  const sec = r.sections.find((s: any) => s.title.includes("Suspicious"));
  return sec.fields.find((f: any) => String(f.label).includes("raised")).value;
}

describe("BoU/NPS return serializer — real data, never fabricated", () => {
  before(async () => {
    // 2 SARs inside the period + 1 outside, all for the test tenant.
    await runWithTenantContext(RUN, async () => {
      for (const [i, when] of [[1, inPeriod], [2, inPeriod], [3, outOfPeriod]] as const) {
        await db.execute(sql`
          INSERT INTO sar_filings (sar_ref, customer_ref, tenant_id, suspicion_type, drafted_at, status, within_sla)
          VALUES (${`${RUN}-sar-${i}`}, 'CUST-TEST', ${RUN}, 'Structuring (test)', ${when}, 'filed', 1)
        `);
      }
    });
  });

  after(async () => {
    // superuser cleanup (bypasses RLS) — remove this run's rows only.
    await ddlPool.query(`DELETE FROM sar_filings WHERE tenant_id LIKE $1`, [`${RUN}%`]);
    await ddlPool.query(`DELETE FROM compliance_check_results WHERE tenant_id LIKE $1`, [`${RUN}%`]);
    await ddlPool.query(`DELETE FROM compliance_check_runs WHERE tenant_id LIKE $1`, [`${RUN}%`]);
  });

  test("LOAD-BEARING: AML-FIA-Q counts ONLY real in-period rows (2), not the out-of-period one, not a fabricated number", async () => {
    const r = await serializeBouReturn({ reportCode: "AML-FIA-Q", periodStart, periodEnd, tenantId: RUN });
    assert.equal(r.status, "GENERATED");
    assert.equal(r.submittable, false, "template pending → not submittable (never a fabricated 'ready')");
    assert.equal(r.templateStatus, "PENDING_ACTUAL_BOU_TEMPLATE");
    assert.equal(sarRaised(r), 2, "must count exactly the 2 in-period SARs — not 3 (out-of-period excluded), not a hardcoded figure");
    assert.ok(r.gaps.length > 0, "must surface the template gap");
  });

  test("honest empty: a tenant/period with no activity reports zero, not a floor figure", async () => {
    const r = await serializeBouReturn({ reportCode: "AML-FIA-Q", periodStart, periodEnd, tenantId: EMPTY });
    assert.equal(r.status, "GENERATED");
    assert.equal(sarRaised(r), 0, "no rows → honest zero");
  });

  test("MM-DAILY-SETTLE is refused NOT_ASSESSED — no real settlement source (does not re-create the deleted fabrication)", async () => {
    const r = await serializeBouReturn({ reportCode: "MM-DAILY-SETTLE", periodStart, periodEnd, tenantId: RUN });
    assert.equal(r.status, "NOT_ASSESSED");
    assert.equal(r.submittable, false);
    assert.equal(r.sections.length, 0, "no fabricated sections/figures");
    assert.match(String(r.note), /NOT_ASSESSED/);
  });

  test("CYBER-RISK-Q generates from real incidents + a PERSISTED compliance run (not a recompute of hardcoded numbers)", async () => {
    const r = await serializeBouReturn({ reportCode: "CYBER-RISK-Q", periodStart, periodEnd, tenantId: RUN });
    assert.equal(r.status, "GENERATED");
    assert.equal(r.submittable, false);
    assert.ok(r.sections.some((s: any) => s.title.includes("incidents")), "has a security-incidents section");
    assert.ok(r.sections.some((s: any) => s.title.includes("Control self-assessment")), "has the control self-assessment section");
    assert.ok(r.provenance.complianceRunId !== undefined, "references a persisted compliance run (runId), not a live recompute");
    assert.ok(r.gaps.some((g: string) => g.includes("synthetic") || g.includes("EXCLUDED")), "surfaces the synthetic-threat exclusion gap");
  });
});
