import assert from "node:assert/strict";
import test from "node:test";
import { computeProcess, missingRequired } from "@/lib/mortgage/gates";
import { emptyProfile, type ApplicantProfile } from "@/lib/mortgage/schema";
import { heuristicPatch, mergeProfile } from "@/lib/mortgage/extract";

function profile(extra: Partial<ApplicantProfile> = {}): ApplicantProfile {
  return mergeProfile(emptyProfile(), {
    name: "Ann",
    state: "FL",
    intent: "mortgage_protection",
    coverage_on_whom: "primary",
    age: 40,
    loan_balance: 200000,
    height_ft_in: "5'6\"",
    weight_lb: 140,
    tobacco_answered: true,
    diseases_complete: true,
    ...extra,
  });
}

test("S5-01 primary income and beneficiary pass gate5", () => {
  const patch = heuristicPatch("I make $85,000 a year, beneficiary is my spouse");
  const p = mergeProfile(profile(), patch);
  assert.equal(p.annual_income, 85000);
  assert.equal(p.beneficiary_relationship, "spouse");
  assert.equal(missingRequired(p, 5).length, 0);
  assert.equal(computeProcess(p).step, 6);
});

test("S5-02 co-borrower spouse age then spouse income then applicant income", () => {
  let p = profile({ co_borrower_flag: true, coverage_on_whom: "both" });
  p = mergeProfile(p, heuristicPatch("my wife is 38"));
  assert.ok(p.spouse_age_sex);
  p = mergeProfile(p, heuristicPatch("she makes 40000", { lastAssistant: "About what is your spouse’s annual income?" }));
  assert.equal(p.spouse_annual_income, 40000);
  p = mergeProfile(p, heuristicPatch("I make 85000"));
  assert.equal(p.annual_income, 85000);
  p = mergeProfile(p, heuristicPatch("beneficiary is my spouse"));
  assert.equal(computeProcess(p).step, 6);
});

test("S5-03 co-borrower missing spouse_age_sex", () => {
  const p = profile({ co_borrower_flag: true, coverage_on_whom: "both", annual_income: 85000 });
  assert.ok(missingRequired(p, 5).includes("spouse_age_sex"));
  assert.equal(computeProcess(p).step, 5);
});

test("S5-04 co-borrower missing spouse income", () => {
  const p = profile({
    co_borrower_flag: true,
    coverage_on_whom: "both",
    spouse_age_sex: "38 F",
    annual_income: 85000,
    beneficiary_relationship: "spouse",
  });
  assert.ok(missingRequired(p, 5).includes("spouse_annual_income"));
});

test("S5-05 applicant income missing", () => {
  const p = profile({ beneficiary_relationship: "spouse" });
  assert.ok(missingRequired(p, 5).includes("annual_income"));
});

test("S5-06 beneficiary missing", () => {
  const p = profile({ annual_income: 85000 });
  assert.ok(missingRequired(p, 5).includes("beneficiary_relationship"));
});

test("S5-07 primary-only does not require spouse fields", () => {
  const p = profile({
    co_borrower_flag: false,
    coverage_on_whom: "primary",
    annual_income: 85000,
    beneficiary_relationship: "self",
  });
  const miss = missingRequired(p, 5);
  assert.ok(!miss.includes("spouse_age_sex"));
  assert.ok(!miss.includes("spouse_annual_income"));
  assert.equal(miss.length, 0);
});

test("knowledge_base mortgage income: household and yearly wording", () => {
  assert.equal(heuristicPatch("my annual income is 85k").annual_income, 85000);
  assert.equal(
    heuristicPatch("85000", { lastAssistant: "About what is your annual household income from work" })
      .annual_income,
    85000
  );
  const spouse = heuristicPatch("spouse income is 40 thousand");
  assert.equal(spouse.spouse_annual_income, 40000);
  assert.equal(spouse.loan_balance, undefined);
});

test("S1-02 / S1-03 coverage both and spouse-only", () => {
  const both = heuristicPatch("Cover both me and my wife on the loan");
  assert.equal(both.coverage_on_whom, "both");
  assert.equal(both.co_borrower_flag, true);
  const spouse = heuristicPatch("Just my husband needs to be covered");
  assert.equal(spouse.coverage_on_whom, "spouse");
});
