import type { OcrPage } from "../../statements/ocr/ocr.provider";
import {
  detectPolicyProvider,
  parsePolicy,
  type ParsedCoverage,
} from "./policy-parser";

/**
 * Verbatim excerpts of what the GMX portal's translation PDF actually
 * rendered through pdftotext — same convention as the statement parser
 * tests, where invented-clean input would test nothing because clean input
 * is not the failure mode.
 */
function page(text: string): OcrPage {
  return { text, words: [], confidence: 0.95 };
}

describe("detectPolicyProvider", () => {
  it("claims GMX from the brand wordmark on the letterhead", () => {
    expect(
      detectPolicyProvider(
        "Grupo Mexicano de Seguros, S.A. de C.V.\nTecoyotitla 412, Edificio GMX",
      ),
    ).toBe("GMX");
  });

  it("claims GMX from the 'gmx.com.mx' footer URL", () => {
    expect(detectPolicyProvider("JUNTOS EL RIESGO ES MENOR\nwww.gmx.com.mx")).toBe("GMX");
  });
});

describe("parsePolicy / GMX", () => {
  // Verbatim text extracted from ~/Downloads/HC_Folio_000767_Traduccion.pdf via
  // `pdftotext -layout`. Two pages joined by "\n\n".
  const GMX_FULL = page(
    "Multiple Policy\nHome\n" +
      "Policy 007-037-07005947-0000-02 in accordance with the enclosed clauses, to insurance:\n" +
      "Insured JON ASHLEY STRABALA\n" +
      "Additional insured VIVIAN\n" +
      "Legal address BONAMPACK No. EXT26 No.INT 0 COL. Punta Bandera, Tijuana, Baja California, C.P. 22550\n" +
      "ZIP 22550 Income Tax No. XEXX-010101-000\n" +
      "Broker (1176) Jorge Humberto Cuadros\n" +
      "Term 12 months\n" +
      "From 19/07/2026\n" +
      "To 19/07/2027 at twelve hours (noon) Mexico City time.\n" +
      "Currency DOLARES Premium payment CONTADO\n" +
      "Free translation from the Spanish Insurance contract. The English text is just copy given by courtesy. In case of a dispute, the Spanish will prevail over the English version.\n" +
      "Agreed clauses:\n" +
      "•The insured and GMX Hereby declared...\n" +
      "From the above, the present contract shall not be considered under the condition mentioned within article 36-B from the Insurance Companies General Law. Therefore it shall not be required its registration before the Comision National de Seguros y Fianzas.\n" +
      "July 23, 2026\n" +
      "Authority sign.\n" +
      "Grupo Mexicano de Seguros, S.A. de C.V.\n" +
      "Tecoyotitla 412, Edificio GMX\n" +
      "JUNTOS EL RIESGO ES MENOR\n" +
      "www.gmx.com.mx\n\n" +
      "Risk Insured Amount Deductible Loss Participation\n" +
      "Building $350,000.00 Not applies Not applies\n" +
      "Contents $60,000.00 Not applies Not applies\n" +
      "ADDITIONAL RISK\n" +
      "Risk Insured Amount Deductible Loss Participation\n" +
      "Debris removal Building $35,000.00 Not applies Not applies\n" +
      "Debris removal Contents $6,000.00 Not applies Not applies\n" +
      "Outdoors Constructions $10,000.00 5% 10%\n" +
      "Coverage Extention Covered Not applies Not applies\n" +
      "All Risk Covered Not applies Not applies\n" +
      "Earthquake and/or volcanic eruption Covered 2% of the sum insured for each damage structure 20%\n" +
      "Extra Expenses $41,000.00 Not applies Not applies\n" +
      "Robbery with violence $10,000.00 Not applies Not applies\n" +
      "Jewerly $3,900.00 Not applies Not applies\n" +
      "Electronic Equipment $10,000.00 Not applies Not applies\n" +
      "Glasses $10,000.00 Not applies Not applies\n" +
      "Tenant $200,000.00 Not applies Not applies\n" +
      "Family $200,000.00 Not applies Not applies\n" +
      "Family $200,000.00 Not applies Not applies\n" +
      "Domestic workers $7,010.00 Not applies Not applies\n" +
      "VALUES ADDED, HOME GMX",
  );

  it("extracts the policy number, insured name, broker, dates, and currency", () => {
    const p = parsePolicy(GMX_FULL);
    expect(p.provider).toBe("GMX");
    expect(p.policyNumber).toBe("007-037-07005947-0000-02");
    expect(p.insuredName).toBe("JON ASHLEY STRABALA");
    expect(p.additionalInsured).toBe("VIVIAN");
    expect(p.agentName).toBe("Jorge Humberto Cuadros");
    expect(p.policyFrom?.toISOString().slice(0, 10)).toBe("2026-07-19");
    expect(p.policyTo?.toISOString().slice(0, 10)).toBe("2027-07-19");
    expect(p.policyDate?.toISOString().slice(0, 10)).toBe("2026-07-23");
    expect(p.currency).toBe("USD");
    expect(p.zip).toBe("22550");
    expect(p.legalAddress).toContain("BONAMPACK");
    expect(p.premiumPayment).toBe("CONTADO");
  });

  it("extracts every coverage row off the second page table", () => {
    const p = parsePolicy(GMX_FULL);
    const byName = Object.fromEntries(p.coverages.map((c) => [c.risk, c]));
    expect(byName.Building?.insuredAmount).toBe(350000);
    expect(byName.Contents?.insuredAmount).toBe(60000);
    expect(byName["Debris removal Building"]?.insuredAmount).toBe(35000);
    expect(byName["Outdoors Constructions"]?.insuredAmount).toBe(10000);
    expect(byName["Outdoors Constructions"]?.deductible).toBe("5%");
    expect(byName["Outdoors Constructions"]?.lossParticipation).toBe("10%");
    // Free-text coverage cells kept verbatim (the policy form surfaces them
    // as observations, not as numbers).
    expect(byName["Earthquake and/or volcanic eruption"]?.insuredAmount).toBeNull();
    expect(byName["Earthquake and/or volcanic eruption"]?.deductible).toContain("2%");
    expect(byName["Earthquake and/or volcanic eruption"]?.lossParticipation).toBe("20%");
    expect(byName["All Risk"]?.insuredAmount).toBeNull();
    expect(p.coverages.length).toBeGreaterThan(10);
  });

  it("leaves premium fields null on the certificate page and notes it", () => {
    const p = parsePolicy(GMX_FULL);
    expect(p.netPremium).toBeNull();
    expect(p.total).toBeNull();
    expect(p.policyFee).toBeNull();
    expect(p.notes.join(" ")).toMatch(/prima/i);
  });

  it("still parses when the broker parens are missing", () => {
    const p = parsePolicy(
      page(
        "Insured JON ASHLEY STRABALA\nBroker Jorge Humberto Cuadros\n" +
          "From 19/07/2026\nTo 19/07/2027\nCurrency DOLARES\n" +
          "Grupo Mexicano de Seguros",
      ),
    );
    expect(p.agentName).toBe("Jorge Humberto Cuadros");
  });

  it("rejects a page that carries no GMX signal at all", () => {
    const p = parsePolicy(page("Random unrelated document with no policy data."));
    expect(p.provider).toBe("");
    expect(p.notes.join(" ")).toContain("no se reconoció el proveedor");
  });

  it("captures the deductible / loss-participation columns verbatim as strings", () => {
    const p = parsePolicy(GMX_FULL);
    const eq = p.coverages.find((c) => c.risk === "Earthquake and/or volcanic eruption");
    expect(eq).toBeDefined();
    const eqTyped = eq as ParsedCoverage;
    expect(eqTyped.deductible).toContain("sum insured");
    expect(eqTyped.lossParticipation).toBe("20%");
  });
});