/**
 * Billing / credit constants for Songs2VID hybrid pricing.
 * Plan enum in DB: FREE | PREMIUM (Pro = €5/mo "starter_5eur").
 */

export const CREDIT_CURRENCY = "eur";

/** Free monthly allocation */
export const FREE_MONTHLY_CREDITS = 10;

/** Pro monthly allocation */
export const PRO_MONTHLY_CREDITS = 50;

/** Free-tier top-up: buyer picks 1–15 credits */
export const FREE_TOP_UP_MIN = 1;
export const FREE_TOP_UP_MAX = 15;

/** €0.25 per extra credit */
export const CREDIT_PRICE_CENTS = 25;

/** @deprecated use FREE_TOP_UP_MAX */
export const FREE_TOP_UP_CREDITS = FREE_TOP_UP_MAX;

/** @deprecated use creditPurchaseTotalCents(FREE_TOP_UP_MAX) */
export const FREE_TOP_UP_PRICE_CENTS = FREE_TOP_UP_MAX * CREDIT_PRICE_CENTS;

/** Pro subscription €5 / month */
export const PRO_PRICE_CENTS = 500;

/** Soft cap on never-expiring extra credits (Pro / legacy storage bound) */
export const EXTRA_CREDITS_MAX = 1000;

/**
 * Hard cap on total accumulated credits (monthly remaining + extras).
 * On renewal, unused + new monthly is trimmed to this threshold.
 */
export const MAX_CREDIT_CAP = 30;

/**
 * Free plan: extras balance cannot exceed 15.
 * After monthly (10) + extras (≤15) are used, upgrade to Pro is required.
 */
export const FREE_EXTRA_CREDITS_MAX = FREE_TOP_UP_MAX;

/** Stripe Tax / Managed Payments  SaaS personal use */
export const STRIPE_PRODUCT_TAX_CODE = "txcd_10103000";

export const CREDIT_PURCHASE_MIN = FREE_TOP_UP_MIN;
export const CREDIT_PURCHASE_MAX = FREE_TOP_UP_MAX;
export const CREDIT_BALANCE_MAX = EXTRA_CREDITS_MAX;

/** Shown in quota UI errors so UpgradeProLink can attach a CTA */
export const PRO_UPGRADE_REQUIRED_SUFFIX = " Upload up to 50 videos with Pro!";

export function monthlyCreditsForPlan(plan: "FREE" | "PREMIUM"): number {
  return plan === "PREMIUM" ? PRO_MONTHLY_CREDITS : FREE_MONTHLY_CREDITS;
}

export function freeExtraCreditsCap(): number {
  return FREE_EXTRA_CREDITS_MAX;
}

export function formatEuroFromCents(cents: number): string {
  const amount = cents / 100;
  const formatted = amount % 1 === 0 ? String(amount) : amount.toFixed(2);
  return `€${formatted}`;
}

export function creditPurchaseTotalCents(credits: number): number {
  return credits * CREDIT_PRICE_CENTS;
}

export function formatCreditPrice(credits = 1): string {
  return formatEuroFromCents(creditPurchaseTotalCents(credits));
}

export function validateFreeTopUpAmount(
  credits: number,
  currentExtraBalance: number,
  monthlyRemaining = 0,
): { ok: true; credits: number; amountCents: number } | { ok: false; error: string } {
  if (!Number.isInteger(credits)) {
    return { ok: false, error: "Credit amount must be a whole number." };
  }
  if (credits < FREE_TOP_UP_MIN || credits > FREE_TOP_UP_MAX) {
    return {
      ok: false,
      error: `You can buy between ${FREE_TOP_UP_MIN} and ${FREE_TOP_UP_MAX} credits per top-up.`,
    };
  }
  if (currentExtraBalance >= FREE_EXTRA_CREDITS_MAX) {
    return {
      ok: false,
      error: `Free plan extras are capped at ${FREE_EXTRA_CREDITS_MAX}. Upgrade to Pro for 50 videos every month.${PRO_UPGRADE_REQUIRED_SUFFIX}`,
    };
  }
  const freeExtraRoom = FREE_EXTRA_CREDITS_MAX - currentExtraBalance;
  const totalRoom = Math.max(0, MAX_CREDIT_CAP - monthlyRemaining - currentExtraBalance);
  const room = Math.min(freeExtraRoom, totalRoom);
  if (room <= 0) {
    return {
      ok: false,
      error: `Your total credit balance cannot exceed ${MAX_CREDIT_CAP}. Upgrade to Pro or use existing credits first.${PRO_UPGRADE_REQUIRED_SUFFIX}`,
    };
  }
  if (credits > room) {
    return {
      ok: false,
      error: `You can buy up to ${room} more credits under the ${MAX_CREDIT_CAP}-credit account cap.`,
    };
  }
  return { ok: true, credits, amountCents: creditPurchaseTotalCents(credits) };
}
