import type { ApplicantProfile } from "./schema";

/** Mortgage SI required disease screens (R modules). */
export const R_DISEASE = ["heart", "diabetes", "cancer", "kidney", "disabled"] as const;
export type DiseaseModule = (typeof R_DISEASE)[number] | "lung";

export const DISEASE_ASK: Record<DiseaseModule, string> = {
  heart: "Have you had a heart attack, stent, bypass, stroke, or heart failure — or is it none of those?",
  diabetes: "You mentioned diabetes — is it Type 1 or Type 2, and about what year were you diagnosed?",
  cancer: "Any cancer history other than basal cell skin cancer? You can say no.",
  kidney: "Any kidney disease, dialysis, or kidney failure? You can say no.",
  disabled: "Any disability or condition that keeps you from working? You can say no.",
  lung: "Any lung or COPD history? You can say no.",
};

const MODULE_HINTS: { module: DiseaseModule; re: RegExp }[] = [
  { module: "diabetes", re: /diabet|diabtic|metformin|insulin|a1c|hba1c|blood sugar/i },
  { module: "cancer", re: /cancer|chemo|malignant|tumor/i },
  { module: "heart", re: /heart (attack|disease|problem|issue|condition)|stent|bypass|stroke|chf|atrial|pacemaker|cardiac/i },
  { module: "kidney", re: /kidney|dialysis|renal/i },
  { module: "lung", re: /lung|copd|emphysema|asthma|oxygen|pulmonar/i },
  { module: "disabled", re: /disab|cannot work|can't work|wheelchair|lupus|epilep|arthritis|sclerosis|parkinson/i },
];

function lastAskedModule(assistant?: string): DiseaseModule | null {
  if (!assistant) return null;
  const t = assistant.toLowerCase();
  if (/diabet/.test(t)) return "diabetes";
  if (/cancer/.test(t)) return "cancer";
  if (/kidney|dialysis/.test(t)) return "kidney";
  if (/heart|cardiac|stroke|stent/.test(t)) return "heart";
  if (/lung|copd|asthma|emphysema/.test(t)) return "lung";
  if (/disab/.test(t)) return "disabled";
  if (/immune|neurolog|epilep|lupus|sclerosis/.test(t)) return "disabled";
  if (/joint|arthritis|muscle/.test(t)) return "disabled";
  return null;
}

function isNo(message: string) {
  return /^(no|nope|none|never|no never|n)$/i.test(message.trim()) || /\bno never\b|\bnone of (those|them|that)\b|\bno (cancer|heart|kidney|diabetes)?\b/i.test(message);
}

function mergeImpairment(
  list: NonNullable<ApplicantProfile["impairments"]> | undefined,
  module: string,
  attributes: Record<string, string | number | boolean>,
  path?: string
) {
  const next = [...(list || [])];
  const i = next.findIndex((x) => x.module === module);
  const row = i >= 0 ? next[i] : { module, attributes: {}, path_answers: [] as string[] };
  row.attributes = { ...row.attributes, ...attributes };
  if (path) row.path_answers = [...(row.path_answers || []), path].slice(-12);
  if (i >= 0) next[i] = row;
  else next.push(row);
  return next;
}

export function remainingDiseaseModules(p: ApplicantProfile): DiseaseModule[] {
  const screens = p.disease_screens || {};
  return R_DISEASE.filter((m) => screens[m] !== "yes" && screens[m] !== "no");
}

export function healthGateComplete(p: ApplicantProfile): boolean {
  if (p.diseases_none_reported || p.diseases_complete) return true;
  return remainingDiseaseModules(p).length === 0;
}

/** Pull health/disease facts from this turn into the mortgage ApplicantProfile. */
export function extractHealthPatch(
  message: string,
  lastAssistant?: string,
  base?: ApplicantProfile
): Partial<ApplicantProfile> {
  const t = message.toLowerCase();
  const screens: NonNullable<ApplicantProfile["disease_screens"]> = { ...(base?.disease_screens || {}) };
  let impairments = base?.impairments ? [...base.impairments] : undefined;
  const patch: Partial<ApplicantProfile> = {};
  const asked = lastAskedModule(lastAssistant);

  const restGood =
    /rest (of )?(my )?health is (very )?(good|fine|ok)|only .{0,80}diabet|only .{0,80}diabtic|no other (health )?condition|otherwise (healthy|fine|good)|nothing else/i.test(
      t
    );

  if (
    /\bno (diagnos|disease|conditions|history)\b|\bnone of those\b|\b(don't|do not) have any of those\b|\bno medical (issues|problems)\b/.test(
      t
    ) &&
    !/diabet/.test(t)
  ) {
    patch.diseases_none_reported = true;
    patch.diseases_complete = true;
    for (const m of R_DISEASE) screens[m] = screens[m] === "yes" ? "yes" : "no";
    patch.disease_screens = screens;
    return patch;
  }

  if (isNo(message) && asked) {
    if (screens[asked] !== "yes") screens[asked] = "no";
    patch.disease_screens = screens;
  }

  if (/diabet|diabtic|metformin|insulin/i.test(t)) {
    screens.diabetes = "yes";
    const attrs: Record<string, string | number | boolean> = { disclosed: true };
    const typ = message.match(/type\s*([12])/i);
    if (typ) attrs.type = `Type ${typ[1]}`;
    const year = message.match(/\b(19|20)\d{2}\b/);
    if (year) attrs.diagnosed_year = year[0];
    if (/metformin/i.test(t)) attrs.medication = message.match(/metformin[^.]*/i)?.[0] || "Metformin";
    if (/no complication/i.test(t) || (asked === "diabetes" && isNo(message) && /complication/i.test(lastAssistant || ""))) {
      attrs.complications = false;
    }
    impairments = mergeImpairment(impairments, "diabetes", attrs, message.slice(0, 180));
  }

  if (yearOnly(message) && (asked === "diabetes" || screens.diabetes === "yes")) {
    screens.diabetes = "yes";
    impairments = mergeImpairment(impairments, "diabetes", { diagnosed_year: message.match(/\b(19|20)\d{2}\b/)![0] }, message);
  }

  if (/type\s*[12]/i.test(t) && (asked === "diabetes" || /diabet/i.test(t) || screens.diabetes === "yes")) {
    screens.diabetes = "yes";
    impairments = mergeImpairment(impairments, "diabetes", { type: /type\s*1/i.test(t) ? "Type 1" : "Type 2" }, message);
  }

  if (/metformin|insulin/i.test(t)) {
    screens.diabetes = "yes";
    impairments = mergeImpairment(
      impairments,
      "diabetes",
      { medication: message.trim().slice(0, 120) },
      message
    );
  }

  if (asked && isNo(message) && /complication/i.test(lastAssistant || "") && screens.diabetes === "yes") {
    impairments = mergeImpairment(impairments, "diabetes", { complications: false }, "no complications");
  }

  for (const { module, re } of MODULE_HINTS) {
    if (re.test(message) && !isNo(message)) {
      screens[module] = "yes";
      impairments = mergeImpairment(impairments, module, { disclosed: true }, message.slice(0, 180));
    }
  }

  if (restGood) {
    for (const m of R_DISEASE) {
      if (screens[m] !== "yes") screens[m] = "no";
    }
  }

  if (Object.keys(screens).length) patch.disease_screens = screens;
  if (impairments?.length) patch.impairments = impairments;

  const allDone = R_DISEASE.every((m) => screens[m] === "yes" || screens[m] === "no");
  if (allDone) patch.diseases_complete = true;
  if (R_DISEASE.every((m) => screens[m] === "no")) patch.diseases_none_reported = true;

  return patch;
}

function yearOnly(message: string) {
  return /^(in\s*)?(19|20)\d{2}\.?$/.test(message.trim());
}

export function nextDiseaseQuestion(p: ApplicantProfile): string {
  const left = remainingDiseaseModules(p);
  if (!left.length) return "Thanks — I have the health screens we need for this file.";
  if (p.disease_screens?.diabetes === "yes") {
    const d = (p.impairments || []).find((i) => i.module === "diabetes")?.attributes || {};
    if (!d.type) return DISEASE_ASK.diabetes;
    if (!d.diagnosed_year) return "About what year were you diagnosed with diabetes?";
    if (d.medication == null && d.complications == null) {
      /* already has meds possibly */
    }
  }
  return DISEASE_ASK[left[0]];
}
