import { api } from "@/lib/api";
import {
  fetchOrganizationBillingState,
  hasOrganizationBillingAccess,
  isOrganizationBillingQueryEnabled,
  shouldShowInAppBillingPaywall,
  type OrganizationBillingState,
} from "@/hooks/organization";

jest.mock("@/lib/api", () => ({
  api: {
    get: jest.fn(),
  },
}));

jest.mock("@/stores/auth", () => ({
  useAuthStore: jest.fn(),
}));

const mockedApi = api as jest.Mocked<typeof api>;

const baseOrganizationState: OrganizationBillingState = {
  active_subscription_plan: null,
  active_subscription_quantity: 0,
  invites_sent: [],
  is_billing_owner: true,
  is_trial_expired: true,
  members: [],
  organization: {
    id: 1,
    logo_url: null,
    member_count: 1,
    name: "XTablo",
    plan: "solo",
    tablo_count: 0,
  },
  required_plan: "solo",
  required_team_quantity: 1,
  trial_ends_at: "2026-05-16T00:00:00.000Z",
  trial_starts_at: "2026-05-02T00:00:00.000Z",
};

describe("organization billing hook helpers", () => {
  beforeEach(() => {
    mockedApi.get.mockReset();
  });

  it("fetches the organization billing payload with the current bearer token", async () => {
    mockedApi.get.mockResolvedValue({ data: baseOrganizationState });

    const result = await fetchOrganizationBillingState("session-token");

    expect(mockedApi.get).toHaveBeenCalledWith("/api/v1/users/organization", {
      headers: {
        Authorization: "Bearer session-token",
      },
    });
    expect(result).toEqual(baseOrganizationState);
  });

  it("enables the query only when an access token is present", () => {
    expect(isOrganizationBillingQueryEnabled(null)).toBe(false);
    expect(isOrganizationBillingQueryEnabled(undefined)).toBe(false);
    expect(isOrganizationBillingQueryEnabled("token")).toBe(true);
  });

  it("treats active subscriptions and active trials as organization access", () => {
    expect(hasOrganizationBillingAccess(baseOrganizationState)).toBe(false);
    expect(
      hasOrganizationBillingAccess({
        ...baseOrganizationState,
        active_subscription_plan: "annual",
      })
    ).toBe(true);
    expect(
      hasOrganizationBillingAccess({
        ...baseOrganizationState,
        is_trial_expired: false,
      })
    ).toBe(true);
  });

  it("shows the iOS paywall only to unpaid billing owners after the trial expires", () => {
    expect(shouldShowInAppBillingPaywall(baseOrganizationState)).toBe(true);
    expect(
      shouldShowInAppBillingPaywall({
        ...baseOrganizationState,
        is_billing_owner: false,
      })
    ).toBe(false);
    expect(
      shouldShowInAppBillingPaywall({
        ...baseOrganizationState,
        active_subscription_plan: "solo",
      })
    ).toBe(false);
    expect(
      shouldShowInAppBillingPaywall({
        ...baseOrganizationState,
        is_trial_expired: false,
      })
    ).toBe(false);
  });
});
