import { fromUnitToToken } from '@ocap/util';
import type { TPaymentCurrency } from '@blocklet/payment-types';

export { primaryContrastColor } from '../../libs/util';

// Interval key → locale key mapping
export const INTERVAL_LOCALE_KEY: Record<string, string> = {
  day: 'common.daily',
  week: 'common.weekly',
  month: 'common.monthly',
  year: 'common.yearly',
};

// Convert ISO2 country code to flag emoji (e.g., "us" → "🇺🇸")
export function countryCodeToFlag(code: string): string {
  if (!code || code.length !== 2) return '';
  return String.fromCodePoint(
    ...code
      .toUpperCase()
      .split('')
      .map((c) => 127397 + c.charCodeAt(0))
  );
}

export function formatTokenAmount(unitAmount: string | number | bigint, currency: TPaymentCurrency | null): string {
  if (!unitAmount || !currency) return '0';
  try {
    const tokenAmount = fromUnitToToken(String(unitAmount), currency.decimal || 0);
    const num = Number(tokenAmount);
    if (!Number.isFinite(num)) return '0';
    const abs = Math.abs(num);
    const precision = abs > 0 && abs < 0.01 ? 6 : 2;
    const formatted = num.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: precision });
    return formatted.replace(/(\.\d*?)0+$/, '$1').replace(/\.$/, '') || '0';
  } catch {
    return '0';
  }
}

interface CurrencyOption {
  currency_id: string;
  unit_amount: string;
  custom_unit_amount?: { preset?: string; presets?: string[] } | null;
}

interface PriceWithDynamic {
  pricing_type?: string;
  base_amount?: string;
  unit_amount?: string;
  base_currency?: string;
  currency_id?: string;
  currency_options?: CurrencyOption[];
  price_currency_options?: CurrencyOption[];
}

// Get the unit_amount for a specific currency, checking currency_options first
export function getUnitAmountForCurrency(
  price: PriceWithDynamic | null | undefined,
  currency: TPaymentCurrency | null
): string {
  if (!price || !currency) return '0';
  const options = price.price_currency_options || price.currency_options || [];
  const option = options.find((x) => x.currency_id === currency.id);
  if (option) {
    if (option.custom_unit_amount) {
      return option.custom_unit_amount.preset || option.custom_unit_amount.presets?.[0] || option.unit_amount;
    }
    return option.unit_amount;
  }
  if (price.currency_id === currency.id) {
    return price.unit_amount || '0';
  }
  return '0';
}

// Format price with exchange rate for dynamic pricing
export function formatDynamicUnitPrice(
  price: PriceWithDynamic | null | undefined,
  currency: TPaymentCurrency | null,
  exchangeRate: string | null
): string | null {
  if (!price || !currency) return null;
  const isDynamic = price.pricing_type === 'dynamic';
  if (isDynamic && exchangeRate && price.base_amount) {
    const rate = Number(exchangeRate);
    if (rate > 0 && Number.isFinite(rate)) {
      const baseUsd = Number(price.base_amount);
      if (baseUsd > 0 && Number.isFinite(baseUsd)) {
        const tokenAmount = baseUsd / rate;
        const abs = Math.abs(tokenAmount);
        const precision = abs > 0 && abs < 0.01 ? 6 : 2;
        return (
          tokenAmount
            .toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: precision })
            .replace(/(\.\d*?)0+$/, '$1')
            .replace(/\.$/, '') || '0'
        );
      }
    }
  }
  // Fiat/Stripe fallback: use base_amount when no exchange rate
  // (unit_amount may be in crypto denomination, not fiat cents)
  if (!exchangeRate && price.base_amount != null) {
    const baseUsd = Number(price.base_amount);
    if (baseUsd >= 0 && Number.isFinite(baseUsd)) {
      return baseUsd.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }
  }
  // Fallback: look up unit_amount from currency_options for the selected currency
  return formatTokenAmount(getUnitAmountForCurrency(price, currency), currency);
}

// Safe translation with fallback for missing keys (returns fallback if t() returns the raw key path)
export function tSafe(t: (key: string, params?: any) => string, key: string, fallback: string): string {
  const v = t(key);
  return v && !v.includes('.') ? v : fallback;
}

// Shared white tooltip style for checkout-v2
export const whiteTooltipSx = {
  '& .MuiTooltip-tooltip': {
    bgcolor: 'background.paper',
    color: 'text.primary',
    border: '1px solid',
    borderColor: 'divider',
    borderRadius: '10px',
    boxShadow: '0 8px 24px rgba(0,0,0,0.12)',
    p: 1.5,
    maxWidth: 280,
    fontSize: 12,
  },
  '& .MuiTooltip-arrow': {
    color: 'background.paper',
    '&::before': { border: '1px solid', borderColor: 'divider' },
  },
};

// Helper: format trial text
export function formatTrialText(
  t: (key: string, params?: Record<string, any>) => string,
  days: number,
  interval: string
): string {
  const key = interval || 'day';
  const intervalKey = days > 1 ? `common.${key}s` : `common.${key}`;
  return t('payment.checkout.free', { count: days, interval: t(intervalKey) });
}

// ── Item meta: badge / title / subtitle for the header area ──

type TFn = (key: string, params?: Record<string, any>) => string;

export type ItemTypeBadge = 'subscription' | 'topup' | 'oneTime';

interface ItemMeta {
  badge: ItemTypeBadge;
  badgeLabel: string;
  title: string;
  subtitle: string;
}

/**
 * Derive structured badge / title / subtitle for a checkout session header.
 * Works for the "primary product" header above the item list.
 */
export function getSessionHeaderMeta(t: TFn, session: any, product: any, items: any[]): ItemMeta {
  const mode = session?.mode || 'payment';
  const isSubscription = ['subscription', 'setup'].includes(mode);
  const isCreditTopup =
    items.length === 1 &&
    mode === 'payment' &&
    items[0]?.price?.product?.type === 'credit' &&
    items[0]?.price?.metadata?.credit_config;

  // Badge
  let badge: ItemTypeBadge;
  if (isCreditTopup) {
    badge = 'topup';
  } else if (isSubscription) {
    badge = 'subscription';
  } else {
    badge = 'oneTime';
  }
  const badgeLabel = t(`payment.checkout.typeBadge.${badge}`);

  // Title: action + product name based on type
  const productName = product?.name || items[0]?.price?.product?.name || '';
  let title = productName;
  if (productName) {
    if (isSubscription) {
      title = t('payment.checkout.headerTitle.subscribe', { name: productName });
    } else if (!isCreditTopup) {
      title = t('payment.checkout.headerTitle.purchase', { name: productName });
    }
  }

  // Subtitle: system-generated, not product.description
  let subtitle = '';
  if (isCreditTopup) {
    subtitle = t('payment.checkout.subtitle.creditsTopup');
  } else if (isSubscription) {
    // Use plan name if available; skip generic interval labels like "daily subscription"
    const planName = product?.metadata?.plan_name || product?.metadata?.plan_display_name;
    if (planName) {
      subtitle = planName;
    }
  } else {
    subtitle = t('payment.checkout.subtitle.oneTime');
  }

  return { badge, badgeLabel, title, subtitle };
}
