/**
 * Quotation Stripe Checkout Utilities
 *
 * Shared helpers for Stripe checkout session creation across quotation routes:
 *   - Currency validation & fallback
 *   - Checkout session creation with consistent metadata
 *   - Stripe secret key resolution (org-specific -> platform fallback)
 */

import Stripe from "stripe";
import { convexQuery } from "@/lib/convex-client";
import { logger } from "@/lib/logger";

const log = logger.scope("QuotationCheckout");

// =============================================================================
// Stripe-Supported Currencies
// =============================================================================

/**
 * Comprehensive set of Stripe-supported currencies.
 * Unsupported currencies (OMR, BHD, KWD, etc.) fall back to USD.
 *
 * Source: https://stripe.com/docs/currencies
 */
export const STRIPE_SUPPORTED_CURRENCIES = new Set([
  "usd","aed","afn","all","amd","ang","aoa","ars","aud","awg","azn","bam","bbd",
  "bdt","bgn","bif","bmd","bnd","bob","brl","bsd","bwp","byn","bzd","cad","cdf",
  "chf","clp","cny","cop","crc","cve","czk","djf","dkk","dop","dzd","egp","etb",
  "eur","fjd","fkp","gbp","gel","gip","gmd","gnf","gtq","gyd","hkd","hnl","hrk",
  "htg","huf","idr","ils","inr","isk","jmd","jpy","kes","kgs","khr","kmf","krw",
  "kyd","kzt","lak","lbp","lkr","lrd","lsl","mad","mdl","mga","mkd","mmk","mnt",
  "mop","mur","mvr","mwk","mxn","myr","mzn","nad","ngn","nio","nok","npr","nzd",
  "pab","pen","pgk","php","pkr","pln","pyg","qar","ron","rsd","rub","rwf","sar",
  "sbd","scr","sek","sgd","shp","sle","sos","srd","std","szl","thb","tjs","top",
  "try","ttd","twd","tzs","uah","ugx","uyu","uzs","vnd","vuv","wst","xaf","xcd",
  "xcg","xof","xpf","yer","zar","zmw",
]);

/**
 * Map a currency code to a Stripe-supported currency.
 * Returns the lowercase currency if supported, otherwise falls back to "usd".
 */
export function getStripeCurrency(currency: string): string {
  const lower = currency.toLowerCase();
  return STRIPE_SUPPORTED_CURRENCIES.has(lower) ? lower : "usd";
}

/**
 * Build the currency note appended to the Stripe product name when
 * the quotation currency is converted to a fallback (e.g. OMR -> USD).
 * Returns empty string when no conversion occurs.
 */
export function buildCurrencyNote(
  originalCurrency: string,
  stripeCurrency: string,
  total: number,
): string {
  return stripeCurrency !== originalCurrency.toLowerCase()
    ? ` (${originalCurrency.toUpperCase()} ${total.toFixed(2)})`
    : "";
}

// =============================================================================
// Stripe Secret Key Resolution
// =============================================================================

/**
 * Resolve the Stripe secret key for a user:
 * 1. Check for org-specific encrypted Stripe key
 * 2. Fall back to platform STRIPE_SECRET_KEY env var
 *
 * Returns null if no key is available.
 */
export async function resolveStripeSecretKey(
  userId: string,
): Promise<string | null> {
  // Try org-specific Stripe keys first
  try {
    const orgState = await convexQuery<Record<string, unknown>>(
      "organizations/queries:getOrganizationStateByUserId",
      { userId },
    );
    const org = orgState?.organization as Record<string, unknown> | undefined;
    const stripeSecretKeyEncrypted = org?.stripeSecretKeyEncrypted as
      | string
      | undefined;

    if (stripeSecretKeyEncrypted) {
      const { decryptStripeKey } = await import(
        "@/lib/services/stripe-keys.service"
      );
      return decryptStripeKey(stripeSecretKeyEncrypted);
    }
  } catch (err) {
    log.warn("Failed to resolve org Stripe key, falling back to platform", err);
  }

  // Fall back to platform Stripe key
  return process.env.STRIPE_SECRET_KEY || null;
}

// =============================================================================
// Checkout Session Creation
// =============================================================================

export interface QuotationCheckoutParams {
  /** Stripe secret key to use */
  stripeSecretKey: string;
  /** Quotation ID (Convex _id or Prisma id) */
  quotationId: string;
  /** Human-readable quotation number (e.g. Q-20260324-0001) */
  quotationNumber: string;
  /** Quotation title */
  title: string;
  /** Original currency code (e.g. "QAR", "OMR") */
  currency: string;
  /** Amount to charge (remaining balance) */
  amount: number;
  /** Customer email for Stripe receipt (optional) */
  customerEmail?: string;
  /** Portal token for cancel URL (optional) */
  portalToken?: string;
  /** Base app URL */
  appUrl: string;
}

export interface QuotationCheckoutResult {
  checkoutUrl: string | null;
  sessionId: string;
}

/**
 * Create a Stripe checkout session for quotation payment.
 *
 * Handles currency fallback, product name with currency note,
 * and consistent metadata shape for the webhook handler.
 */
export async function createQuotationCheckoutSession(
  params: QuotationCheckoutParams,
): Promise<QuotationCheckoutResult> {
  const {
    stripeSecretKey,
    quotationId,
    quotationNumber,
    title,
    currency,
    amount,
    customerEmail,
    portalToken,
    appUrl,
  } = params;

  const stripe = new Stripe(stripeSecretKey, {
    apiVersion: "2024-12-18.acacia",
  });

  const originalCurrency = (currency || "QAR").toLowerCase();
  const stripeCurrency = getStripeCurrency(originalCurrency);
  const currencyNote = buildCurrencyNote(currency || "QAR", stripeCurrency, amount);

  const session = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    mode: "payment",
    ...(customerEmail ? { customer_email: customerEmail } : {}),
    line_items: [
      {
        price_data: {
          currency: stripeCurrency,
          product_data: {
            name: `Quotation ${quotationNumber} — ${title || "Payment"}${currencyNote}`,
          },
          unit_amount: Math.round(amount * 100),
        },
        quantity: 1,
      },
    ],
    metadata: {
      quotationId: String(quotationId),
      quotationNumber,
      ...(portalToken ? { portalToken } : {}),
      type: "quotation_payment",
    },
    success_url: `${appUrl}/en/payment/success?type=quotation&id=${quotationId}`,
    cancel_url: portalToken
      ? `${appUrl}/quotation/${portalToken}`
      : `${appUrl}/en/dashboard?tab=quotations`,
  });

  return {
    checkoutUrl: session.url,
    sessionId: session.id,
  };
}
