import { create } from 'zustand';
import { persist } from 'zustand/middleware';

// ── Currency config ───────────────────────────────────────────────────────────

export type CurrencyCode = 'USD' | 'AED' | 'INR';

export interface CurrencyOption {
  code: CurrencyCode;
  label: string;
  symbol: string;
  locale: string;
  flag: string;
}

export const CURRENCY_OPTIONS: CurrencyOption[] = [
  { code: 'USD', label: 'US Dollar',       symbol: '$',   locale: 'en-US', flag: '🇺🇸' },
  { code: 'AED', label: 'UAE Dirham',      symbol: 'AED', locale: 'en-AE', flag: '🇦🇪' },
  { code: 'INR', label: 'Indian Rupee',    symbol: '₹',   locale: 'en-IN', flag: '🇮🇳' },
];

// ── Store ─────────────────────────────────────────────────────────────────────

interface CurrencyState {
  currency: CurrencyCode;
  setCurrency: (code: CurrencyCode) => void;

  /** Format a numeric amount with the active currency */
  formatAmount: (amount: number, options?: { compact?: boolean }) => string;

  /** Format a text string containing currency prefixes (e.g. AED 15M -> $ 15M) */
  formatText: (text: string) => string;

  /** Active currency option object */
  option: () => CurrencyOption;
}

export const useCurrencyStore = create<CurrencyState>()(
  persist(
    (set, get) => ({
      currency: 'USD',

      setCurrency: (code) => set({ currency: code }),

      option: () =>
        CURRENCY_OPTIONS.find((o) => o.code === get().currency) ?? CURRENCY_OPTIONS[0],

      formatAmount: (amount, opts) => {
        const { currency, option } = get();
        const { locale } = option();

        // Base assumption: inventory and campaign amounts are stored in AED.
        let convertedAmount = amount;
        if (currency === 'USD') convertedAmount = amount * 0.272; // AED -> USD
        if (currency === 'INR') convertedAmount = amount * 25.135112; // AED -> INR (0.272 * 92.4085)

        if (opts?.compact) {
          // Compact notation: 1.5M, 450K, etc. — prefix with symbol
          const abs = Math.abs(convertedAmount);
          const sign = convertedAmount < 0 ? '-' : '';
          const sym = CURRENCY_OPTIONS.find((o) => o.code === currency)?.symbol ?? currency;
          
          if (currency === 'INR' && abs >= 10_000_000) return `${sign}${sym} ${(abs / 10_000_000).toFixed(1)}Cr`;
          if (abs >= 1_000_000) return `${sign}${sym} ${(abs / 1_000_000).toFixed(1)}M`;
          if (abs >= 1_000)     return `${sign}${sym} ${(abs / 1_000).toFixed(0)}K`;
          return `${sign}${sym} ${abs.toFixed(0)}`;
        }

        return new Intl.NumberFormat(locale, {
          style: 'currency',
          currency,
          minimumFractionDigits: 0,
          maximumFractionDigits: 0,
        }).format(convertedAmount);
      },

      formatText: (text) => {
        const { currency } = get();
        const sym = CURRENCY_OPTIONS.find((o) => o.code === currency)?.symbol ?? currency;
        
        return text.replace(/(AED|INR|\$)\s*([\d\.\-]+)\s*([MKCr]*)\+?/g, (match, prefix, numRange, suffix) => {
          const parts = numRange.split('-');
          const convertedParts = parts.map((p: string) => {
             const parsedNum = parseFloat(p);
             if (isNaN(parsedNum)) return p;
             
             // Step 1: Normalize everything to AED Base
             let baseAed = parsedNum;
             if (prefix === 'INR') baseAed = parsedNum / 25.135112;
             if (prefix === '$')   baseAed = parsedNum / 0.272;
             
             // Step 2: Handle suffixes (Cr -> M mapping)
             let multiplier = 1;
             
             if (suffix === 'Cr') {
                if (currency !== 'INR') {
                   multiplier = 10; // 1 Cr = 10M
                }
             } else if (suffix === 'M') {
                if (currency === 'INR') {
                   multiplier = 0.1; // 10M = 1 Cr
                }
             }

             // Step 3: Convert from AED to Target Currency
             let targetNum = baseAed;
             if (currency === 'USD') targetNum = baseAed * 0.272;
             if (currency === 'INR') targetNum = baseAed * 25.135112;

             targetNum = targetNum * multiplier;
             
             return targetNum >= 10 ? targetNum.toFixed(0) : parseFloat(targetNum.toFixed(1)).toString();
          });
          
          const hasPlus = match.includes('+');
          
          // Determine final output suffix 
          let outSuffix = suffix;
          if (suffix === 'Cr' && currency !== 'INR') outSuffix = 'M';
          if (suffix === 'M' && currency === 'INR') outSuffix = 'Cr';
          
          return `${sym} ${convertedParts.join('-')}${outSuffix}${hasPlus ? '+' : ''}`;
        });
      },
    }),
    {
      name: 'pv-currency',   // localStorage key
      partialize: (state) => ({ currency: state.currency }),
    },
  ),
);

// ── Convenience hook ──────────────────────────────────────────────────────────

/** Use anywhere — returns stable primitives + function refs. No infinite loop. */
export function useCurrency() {
  // Select each piece individually so zustand compares with Object.is on primitives
  const currency     = useCurrencyStore((s) => s.currency);
  const setCurrency  = useCurrencyStore((s) => s.setCurrency);
  const formatAmount = useCurrencyStore((s) => s.formatAmount);
  const formatText   = useCurrencyStore((s) => s.formatText);

  // Derive display values from the stable `currency` string  (no selector object)
  const option = CURRENCY_OPTIONS.find((o) => o.code === currency) ?? CURRENCY_OPTIONS[0];
  const rate = currency === 'USD' ? 0.272 : currency === 'INR' ? 25.135112 : 1;

  return {
    currency,
    symbol:       option.symbol,
    flag:         option.flag,
    label:        option.label,
    option,
    rate,
    formatAmount,
    formatText,
    setCurrency,
  };
}
