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

const { requireAdminApiUserMock, readStoredContractDocumentFileMock, prismaMock } = vi.hoisted(() => ({
  requireAdminApiUserMock: vi.fn(),
  readStoredContractDocumentFileMock: vi.fn(),
  prismaMock: {
    contractDocument: {
      findFirst: vi.fn(),
      delete: vi.fn(),
    },
  },
}));

vi.mock("@/lib/auth/admin", () => ({
  requireAdminApiUser: requireAdminApiUserMock,
}));

vi.mock("@/lib/contracts/storage", async () => {
  const actual = await vi.importActual<typeof import("@/lib/contracts/storage")>("@/lib/contracts/storage");
  return {
    ...actual,
    readStoredContractDocumentFile: readStoredContractDocumentFileMock,
  };
});

vi.mock("@/lib/prisma", () => ({
  prisma: prismaMock,
}));

import { GET } from "@/app/api/contracts/[id]/documents/[documentId]/route";

describe("contract document download API security", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("returns 404 for non-owned or missing contract document", async () => {
    requireAdminApiUserMock.mockResolvedValue({ id: "user-1" });
    prismaMock.contractDocument.findFirst.mockResolvedValue(null);

    const response = await GET(new Request("http://localhost/api/contracts/c1/documents/d1"), {
      params: Promise.resolve({ id: "c1", documentId: "d1" }),
    });
    const payload = (await response.json()) as { error?: string };

    expect(response.status).toBe(404);
    expect(payload.error).toContain("Documento no encontrado");
    expect(readStoredContractDocumentFileMock).not.toHaveBeenCalled();
  });

  it("returns 400 when contract storage path is invalid", async () => {
    requireAdminApiUserMock.mockResolvedValue({ id: "user-1" });
    prismaMock.contractDocument.findFirst.mockResolvedValue({
      fileName: "contrato.pdf",
      filePath: "../../escape.pdf",
      mimeType: "application/pdf",
    });
    readStoredContractDocumentFileMock.mockRejectedValue(new Error("CONTRACT_DOCUMENT_INVALID_PATH"));

    const response = await GET(new Request("http://localhost/api/contracts/c1/documents/d1"), {
      params: Promise.resolve({ id: "c1", documentId: "d1" }),
    });
    const payload = (await response.json()) as { error?: string };

    expect(response.status).toBe(400);
    expect(payload.error).toContain("Ruta de almacenamiento invalida");
  });
});
