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

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

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

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

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

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

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

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

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

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

  it("returns 400 when storage path is invalid", async () => {
    requireAdminApiUserMock.mockResolvedValue({ id: "user-1" });
    prismaMock.proposalDocument.findFirst.mockResolvedValue({
      id: "d1",
      fileName: "propuesta.pdf",
      filePath: "../outside.pdf",
      mimeType: "application/pdf",
    });
    readStoredProposalDocumentMock.mockRejectedValue(new Error("PROPOSAL_DOCUMENT_INVALID_PATH"));

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

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