import { beforeEach, describe, expect, it, vi } from "vitest";

const {
  requirePermissionMock,
  employeeScopeFromAccessMock,
  buildDraftMock,
  renderPdfMock,
} = vi.hoisted(() => ({
  requirePermissionMock: vi.fn(),
  employeeScopeFromAccessMock: vi.fn(),
  buildDraftMock: vi.fn(),
  renderPdfMock: vi.fn(),
}));

vi.mock("@/lib/authorization", () => ({
  requirePermission: requirePermissionMock,
  employeeScopeFromAccess: employeeScopeFromAccessMock,
}));

vi.mock("@/services/impressions.service", () => ({
  buildAttestationRetraitePdfDraft: buildDraftMock,
  DocumentGenerationError: class extends Error {},
}));

vi.mock("@/services/attestation-retraite-pdf.service", () => ({
  renderAttestationRetraitePdf: renderPdfMock,
}));

import { POST } from "@/app/api/impressions/attestation-retraite/pdf/route";

const data = {
  formuleSoussignataire: "soussignée",
  signataireNom: "Béatrice LAFRANCE",
  signataireFonction: "Directrice",
  titreNomPrenom: "Monsieur Nadir ABABSI",
  domicilie: "domicilié",
  adresseLigne: "125 avenue de la République, 59000 Lille",
  entreprise: "S.A.S. ENVIE 2E NORD",
  typeContrat: "CDD",
  dateEmbauche: "2024-05-11",
  dateSortiePrevue: "2026-09-30",
  dateRetraite: "2026-10-01",
  poste: "Agent polyvalent",
  dateDocument: "2026-08-11",
  lieuDocument: "Lesquin",
};

function request(body: unknown) {
  return new Request("http://localhost/api/impressions/attestation-retraite/pdf", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify(body),
  });
}

describe("Unit — /api/impressions/attestation-retraite/pdf", () => {
  beforeEach(() => {
    vi.resetAllMocks();
    requirePermissionMock.mockResolvedValue({ ok: true, access: {} });
    employeeScopeFromAccessMock.mockReturnValue({ sectors: undefined });
    buildDraftMock.mockResolvedValue(data);
    renderPdfMock.mockResolvedValue(Buffer.from("%PDF-test"));
  });

  it("requires the impressions permission", async () => {
    requirePermissionMock.mockResolvedValue({
      ok: false,
      response: Response.json({ message: "Forbidden" }, { status: 403 }),
    });

    const response = await POST(request({ cos: 123, signataireId: 7, data }));

    expect(response.status).toBe(403);
    expect(renderPdfMock).not.toHaveBeenCalled();
  });

  it("rejects a missing retirement date", async () => {
    const response = await POST(
      request({ cos: 123, signataireId: 7, data: { ...data, dateRetraite: "" } }),
    );

    expect(response.status).toBe(422);
    expect(renderPdfMock).not.toHaveBeenCalled();
  });

  it("returns the generated retirement PDF", async () => {
    const response = await POST(request({ cos: 123, signataireId: 7, data }));

    expect(response.status).toBe(200);
    expect(response.headers.get("content-type")).toBe("application/pdf");
    expect(response.headers.get("content-disposition")).toBe(
      'inline; filename="attestation-retraite-123.pdf"',
    );
    expect(buildDraftMock).toHaveBeenCalledWith(123, 7, {
      sectors: undefined,
    });
    expect(renderPdfMock).toHaveBeenCalledWith(data);
  });
});
