// lib/api/billingAdminApi.ts
// Admin/superadmin billing calls. Uses the staff token (same keys as the CRM).

const API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3007/api";

function staffToken(): string {
  if (typeof window === "undefined") return "";
  return (
    localStorage.getItem("token") ||
    localStorage.getItem("accessToken") ||
    localStorage.getItem("access_token") ||
    ""
  );
}

async function call<T = any>(
  path: string,
  method: "GET" | "POST" = "GET",
  body?: any,
): Promise<T> {
  const token = staffToken();
  const res = await fetch(`${API_BASE}${path}`, {
    method,
    headers: {
      "Content-Type": "application/json",
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
    ...(body ? { body: JSON.stringify(body) } : {}),
  });
  const json = await res.json().catch(() => ({}));
  if (!res.ok) throw new Error(json?.message || `Error ${res.status}`);
  return json as T;
}

export interface AdminBillingStatus {
  active: boolean;
  status: string;
  plan: string | null;
  is_free?: boolean;
  billing_enabled?: boolean;
  requires_payment?: boolean;
  access_allowed?: boolean;
  current_period_end: string | null;
  price_amount: number | null;
  price_currency: string | null;
  price_interval: string | null;
  currency: string;
}

export const billingAdminApi = {
  /**
   * ALL companies for the billing table.
   * /companies is paginated (default 10) — so we read page 1, then fetch the
   * remaining pages and concat. This is why only 10 showed before.
   */
  getCompanies: async (): Promise<{ id: number; name: string }[]> => {
    const PAGE = 500;
    const first = await call<any>(`/companies?page=1&limit=${PAGE}`, "GET");
    const firstList = Array.isArray(first) ? first : first?.data ?? [];
    const total = first?.total ?? first?.meta?.total ?? firstList.length;
    const totalPages =
      first?.totalPages ??
      first?.meta?.totalPages ??
      Math.max(1, Math.ceil(total / PAGE));

    let all = [...firstList];
    if (totalPages > 1) {
      const rest = await Promise.all(
        Array.from({ length: totalPages - 1 }, (_, i) =>
          call<any>(`/companies?page=${i + 2}&limit=${PAGE}`, "GET").catch(() => null),
        ),
      );
      for (const r of rest) {
        const l = Array.isArray(r) ? r : r?.data ?? [];
        all = all.concat(l);
      }
    }
    return all.map((c: any) => ({ id: c.id, name: c.name || `#${c.id}` }));
  },

  getStatus: (companyId: number) =>
    call<{ success: boolean; data: AdminBillingStatus }>(
      `/companies/${companyId}/billing`,
      "GET",
    ),

  /** amount in MINOR units (50000 = 500.00). interval: year | month | one_time */
  setPrice: (companyId: number, amount: number, currency = "aed", interval = "year") =>
    call(`/companies/${companyId}/billing/set-price`, "POST", { amount, currency, interval }),

  grantFree: (companyId: number) =>
    call(`/companies/${companyId}/billing/grant-free`, "POST"),

  /** Turn the per-company paywall ON — client portal shows the gateway. */
  enableBilling: (companyId: number) =>
    call(`/companies/${companyId}/billing/enable`, "POST"),

  /** Turn the per-company paywall OFF — no gateway shown. */
  disableBilling: (companyId: number) =>
    call(`/companies/${companyId}/billing/disable`, "POST"),

  markPaid: (companyId: number) =>
    call(`/companies/${companyId}/billing/mark-paid`, "POST"),

  revoke: (companyId: number) =>
    call(`/companies/${companyId}/billing/revoke`, "POST"),
};