import { describe, it, expect, beforeEach, vi } from "vitest";
import { POST } from "@/app/api/stripe/webhook/route";
import { db } from "@/lib/db";
import { stripe } from "@/lib/stripe";

vi.mock("@/lib/db", () => ({
  db: {
    user: { findUnique: vi.fn(), update: vi.fn() },
  },
}));

vi.mock("@/lib/stripe", () => ({
  stripe: {
    webhooks: { constructEvent: vi.fn() },
  },
}));

vi.mock("@/lib/logger", () => ({
  logger: { info: vi.fn(), error: vi.fn(), warn: vi.fn() },
}));

describe("POST /api/stripe/webhook - marketplace credits checkout.session.completed", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.stubEnv("STRIPE_WEBHOOK_SECRET", "whsec_test");
    vi.mocked(db.user.findUnique).mockResolvedValue({
      id: "user_1",
      marketplaceCreditsCents: 0,
    } as never);
    vi.mocked(db.user.update).mockResolvedValue({} as never);
  });

  it("increments user marketplaceCreditsCents when checkout.session.completed (payment, marketplace_credits)", async () => {
    const session = {
      id: "cs_1",
      mode: "payment",
      metadata: {
        userId: "user_1",
        type: "marketplace_credits",
        amount_cents: "10000",
      },
    };
    const event = {
      id: "evt_credits_1",
      type: "checkout.session.completed",
      data: { object: session },
    };
    vi.mocked(stripe!.webhooks.constructEvent).mockReturnValue(event as never);

    const res = await POST(
      new Request("http://localhost/api/stripe/webhook", {
        method: "POST",
        body: JSON.stringify(event),
        headers: { "stripe-signature": "valid_sig" },
      }),
    );

    expect(res.status).toBe(200);
    expect(db.user.findUnique).toHaveBeenCalledWith({
      where: { id: "user_1" },
      select: { id: true, marketplaceCreditsCents: true },
    });
    expect(db.user.update).toHaveBeenCalledWith({
      where: { id: "user_1" },
      data: { marketplaceCreditsCents: { increment: 10000 } },
    });
  });
});
