import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { api } from "@/lib/api";

/** Identique au type côté API (`OrgSubscriptionState`). */
export type PlanKey = "free" | "pro" | "business";
export type BillingCycle = "monthly" | "yearly";

export type SubscriptionState = {
  plan: PlanKey;
  caps: {
    activeInvoicesLimit: number | null;
    seatsLimit: number | null;
    multiUsers: boolean;
    replyFromUserEmail: boolean;
    smsEnabled: boolean;
  };
  activeInvoicesCount: number;
  inGracePeriod: boolean;
  gracePeriodEndsAt: string | null;
  subscriptionStatus: string | null;
  billingCycle: BillingCycle | null;
  currentPeriodEnd: string | null;
  hasStripeCustomer: boolean;
  /** L'user a annulé : sub reste active jusqu'à currentPeriodEnd puis Free. */
  cancelAtPeriodEnd: boolean;
};

/** Lit l'état de l'abonnement courant. */
export function useSubscription() {
  return useQuery({
    queryKey: ["billing", "subscription"] as const,
    queryFn: () =>
      api.get<SubscriptionState>("/api/v1/billing/subscription"),
    staleTime: 30_000,
  });
}

/**
 * Lance le checkout Stripe pour upgrader vers Pro / Business.
 * Renvoie l'URL hostée Stripe — le caller doit `window.location.href = url`.
 */
export function useStartCheckout() {
  return useMutation({
    mutationFn: ({ plan, cycle }: { plan: "pro" | "business"; cycle: BillingCycle }) =>
      api.post<{ url: string }>("/api/v1/billing/checkout", { plan, cycle }),
  });
}

/**
 * Ouvre le Customer Portal Stripe pour gérer abonnement / CB / annuler.
 * Disponible seulement si l'org a déjà un Stripe customer.
 */
export function useOpenPortal() {
  return useMutation({
    mutationFn: () => api.post<{ url: string }>("/api/v1/billing/portal"),
  });
}

/**
 * Réactive une souscription annulée (cancel_at_period_end=true → false).
 * Pas de paiement immédiat — le sub continue son cycle normal.
 */
export function useReactivateSubscription() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => api.post<{ ok: true }>("/api/v1/billing/reactivate"),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ["billing", "subscription"] });
    },
  });
}

/**
 * True si l'org est sur Free, hors grace period, et ≥ limit. Le SPA
 * l'utilise pour afficher un banner "limite atteinte" et bloquer
 * l'upload côté UI avant même de toucher l'API.
 */
export function useIsAtFreeLimit(): boolean {
  const { data: state } = useSubscription();
  if (!state) return false;
  if (state.plan !== "free") return false;
  if (state.inGracePeriod) return false;
  const limit = state.caps.activeInvoicesLimit;
  if (limit === null) return false;
  return state.activeInvoicesCount >= limit;
}
