import assert from "node:assert/strict";
import test from "node:test";
import { MP_CHAT_API, MP_JOURNEY_IDS } from "../mp-golden";
import { heuristicPatch, mergeProfile } from "@/lib/mortgage/extract";
import { computeProcess, detectStopPath } from "@/lib/mortgage/gates";
import { emptyProfile } from "@/lib/mortgage/schema";
import { isGreetingOnly } from "@/lib/mortgage/usGeo";

test("golden catalog covers MP-001–200 with journeys", () => {
  const ids = new Set([...MP_CHAT_API.map((c) => c.id), ...MP_JOURNEY_IDS]);
  for (let i = 1; i <= 200; i++) {
    const id = `MP-${String(i).padStart(3, "0")}`;
    assert.ok(ids.has(id), id);
  }
});

test("golden Chat-API extract expectations match heuristic replay", () => {
  const failures: string[] = [];
  for (const c of MP_CHAT_API) {
    let profile = emptyProfile();
    let stop: string | null = null;
    for (const message of c.messages) {
      stop = detectStopPath(message) || stop;
      const patch = isGreetingOnly(message) ? {} : heuristicPatch(message, { profile });
      profile = mergeProfile(profile, patch);
    }
    const process = computeProcess(profile, stop);
    if (c.profile) {
      for (const [k, v] of Object.entries(c.profile)) {
        const actual = (profile as Record<string, unknown>)[k];
        if (JSON.stringify(actual) !== JSON.stringify(v)) {
          failures.push(`${c.id} ${k}: expected ${JSON.stringify(v)} got ${JSON.stringify(actual)}`);
        }
      }
    }
    for (const k of c.absent || []) {
      const actual = (profile as Record<string, unknown>)[k];
      if (actual) failures.push(`${c.id} ${k} should be absent, got ${JSON.stringify(actual)}`);
    }
    if (c.screens) {
      const screens = profile.disease_screens || {};
      for (const [k, v] of Object.entries(c.screens)) {
        if (screens[k] !== v) failures.push(`${c.id} screen ${k}: expected ${v} got ${screens[k]}`);
      }
    }
    if (c.step != null && process.step !== c.step) {
      failures.push(`${c.id} step: expected ${c.step} got ${process.step}`);
    }
    if (c.stopPath === null && stop) failures.push(`${c.id} stop should be empty, got ${stop}`);
    if (c.stopPath && stop !== c.stopPath) failures.push(`${c.id} stop: expected ${c.stopPath} got ${stop}`);
  }
  assert.deepEqual(failures, [], failures.join("\n"));
});
