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

const {
  requireSuperAdminMock,
  exportAdminTableRowsMock,
  exportActiveEmployeesWithContractsMock,
} = vi.hoisted(() => ({
  requireSuperAdminMock: vi.fn(),
  exportAdminTableRowsMock: vi.fn(),
  exportActiveEmployeesWithContractsMock: vi.fn(),
}));

vi.mock("@/lib/authorization", () => ({
  requireSuperAdmin: requireSuperAdminMock,
}));

vi.mock("@/services/admin-tables.service", () => ({
  exportAdminTableRows: exportAdminTableRowsMock,
  exportActiveEmployeesWithContracts: exportActiveEmployeesWithContractsMock,
}));

import { GET as exportTable } from "@/app/api/admin/tables/[table]/export/route";
import { GET as exportActiveEmployees } from "@/app/api/admin/exports/employes-contrats-actifs/route";

describe("Admin CSV export routes", () => {
  beforeEach(() => {
    vi.resetAllMocks();
    requireSuperAdminMock.mockResolvedValue({ ok: true });
  });

  it("exports every value of the selected table", async () => {
    exportAdminTableRowsMock.mockResolvedValue({
      columns: ["id", "libelle"],
      rows: [{ id: 1, libelle: "Valeur" }],
    });

    const response = await exportTable(
      new Request("http://localhost/api/admin/tables/secteurs/export"),
      { params: Promise.resolve({ table: "secteurs" }) },
    );

    expect(response.status).toBe(200);
    expect(exportAdminTableRowsMock).toHaveBeenCalledWith("secteurs");
    expect(response.headers.get("content-disposition")).toContain(
      "secteurs-",
    );
    expect(await response.text()).toContain('"1";"Valeur"');
  });

  it("refuses the generic export of a protected table", async () => {
    exportAdminTableRowsMock.mockRejectedValue(new Error("PROTECTED_TABLE"));

    const response = await exportTable(
      new Request("http://localhost/api/admin/tables/auth_users/export"),
      { params: Promise.resolve({ table: "auth_users" }) },
    );

    expect(response.status).toBe(403);
  });

  it("exports active employees with their current contract", async () => {
    exportActiveEmployeesWithContractsMock.mockResolvedValue({
      columns: ["employe_COS", "contrat_ID_Contrat"],
      rows: [{ employe_COS: 12, contrat_ID_Contrat: 34 }],
    });

    const response = await exportActiveEmployees(
      new Request(
        "http://localhost/api/admin/exports/employes-contrats-actifs",
      ),
    );

    expect(response.status).toBe(200);
    expect(exportActiveEmployeesWithContractsMock).toHaveBeenCalledOnce();
    expect(response.headers.get("content-disposition")).toContain(
      "salaries-contrats-actifs-",
    );
    expect(await response.text()).toContain('"12";"34"');
  });

  it("does not export anything for a non-super-admin", async () => {
    requireSuperAdminMock.mockResolvedValue({
      ok: false,
      response: new Response("Forbidden", { status: 403 }),
    });

    const response = await exportActiveEmployees(
      new Request(
        "http://localhost/api/admin/exports/employes-contrats-actifs",
      ),
    );

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