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: { updateMany: 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 - Connect account.updated", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.stubEnv("STRIPE_WEBHOOK_SECRET", "whsec_platform_test");
  });

  it("calls updateMany to mark onboarding complete when account.updated received", async () => {
    const accountId = "acct_express123";
    const event = {
      id: "evt_connect_1",
      type: "account.updated",
      account: accountId,
      data: { object: { id: accountId } },
    };

    vi.mocked(stripe!.webhooks.constructEvent).mockReturnValue(event as never);
    vi.mocked(db.user.updateMany).mockResolvedValue({ count: 1 });

    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.updateMany).toHaveBeenCalledWith({
      where: { stripeConnectAccountId: accountId },
      data: { stripeConnectOnboardingComplete: true },
    });
  });

  it("returns 400 when signature verification fails", async () => {
    vi.mocked(stripe!.webhooks.constructEvent).mockImplementation(() => {
      throw new Error("Signature verification failed");
    });

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

    expect(res.status).toBe(400);
    expect(db.user.updateMany).not.toHaveBeenCalled();
  });
});
