import { render, waitFor } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { PendingSignupCheckout } from "./PendingSignupCheckout";

const mockCreateCheckout = vi.fn();

vi.mock("../hooks/organization", () => ({
  useOrganization: vi.fn(),
}));

vi.mock("../hooks/stripe", () => ({
  useCreateCheckoutSession: () => ({
    mutate: mockCreateCheckout,
  }),
}));

vi.mock("../providers/UserStoreProvider", () => ({
  useMaybeUser: vi.fn(),
}));

describe("PendingSignupCheckout", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    localStorage.clear();
  });

  it("creates checkout for pending solo", async () => {
    const { useOrganization } = await import("../hooks/organization");
    const { useMaybeUser } = await import("../providers/UserStoreProvider");

    vi.mocked(useMaybeUser).mockReturnValue({ id: "user-1" } as never);
    vi.mocked(useOrganization).mockReturnValue({
      isLoading: false,
      data: {
        active_subscription_plan: null,
        is_billing_owner: true,
      },
    } as never);

    localStorage.setItem("pendingBillingCheckoutPlan", "solo");
    render(<PendingSignupCheckout />);

    await waitFor(() => {
      expect(mockCreateCheckout).toHaveBeenCalledWith(
        expect.objectContaining({ plan: "solo" }),
        expect.any(Object)
      );
    });
  });

  it("creates checkout for pending team", async () => {
    const { useOrganization } = await import("../hooks/organization");
    const { useMaybeUser } = await import("../providers/UserStoreProvider");

    vi.mocked(useMaybeUser).mockReturnValue({ id: "user-1" } as never);
    vi.mocked(useOrganization).mockReturnValue({
      isLoading: false,
      data: {
        active_subscription_plan: null,
        is_billing_owner: true,
      },
    } as never);

    localStorage.setItem("pendingBillingCheckoutPlan", "team");
    render(<PendingSignupCheckout />);

    await waitFor(() => {
      expect(mockCreateCheckout).toHaveBeenCalledWith(
        expect.objectContaining({ plan: "team" }),
        expect.any(Object)
      );
    });
  });

  it("clears founder pending checkout when annual plan is already active", async () => {
    const { useOrganization } = await import("../hooks/organization");
    const { useMaybeUser } = await import("../providers/UserStoreProvider");

    vi.mocked(useMaybeUser).mockReturnValue({ id: "user-1" } as never);
    vi.mocked(useOrganization).mockReturnValue({
      isLoading: false,
      data: {
        active_subscription_plan: "annual",
        is_billing_owner: true,
      },
    } as never);

    localStorage.setItem("pendingBillingCheckoutPlan", "founder");
    render(<PendingSignupCheckout />);

    await waitFor(() => {
      expect(localStorage.getItem("pendingBillingCheckoutPlan")).toBeNull();
      expect(mockCreateCheckout).not.toHaveBeenCalled();
    });
  });

  it("clears invalid pending checkout value", async () => {
    const { useOrganization } = await import("../hooks/organization");
    const { useMaybeUser } = await import("../providers/UserStoreProvider");

    vi.mocked(useMaybeUser).mockReturnValue({ id: "user-1" } as never);
    vi.mocked(useOrganization).mockReturnValue({
      isLoading: false,
      data: {
        active_subscription_plan: null,
        is_billing_owner: true,
      },
    } as never);

    localStorage.setItem("pendingBillingCheckoutPlan", "invalid");
    render(<PendingSignupCheckout />);

    await waitFor(() => {
      expect(localStorage.getItem("pendingBillingCheckoutPlan")).toBeNull();
      expect(mockCreateCheckout).not.toHaveBeenCalled();
    });
  });
});
