import React, { createContext, useContext, useState, useCallback, useEffect, useMemo } from 'react';
import type { CurrencyCode, Currency } from '@/types';

export const currencies: Currency[] = [
  { code: 'XOF', name: 'Franc CFA BCEAO', symbol: 'FCFA', flag: '🇸🇳' },
  { code: 'EUR', name: 'Euro', symbol: '€', flag: '🇪🇺' },
  { code: 'USD', name: 'Dollar US', symbol: '$', flag: '🇺🇸' },
  { code: 'GBP', name: 'Livre Sterling', symbol: '£', flag: '🇬🇧' }
];

// Taux de change de base (XOF)
const exchangeRates: Record<CurrencyCode, Record<CurrencyCode, number>> = {
  XOF: { XOF: 1, EUR: 0.00152, USD: 0.00165, GBP: 0.00129 },
  EUR: { XOF: 657.89, EUR: 1, USD: 1.09, GBP: 0.85 },
  USD: { XOF: 606.06, EUR: 0.92, USD: 1, GBP: 0.78 },
  GBP: { XOF: 775.19, EUR: 1.18, USD: 1.28, GBP: 1 }
};

interface CurrencyContextType {
  currentCurrency: CurrencyCode;
  setCurrency: (currency: CurrencyCode) => void;
  convertPrice: (priceXOF: number) => number;
  formatPrice: (price: number, currency?: CurrencyCode) => string;
  getCurrencySymbol: (currency?: CurrencyCode) => string;
  getCurrencyFlag: (currency?: CurrencyCode) => string;
  currencies: Currency[];
}

const CurrencyContext = createContext<CurrencyContextType | undefined>(undefined);

const STORAGE_KEY = 'zlo_fbo_currency';

export function CurrencyProvider({ children }: { children: React.ReactNode }) {
  const [currentCurrency, setCurrentCurrency] = useState<CurrencyCode>(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem(STORAGE_KEY) as CurrencyCode;
      if (saved && currencies.find(c => c.code === saved)) {
        return saved;
      }
    }
    return 'XOF';
  });

  useEffect(() => {
    localStorage.setItem(STORAGE_KEY, currentCurrency);
  }, [currentCurrency]);

  const setCurrency = useCallback((currency: CurrencyCode) => {
    if (currencies.find(c => c.code === currency)) {
      setCurrentCurrency(currency);
    }
  }, []);

  const convertPrice = useCallback((priceXOF: number): number => {
    const rate = exchangeRates.XOF[currentCurrency];
    return Math.round(priceXOF * rate * 100) / 100;
  }, [currentCurrency]);

  const formatPrice = useCallback((price: number, currency?: CurrencyCode): string => {
    const curr = currency || currentCurrency;
    const currencyInfo = currencies.find(c => c.code === curr);
    if (!currencyInfo) return `${price}`;

    const formattedPrice = new Intl.NumberFormat('fr-FR', {
      minimumFractionDigits: curr === 'XOF' ? 0 : 2,
      maximumFractionDigits: curr === 'XOF' ? 0 : 2
    }).format(price);

    return `${formattedPrice} ${currencyInfo.symbol}`;
  }, [currentCurrency]);

  const getCurrencySymbol = useCallback((currency?: CurrencyCode): string => {
    const curr = currency || currentCurrency;
    const currencyInfo = currencies.find(c => c.code === curr);
    return currencyInfo?.symbol || '';
  }, [currentCurrency]);

  const getCurrencyFlag = useCallback((currency?: CurrencyCode): string => {
    const curr = currency || currentCurrency;
    const currencyInfo = currencies.find(c => c.code === curr);
    return currencyInfo?.flag || '';
  }, [currentCurrency]);

  const value = useMemo(() => ({
    currentCurrency,
    setCurrency,
    convertPrice,
    formatPrice,
    getCurrencySymbol,
    getCurrencyFlag,
    currencies
  }), [currentCurrency, setCurrency, convertPrice, formatPrice, getCurrencySymbol, getCurrencyFlag]);

  return (
    <CurrencyContext.Provider value={value}>
      {children}
    </CurrencyContext.Provider>
  );
}

export function useCurrency() {
  const context = useContext(CurrencyContext);
  if (context === undefined) {
    throw new Error('useCurrency must be used within a CurrencyProvider');
  }
  return context;
}

// Hook utilitaire pour formater les prix directement
export function usePriceFormatter() {
  const { formatPrice, convertPrice } = useCurrency();
  
  return useCallback((priceXOF: number): string => {
    const converted = convertPrice(priceXOF);
    return formatPrice(converted);
  }, [formatPrice, convertPrice]);
}
