/**
 * Stripe Server Configuration
 * Server-side Stripe instance for API routes
 */

import Stripe from "stripe";

const stripeSecretKey = process.env.STRIPE_SECRET_KEY;

// Create Stripe instance only if key is available
// This prevents build errors when key is not set
let stripe: Stripe | null = null;
const stripeBySecretKey = new Map<string, Stripe>();

if (stripeSecretKey) {
  stripe = new Stripe(stripeSecretKey, {
    apiVersion: "2026-02-25.clover",
    typescript: true,
  });
}

/**
 * Get Stripe instance (throws if not configured)
 */
export function getStripe(): Stripe {
  if (!stripe) {
    throw new Error(
      "Stripe is not configured. Please set STRIPE_SECRET_KEY environment variable."
    );
  }
  return stripe;
}

export function getStripeForSecretKey(secretKey?: string): Stripe {
  const key = secretKey || stripeSecretKey;
  if (!key) {
    throw new Error("Stripe is not configured. Missing secret key.");
  }

  const cached = stripeBySecretKey.get(key);
  if (cached) return cached;

  const instance = new Stripe(key, {
    apiVersion: "2026-02-25.clover",
    typescript: true,
  });
  stripeBySecretKey.set(key, instance);
  return instance;
}

export function isStripeSecretKeyConfigured(secretKey?: string): boolean {
  return Boolean(secretKey || stripeSecretKey);
}

// Currencies Stripe treats as having no minor unit — the amount is charged in
// whole units, so it must NOT be multiplied by 100. Charging UGX/JPY with a
// blanket *100 overcharges the customer 100x.
const STRIPE_ZERO_DECIMAL_CURRENCIES = new Set([
  "BIF", "CLP", "DJF", "GNF", "JPY", "KMF", "KRW", "MGA", "PYG", "RWF",
  "UGX", "VND", "VUV", "XAF", "XOF", "XPF",
]);

// Stripe requires three-decimal currency amounts to be a multiple of 10 in the
// smallest unit (i.e. the last digit is always 0).
const STRIPE_THREE_DECIMAL_CURRENCIES = new Set([
  "BHD", "IQD", "JOD", "KWD", "LYD", "OMR", "TND",
]);

/**
 * Convert a major-unit amount (e.g. dollars) into the smallest unit Stripe
 * expects for the given currency. Handles zero-decimal (UGX, JPY, …) and
 * three-decimal (KWD, BHD, …) currencies instead of assuming ×100.
 */
export function toStripeAmount(amount: number, currency: string): number {
  const normalized = (currency || "USD").trim().toUpperCase();
  const value = Number(amount || 0);
  if (STRIPE_ZERO_DECIMAL_CURRENCIES.has(normalized)) {
    return Math.round(value);
  }
  if (STRIPE_THREE_DECIMAL_CURRENCIES.has(normalized)) {
    return Math.round((value * 1000) / 10) * 10;
  }
  return Math.round(value * 100);
}

/**
 * Check if Stripe is configured
 */
export function isStripeConfigured(): boolean {
  return !!stripeSecretKey;
}

/**
 * Get Stripe publishable key for client
 */
export function getStripePublishableKey(): string {
  return process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || "";
}

// Export stripe for direct usage (may be null)
export { stripe };
