import assert from "node:assert/strict";
import test from "node:test";
import {
  extractHealthPatch,
  healthGateComplete,
  nextDiseaseQuestion,
  remainingDiseaseModules,
  R_DISEASE,
} from "@/lib/mortgage/health";
import { detectEmergency, missingRequired } from "@/lib/mortgage/gates";
import { emptyProfile, type ApplicantProfile } from "@/lib/mortgage/schema";
import { mergeProfile } from "@/lib/mortgage/extract";

function apply(message: string, asked?: string, base?: ApplicantProfile) {
  return mergeProfile(base || emptyProfile(), extractHealthPatch(message, asked, base));
}

test("S4-01 clean bill of health completes all R screens", () => {
  const p = apply("No, I don't have any of those conditions");
  assert.equal(p.diseases_none_reported, true);
  assert.equal(p.diseases_complete, true);
  for (const m of R_DISEASE) assert.equal(p.disease_screens?.[m], "no");
  assert.equal(healthGateComplete(p), true);
});

test("S4-02 otherwise healthy forces remaining screens to no", () => {
  let p = apply("I have type 2 diabetes");
  p = apply("Rest of my health is good", undefined, p);
  assert.equal(p.disease_screens?.diabetes, "yes");
  for (const m of R_DISEASE.filter((x) => x !== "diabetes")) {
    assert.equal(p.disease_screens?.[m], "no");
  }
  assert.equal(p.diseases_complete, true);
});

test("S4-03 diabetes type and year", () => {
  const p = apply("I have type 2 diabetes, diagnosed in 2015");
  assert.equal(p.disease_screens?.diabetes, "yes");
  const dm = (p.impairments || []).find((i) => i.module === "diabetes");
  assert.equal(dm?.attributes.type, "Type 2");
  assert.equal(dm?.attributes.diagnosed_year, "2015");
});

test("S4-04 diabetes metformin medication", () => {
  const p = apply("I'm on metformin for diabetes");
  assert.equal(p.disease_screens?.diabetes, "yes");
  const dm = (p.impairments || []).find((i) => i.module === "diabetes");
  assert.match(String(dm?.attributes.medication || ""), /metformin/i);
});

test("S4-05 complications denied after diabetes ask", () => {
  let p = apply("diabetes");
  p = apply("no", "any complications from diabetes", p);
  const dm = (p.impairments || []).find((i) => i.module === "diabetes");
  assert.equal(dm?.attributes.complications, false);
});

test("S4-06 no on diabetes does not clear prior cancer yes", () => {
  let p = apply("I had cancer and chemo");
  p = apply("no", "You mentioned diabetes — is it Type 1 or Type 2?", p);
  assert.equal(p.disease_screens?.cancer, "yes");
  assert.equal(p.disease_screens?.diabetes, "no");
});

test("S4-07 year-only attaches only with diabetes context", () => {
  const withCtx = apply("2015", "when diagnosed diabetes", apply("diabetes"));
  assert.equal(
    (withCtx.impairments || []).find((i) => i.module === "diabetes")?.attributes.diagnosed_year,
    "2015"
  );
  const noCtx = apply("2015");
  assert.equal(
    (noCtx.impairments || []).find((i) => i.module === "diabetes")?.attributes.diagnosed_year,
    undefined
  );
});

test("S4-08 heart attack", () => {
  const p = apply("I had a heart attack in 2019");
  assert.equal(p.disease_screens?.heart, "yes");
  assert.ok((p.impairments || []).some((i) => i.module === "heart"));
});

test("S4-09 kidney dialysis", () => {
  const p = apply("I'm on dialysis");
  assert.equal(p.disease_screens?.kidney, "yes");
  const raw = JSON.stringify((p.impairments || []).find((i) => i.module === "kidney"));
  assert.match(raw.toLowerCase(), /dialysis|disclosed/);
});

test("S4-10 cancer chemo", () => {
  const p = apply("History of cancer, had chemo");
  assert.equal(p.disease_screens?.cancer, "yes");
});

test("S4-11 disabled synonyms from health knowledge_base", () => {
  assert.equal(apply("I have lupus", "immune or lupus?").disease_screens?.disabled, "yes");
  assert.equal(apply("arthritis in both knees").disease_screens?.disabled, "yes");
  assert.equal(apply("I can't work because of disability").disease_screens?.disabled, "yes");
});

test("S4-12 lung COPD oxygen", () => {
  const p = apply("I have COPD, use oxygen");
  assert.equal(p.disease_screens?.lung, "yes");
  const raw = JSON.stringify(p.impairments || []).toLowerCase();
  assert.match(raw, /oxygen|copd|lung/);
});

test("S4-13 remainingDiseaseModules excludes answered heart", () => {
  const p = mergeProfile(emptyProfile(), {
    disease_screens: { heart: "no", diabetes: "no", cancer: "no", kidney: "no" },
  });
  assert.ok(!remainingDiseaseModules(p).includes("heart"));
  assert.deepEqual(remainingDiseaseModules(p), ["disabled"]);
  assert.match(nextDiseaseQuestion(p), /disab/i);
});

test("S4-14 health gate open when disabled untouched", () => {
  const p = mergeProfile(emptyProfile(), {
    disease_screens: { heart: "no", diabetes: "no", cancer: "no", kidney: "no" },
  });
  assert.equal(healthGateComplete(p), false);
  assert.ok(missingRequired(p, 4).includes("diseases:disabled"));
});

test("S4-15 emergency symptoms halt disease interview", () => {
  assert.equal(detectEmergency("I have chest pain right now"), true);
  assert.equal(detectEmergency("I can't breathe"), true);
  assert.equal(detectEmergency("sudden weakness on my left side"), true);
});

test("S4-16 vague no without asked module does not mark a random screen", () => {
  const p = apply("no");
  assert.equal(p.disease_screens?.heart, undefined);
  assert.equal(p.disease_screens?.diabetes, undefined);
  assert.equal(p.diseases_complete, undefined);
});

test("S4-17 multiple diseases in one message", () => {
  const p = apply("I have diabetes and had a heart attack");
  assert.equal(p.disease_screens?.diabetes, "yes");
  assert.equal(p.disease_screens?.heart, "yes");
});

test("knowledge_base health groups: liver/digestive/mental stay out of R remaining", () => {
  const p = apply("I have hepatitis C and anxiety");
  assert.ok(!remainingDiseaseModules(p).includes("lung"));
  assert.equal(remainingDiseaseModules(emptyProfile()).length, 5);
});
