import { describe, it, expect } from "vitest";
// ── Werkdossier-sessies: 24 uur raadpleegbaar en bijwerkbaar ─────────────────
// Bewaakt de volledige lus: een Word-generatie maakt een sessie aan
// (dossierToken in het antwoord), de sessie is opvraagbaar in lijst en
// detail, en werkWerkdossierSessieBij voegt aanvullende stukken toe en
// regenereert het .docx met de SAMENGEVOEGDE invoer — zonder dat de
// aanroeper de eerdere parameters opnieuw moet opgeven.
import { POST as genereerWerkdossier } from "@/app/api/dossier/word/route";
import { GET as lijstSessies } from "./route";
import { GET as haalSessie, POST as werkSessieBij } from "./[token]/route";
import { haalBestand } from "@/lib/word/bestandenCache";

const MODEL_ID = "verkoopovereenkomst-compromis";

function wordRequest(body: Record<string, unknown>): Request {
  return new Request("http://localhost/api/dossier/word", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
}

function sessieRequest(token: string, body?: Record<string, unknown>): [Request, { params: Promise<{ token: string }> }] {
  return [
    new Request(`http://localhost/api/dossier/sessies/${token}`, {
      method: body ? "POST" : "GET",
      headers: { "Content-Type": "application/json" },
      ...(body ? { body: JSON.stringify(body) } : {}),
    }),
    { params: Promise.resolve({ token }) },
  ];
}

async function maakSessieViaGeneratie(): Promise<{ token: string; downloadUrl: string }> {
  const res = await genereerWerkdossier(
    wordRequest({
      modeldocumentId: MODEL_ID,
      modeldocumentParametersJson: JSON.stringify({ prijs_cijfers: "300000" }),
    })
  );
  expect(res.status).toBe(200);
  const json = await res.json();
  expect(typeof json.dossierToken).toBe("string");
  expect(typeof json.dossierVerlooptOm).toBe("string");
  return { token: json.dossierToken, downloadUrl: json.downloadUrl };
}

describe("werkdossier-sessies (24 uur raadpleegbaar/bijwerkbaar)", () => {
  it("elke generatie maakt een sessie aan die in de lijst en het detail verschijnt", async () => {
    const { token } = await maakSessieViaGeneratie();

    const lijst = await (await lijstSessies()).json();
    const inLijst = lijst.sessies.find((s: { token: string }) => s.token === token);
    expect(inLijst).toBeTruthy();
    expect(inLijst.modeldocumentId).toBe(MODEL_ID);
    expect(inLijst.aantalGeneraties).toBe(1);

    const detailRes = await haalSessie(...sessieRequest(token));
    expect(detailRes.status).toBe(200);
    const detail = await detailRes.json();
    expect(detail.soort).toBe("werkdossier");
    expect(detail.invoer.modeldocumentId).toBe(MODEL_ID);
    expect(detail.historiek).toHaveLength(1);
  });

  it("werkWerkdossierSessieBij voegt parameters samen en regenereert het .docx (zelfde token, historiek groeit)", async () => {
    const { token } = await maakSessieViaGeneratie();

    const res = await werkSessieBij(
      ...sessieRequest(token, {
        parameters: { voorschot_cijfers: "30000" },
        wijziging: "voorschot uit het betalingsbewijs aangevuld",
      })
    );
    expect(res.status).toBe(200);
    const json = await res.json();
    expect(json.dossierToken).toBe(token);
    expect(json.toegepasteWijziging).toBe("voorschot uit het betalingsbewijs aangevuld");
    expect(json.historiek).toHaveLength(2);
    // Het geregenereerde bestand bestaat echt achter de nieuwe downloadUrl.
    const nieuwToken = String(json.downloadUrl).split("/").pop()!;
    expect(await haalBestand(nieuwToken)).toBeTruthy();

    // De samengevoegde invoer bevat de OUDE én de NIEUWE parameter.
    const detail = await (await haalSessie(...sessieRequest(token))).json();
    const parameters = JSON.parse(detail.invoer.modeldocumentParametersJson);
    expect(parameters.prijs_cijfers).toBe("300000");
    expect(parameters.voorschot_cijfers).toBe("30000");
  });

  it("regeneratie vervuilt de lijst niet met een tweede sessie (interne aanroep maakt geen nieuwe aan)", async () => {
    const voor = (await (await lijstSessies()).json()).aantal;
    const { token } = await maakSessieViaGeneratie();
    await werkSessieBij(...sessieRequest(token, { parameters: { extra: "x" } }));
    const na = (await (await lijstSessies()).json()).aantal;
    expect(na).toBe(voor + 1);
  });

  it("verwijderParameters (array én kommagescheiden) haalt waarden uit de bewaarde invoer", async () => {
    const { token } = await maakSessieViaGeneratie();
    await werkSessieBij(...sessieRequest(token, { verwijderParameters: "prijs_cijfers" }));
    const detail = await (await haalSessie(...sessieRequest(token))).json();
    expect(JSON.parse(detail.invoer.modeldocumentParametersJson)).toEqual({});
  });

  it("een onbekend of verlopen token geeft een duidelijke 404 (raadplegen én bijwerken)", async () => {
    expect((await haalSessie(...sessieRequest("bestaat-niet"))).status).toBe(404);
    expect((await werkSessieBij(...sessieRequest("bestaat-niet", { parameters: {} }))).status).toBe(404);
  });
});
