import { describe, it, expect, vi, beforeEach } from "vitest";
import { NextRequest } from "next/server";

const mockSession = { user: { id: "user-1" } };

vi.mock("@/lib/api-auth", () => ({
  requireDeveloper: vi.fn(),
}));

const { mockFindFirst, mockSelectChain } = vi.hoisted(() => {
  const mockSelectChain = {
    from: vi.fn().mockReturnThis(),
    where: vi.fn().mockReturnThis(),
    orderBy: vi.fn().mockReturnThis(),
    limit: vi.fn().mockResolvedValue([]),
  };
  return { mockFindFirst: vi.fn(), mockSelectChain };
});

vi.mock("@epicure/db", () => ({
  db: {
    select: vi.fn(() => mockSelectChain),
    query: { webhooks: { findFirst: mockFindFirst } },
  },
  webhooks: { id: "id", userId: "user_id" },
  webhookDeliveries: { webhookId: "webhook_id", createdAt: "created_at" },
  eq: vi.fn((a, b) => ({ a, b, op: "eq" })),
  and: vi.fn((...args) => ({ args, op: "and" })),
  desc: vi.fn((a) => ({ a, op: "desc" })),
}));

const { requireDeveloper } = await import("@/lib/api-auth");
import { GET } from "../route";

const ctx = { params: Promise.resolve({ id: "wh-1" }) };

beforeEach(() => {
  vi.clearAllMocks();
  vi.mocked(requireDeveloper).mockResolvedValue({ session: mockSession as never, response: null });
  mockFindFirst.mockResolvedValue({ id: "wh-1" });
  mockSelectChain.limit.mockResolvedValue([]);
});

describe("GET /api/v1/webhooks/[id]/deliveries", () => {
  it("returns 401 when not authenticated", async () => {
    vi.mocked(requireDeveloper).mockResolvedValue({
      session: null,
      response: new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 }),
    } as never);

    const res = await GET(new NextRequest("http://localhost/api/v1/webhooks/wh-1/deliveries"), ctx);
    expect(res.status).toBe(401);
  });

  it("returns 404 when the webhook does not belong to the caller", async () => {
    mockFindFirst.mockResolvedValue(undefined);
    const res = await GET(new NextRequest("http://localhost/api/v1/webhooks/wh-1/deliveries"), ctx);
    expect(res.status).toBe(404);
  });

  it("returns 200 with the delivery history", async () => {
    mockSelectChain.limit.mockResolvedValue([{ id: "del-1", event: "recipe.created" }]);
    const res = await GET(new NextRequest("http://localhost/api/v1/webhooks/wh-1/deliveries"), ctx);
    expect(res.status).toBe(200);
    const body = await res.json() as unknown[];
    expect(body).toHaveLength(1);
  });
});
