// ═══════════════════════════════════════════════════════════════
//  Aurelle Bride — currency.jsx
//  Full replacement.
//  Load BEFORE components.jsx and app.jsx.
//
//  Auto-detect only:
//  - No dropdown
//  - No manual selector
//  - Silent currency switching
//  - Read-only badge with location tooltip
//
//  Exposes:
//  - window.CurrencyCtx
//  - window.CurrencyProvider
//  - window.useCurrency
//  - window.PriceDisplay
//  - window.CurrencyBadge
//  - window.ShippingNote
//  - window.InlinePrice
//  - window.convertPrice
// ═══════════════════════════════════════════════════════════════

(function () {
  const ReactRef = typeof React !== 'undefined' ? React : null;
  if (!ReactRef) return;

  const {
    useState,
    useEffect,
    useMemo,
    useCallback,
    useContext,
    createContext,
  } = ReactRef;

  // ── Currency metadata ────────────────────────────────────────
  // decimals = display precision for the target currency.
  window.CURRENCY_META = {
    PKR: { symbol: '₨', name: 'Pakistani Rupee', decimals: 0 },
    USD: { symbol: '$', name: 'US Dollar', decimals: 0 },
    GBP: { symbol: '£', name: 'British Pound', decimals: 0 },
    EUR: { symbol: '€', name: 'Euro', decimals: 0 },
    AED: { symbol: 'AED', name: 'UAE Dirham', decimals: 0 },
    SAR: { symbol: 'SAR', name: 'Saudi Riyal', decimals: 0 },
    INR: { symbol: '₹', name: 'Indian Rupee', decimals: 0 },
    CAD: { symbol: 'CA$', name: 'Canadian Dollar', decimals: 0 },
    AUD: { symbol: 'A$', name: 'Australian Dollar', decimals: 0 },
    SGD: { symbol: 'S$', name: 'Singapore Dollar', decimals: 0 },
    QAR: { symbol: 'QAR', name: 'Qatari Riyal', decimals: 0 },
    KWD: { symbol: 'KWD', name: 'Kuwaiti Dinar', decimals: 3 },
    BHD: { symbol: 'BHD', name: 'Bahraini Dinar', decimals: 3 },
    OMR: { symbol: 'OMR', name: 'Omani Rial', decimals: 3 },
    MYR: { symbol: 'RM', name: 'Malaysian Ringgit', decimals: 0 },
    TRY: { symbol: '₺', name: 'Turkish Lira', decimals: 0 },
    BDT: { symbol: '৳', name: 'Bangladeshi Taka', decimals: 0 },
    JPY: { symbol: '¥', name: 'Japanese Yen', decimals: 0 },
    KRW: { symbol: '₩', name: 'South Korean Won', decimals: 0 },
    CNY: { symbol: '¥', name: 'Chinese Yuan', decimals: 0 },
    HKD: { symbol: 'HK$', name: 'Hong Kong Dollar', decimals: 0 },
    NZD: { symbol: 'NZ$', name: 'New Zealand Dollar', decimals: 0 },
    ZAR: { symbol: 'R', name: 'South African Rand', decimals: 0 },
    NGN: { symbol: '₦', name: 'Nigerian Naira', decimals: 0 },
    EGP: { symbol: 'E£', name: 'Egyptian Pound', decimals: 0 },
    ILS: { symbol: '₪', name: 'Israeli Shekel', decimals: 0 },
    MXN: { symbol: 'MX$', name: 'Mexican Peso', decimals: 0 },
    BRL: { symbol: 'R$', name: 'Brazilian Real', decimals: 0 },
    PLN: { symbol: 'zł', name: 'Polish Złoty', decimals: 0 },
    CZK: { symbol: 'Kč', name: 'Czech Koruna', decimals: 0 },
    HUF: { symbol: 'Ft', name: 'Hungarian Forint', decimals: 0 },
  };

  // ── Country → currency map ──────────────────────────────────
  window.COUNTRY_CURRENCY = {
    PK: 'PKR', US: 'USD', GB: 'GBP', AE: 'AED', SA: 'SAR',
    IN: 'INR', CA: 'CAD', AU: 'AUD', SG: 'SGD', QA: 'QAR',
    KW: 'KWD', BH: 'BHD', OM: 'OMR', MY: 'MYR', TR: 'TRY',
    BD: 'BDT', IE: 'EUR', DE: 'EUR', FR: 'EUR', IT: 'EUR',
    ES: 'EUR', NL: 'EUR', BE: 'EUR', AT: 'EUR', PT: 'EUR',
    FI: 'EUR', GR: 'EUR', CH: 'CHF', SE: 'SEK', NO: 'NOK',
    DK: 'DKK', NZ: 'NZD', ZA: 'ZAR', NG: 'NGN', EG: 'EGP',
    IL: 'ILS', MX: 'MXN', BR: 'BRL', PL: 'PLN', CZ: 'CZK',
    HU: 'HUF', JP: 'JPY', KR: 'KRW', CN: 'CNY', HK: 'HKD',
    TH: 'USD', ID: 'USD', PH: 'USD', VN: 'USD', LK: 'USD',
    NP: 'INR', AF: 'USD', IR: 'USD', RU: 'USD', UA: 'USD',
    MY: 'MYR', CL: 'USD', AR: 'USD', CO: 'USD', PE: 'USD',
  };

  const GEO_KEY = 'ab_geo_v2';
  const RATES_KEY = 'ab_rates_v2';
  const GEO_TTL = 1000 * 60 * 60 * 12; // 12 hours
  const RATES_TTL = 1000 * 60 * 60 * 6; // 6 hours
  const GEO_ENDPOINT = '/api/geo.php';
  const PRIMARY_RATES_URL = 'https://open.er-api.com/v6/latest/PKR';
  const FALLBACK_RATES_URL = 'https://api.exchangerate-api.com/v4/latest/PKR';

  const DEFAULT_GEO = {
    currency: 'USD',
    country_code: 'US',
    country_name: 'Unknown',
    city: '',
    detected: false,
    source: 'fallback',
  };

  const DEFAULT_RATES = {
    PKR: 1,
    USD: 0.0036,
    GBP: 0.0028,
    EUR: 0.0033,
    AED: 0.0131,
    SAR: 0.0134,
    INR: 0.30,
    CAD: 0.0049,
    AUD: 0.0055,
    SGD: 0.0048,
    QAR: 0.0130,
    KWD: 0.0011,
    BHD: 0.0013,
    OMR: 0.0014,
    MYR: 0.0167,
    TRY: 0.120,
    BDT: 0.39,
    JPY: 0.55,
    KRW: 4.8,
    CNY: 0.026,
    HKD: 0.028,
    NZD: 0.0060,
    ZAR: 0.064,
    NGN: 5.6,
    EGP: 0.17,
    ILS: 0.013,
    MXN: 0.066,
    BRL: 0.019,
    PLN: 0.014,
    CZK: 0.077,
    HUF: 1.25,
  };

  function now() {
    return Date.now();
  }

  function safeJsonParse(input, fallback = null) {
    try {
      return JSON.parse(input);
    } catch {
      return fallback;
    }
  }

  function safeStorageGet(key) {
    try {
      return sessionStorage.getItem(key);
    } catch {
      return null;
    }
  }

  function safeStorageSet(key, value) {
    try {
      sessionStorage.setItem(key, value);
    } catch {
      // ignore quota / privacy mode errors
    }
  }

  function timeoutSignal(ms) {
    if (typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function') {
      return AbortSignal.timeout(ms);
    }
    const controller = new AbortController();
    setTimeout(() => controller.abort(), ms);
    return controller.signal;
  }

  function isPlainObject(v) {
    return !!v && typeof v === 'object' && !Array.isArray(v);
  }

  function normalizeCode(code) {
    return String(code || '').trim().toUpperCase();
  }

  function formatNumber(amount, decimals) {
    const n = Number(amount);
    if (!Number.isFinite(n)) return '0';
    return n.toLocaleString('en-US', {
      minimumFractionDigits: decimals,
      maximumFractionDigits: decimals,
    });
  }

  function getCurrencyMeta(currencyCode) {
    return window.CURRENCY_META[normalizeCode(currencyCode)] || {
      symbol: normalizeCode(currencyCode) || '$',
      name: normalizeCode(currencyCode) || 'Currency',
      decimals: 0,
    };
  }

  function roundAmount(amount, decimals) {
    const factor = Math.pow(10, decimals);
    return Math.round(Number(amount) * factor) / factor;
  }

  function getBrowserLocaleCurrency() {
    try {
      const locale = navigator.language || (navigator.languages && navigator.languages[0]) || 'en-US';
      const region = locale.includes('-') ? locale.split('-')[1] : '';
      const mapped = window.COUNTRY_CURRENCY[normalizeCode(region)];
      return mapped || null;
    } catch {
      return null;
    }
  }

  function ipFromHeadersObject(value) {
    if (!value) return '';
    return String(value).split(',')[0].trim();
  }

  async function readTextWithTimeout(url, ms) {
    const res = await fetch(url, {
      signal: timeoutSignal(ms),
      credentials: 'omit',
      cache: 'no-store',
    });
    return await res.text();
  }

  async function readJsonWithTimeout(url, ms) {
    const res = await fetch(url, {
      signal: timeoutSignal(ms),
      credentials: 'omit',
      cache: 'no-store',
    });
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return await res.json();
  }

  function buildGeoResult(sourceData) {
    const cc = normalizeCode(sourceData.country_code || sourceData.country || sourceData.loc || 'US') || 'US';
    const currency = normalizeCode(sourceData.currency || window.COUNTRY_CURRENCY[cc] || getBrowserLocaleCurrency() || 'USD');
    const countryName = sourceData.country_name || sourceData.country || cc || 'Unknown';
    const city = sourceData.city || '';

    return {
      currency: currency || 'USD',
      country_code: cc || 'US',
      country_name: countryName || 'Unknown',
      city,
      detected: true,
      source: sourceData.source || 'api',
    };
  }

  async function detectCurrency() {
    // 1) session cache
    const cached = safeJsonParse(safeStorageGet(GEO_KEY), null);
    if (cached && isPlainObject(cached) && cached.currency) {
      if (!cached.ts || now() - cached.ts < GEO_TTL) return cached;
    }

    // 2) backend geo endpoint
    try {
      const data = await readJsonWithTimeout(GEO_ENDPOINT, 4500);
      if (data && data.currency) {
        const result = {
          ...buildGeoResult({
            currency: data.currency,
            country_code: data.country_code,
            country_name: data.country_name,
            city: data.city,
            source: 'server',
          }),
          detected: data.detected !== false,
        };
        safeStorageSet(GEO_KEY, JSON.stringify({ ...result, ts: now() }));
        return result;
      }
    } catch {
      // continue
    }

    // 3) Cloudflare trace fallback (browser-side)
    try {
      const text = await readTextWithTimeout('https://www.cloudflare.com/cdn-cgi/trace', 3500);
      const loc = (text.match(/(?:^|\n)loc=([A-Z]{2})(?:\n|$)/) || [])[1];
      if (loc) {
        const cc = normalizeCode(loc);
        const result = {
          currency: window.COUNTRY_CURRENCY[cc] || 'USD',
          country_code: cc,
          country_name: cc,
          city: '',
          detected: true,
          source: 'cloudflare-trace',
        };
        safeStorageSet(GEO_KEY, JSON.stringify({ ...result, ts: now() }));
        return result;
      }
    } catch {
      // continue
    }

    // 4) browser locale fallback
    const localeCurrency = getBrowserLocaleCurrency();
    if (localeCurrency) {
      const result = {
        currency: localeCurrency,
        country_code: 'US',
        country_name: 'Unknown',
        city: '',
        detected: false,
        source: 'browser-locale',
      };
      safeStorageSet(GEO_KEY, JSON.stringify({ ...result, ts: now() }));
      return result;
    }

    // 5) fallback
    const fallback = { ...DEFAULT_GEO };
    safeStorageSet(GEO_KEY, JSON.stringify({ ...fallback, ts: now() }));
    return fallback;
  }

  async function fetchRates() {
    const cached = safeJsonParse(safeStorageGet(RATES_KEY), null);
    if (cached && isPlainObject(cached) && cached.rates && cached.ts && now() - cached.ts < RATES_TTL) {
      return cached.rates;
    }

    const tryEndpoint = async (url, timeoutMs) => {
      const data = await readJsonWithTimeout(url, timeoutMs);
      if (!data || !data.rates || typeof data.rates !== 'object') throw new Error('No rates');
      return data.rates;
    };

    try {
      const rates = await tryEndpoint(PRIMARY_RATES_URL, 5000);
      safeStorageSet(RATES_KEY, JSON.stringify({ ts: now(), rates }));
      return rates;
    } catch {
      // continue
    }

    try {
      const rates = await tryEndpoint(FALLBACK_RATES_URL, 5000);
      safeStorageSet(RATES_KEY, JSON.stringify({ ts: now(), rates }));
      return rates;
    } catch {
      // continue
    }

    safeStorageSet(RATES_KEY, JSON.stringify({ ts: now(), rates: DEFAULT_RATES }));
    return DEFAULT_RATES;
  }

  function currencyRateFor(rates, code) {
    if (!rates) return null;
    const cc = normalizeCode(code);
    if (cc === 'PKR') return 1;
    const rate = rates[cc];
    if (typeof rate === 'number' && Number.isFinite(rate)) return rate;
    return null;
  }

  function convertPrice(pkrAmount, rate, currencyCode) {
    const value = Number(pkrAmount);
    if (!Number.isFinite(value)) return null;

    const code = normalizeCode(currencyCode || 'PKR');
    const meta = getCurrencyMeta(code);
    const raw = value * Number(rate || 1);

    // For zero-decimal currencies, keep sensible luxury-friendly rounding.
    const decimals = Number.isFinite(meta.decimals) ? meta.decimals : 0;
    const converted = decimals === 0 ? Math.round(raw) : roundAmount(raw, decimals);
    const formatted = formatNumber(converted, decimals);
    return `${meta.symbol} ${formatted}`;
  }

  window.convertPrice = convertPrice;

  const CurrencyCtx = createContext({
    currency: 'USD',
    country_code: 'US',
    country_name: 'Unknown',
    city: '',
    detected: false,
    loading: true,
    rate: null,
    rates: null,
    symbol: '$',
    convert: (pkr) => null,
    format: (pkr) => null,
  });
  window.CurrencyCtx = CurrencyCtx;

  function CurrencyProvider({ children }) {
    const [state, setState] = useState({
      currency: 'USD',
      country_code: 'US',
      country_name: 'Unknown',
      city: '',
      detected: false,
      loading: true,
      rate: null,
      rates: null,
      symbol: '$',
      source: 'fallback',
    });

    useEffect(() => {
      let alive = true;

      (async () => {
        try {
          const [geo, rates] = await Promise.all([detectCurrency(), fetchRates()]);
          if (!alive) return;

          const currency = normalizeCode(geo.currency || 'USD');
          const rate = currencyRateFor(rates, currency) ?? (currency === 'PKR' ? 1 : null) ?? currencyRateFor(rates, 'USD');
          const symbol = getCurrencyMeta(currency).symbol || currency;

          setState({
            currency,
            country_code: normalizeCode(geo.country_code || 'US') || 'US',
            country_name: geo.country_name || 'Unknown',
            city: geo.city || '',
            detected: !!geo.detected,
            loading: false,
            rate,
            rates,
            symbol,
            source: geo.source || 'api',
          });
        } catch {
          if (!alive) return;
          setState({
            currency: 'USD',
            country_code: 'US',
            country_name: 'Unknown',
            city: '',
            detected: false,
            loading: false,
            rate: currencyRateFor(DEFAULT_RATES, 'USD') || 0.0036,
            rates: DEFAULT_RATES,
            symbol: '$',
            source: 'fallback',
          });
        }
      })();

      return () => {
        alive = false;
      };
    }, []);

    const convert = useCallback((pkrAmount) => {
      if (!Number.isFinite(Number(pkrAmount))) return null;
      if (!state.rate) return null;
      return convertPrice(pkrAmount, state.rate, state.currency);
    }, [state.rate, state.currency]);

    const format = useCallback((pkrAmount) => {
      const main = convert(pkrAmount);
      return main || `₨ ${formatNumber(pkrAmount, 0)}`;
    }, [convert]);

    const value = useMemo(() => ({
      ...state,
      convert,
      format,
    }), [state, convert, format]);

    return React.createElement(CurrencyCtx.Provider, { value }, children);
  }

  window.CurrencyProvider = CurrencyProvider;

  function useCurrency() {
    return useContext(CurrencyCtx);
  }
  window.useCurrency = useCurrency;

  function InlinePrice({ pkr, className = '', style, showCurrency = true }) {
    const { loading, currency, rate, convert } = useCurrency();
    const amount = Number(pkr);

    if (!Number.isFinite(amount)) {
      return React.createElement('span', { className, style }, '—');
    }

    const base = `₨ ${formatNumber(amount, 0)}`;
    if (loading || !rate || currency === 'PKR') {
      return React.createElement('span', { className, style }, base);
    }

    const main = convert(amount) || base;
    return React.createElement('span', { className, style }, showCurrency ? main : main.replace(/^\S+\s*/, ''));
  }
  window.InlinePrice = InlinePrice;

  function ShippingNote({ compact = false, style, className = '' }) {
    const { currency } = useCurrency();
    const note = compact
      ? 'Shipping is quoted after confirmation.'
      : 'Shipping is handled separately after confirmation. Please inquire for a custom shipping quote.';

    return React.createElement(
      'div',
      {
        className,
        style: {
          padding: compact ? '10px 12px' : '14px 16px',
          borderRadius: 12,
          border: '1px solid var(--line)',
          background: 'var(--surface-2)',
          color: 'var(--ink-2)',
          ...style,
        },
      },
      React.createElement('div', {
        style: {
          fontFamily: 'var(--mono)',
          fontSize: 10,
          letterSpacing: '.18em',
          textTransform: 'uppercase',
          color: 'var(--ink-3)',
          marginBottom: 6,
        },
      }, 'Shipping'),
      React.createElement('div', { style: { fontSize: compact ? 12 : 13, lineHeight: 1.6 } }, note),
      currency !== 'PKR' && !compact
        ? React.createElement('div', {
            style: {
              marginTop: 8,
              fontFamily: 'var(--mono)',
              fontSize: 10,
              letterSpacing: '.12em',
              color: 'var(--ink-3)',
            },
          }, `Displayed in ${currency} · billed in PKR`)
        : null
    );
  }
  window.ShippingNote = ShippingNote;

  function PriceDisplay({ pkr, style, showPkrSub = true, className = '' }) {
    const { currency, convert, loading, rate } = useCurrency();
    const amount = Number(pkr);

    if (!Number.isFinite(amount)) {
      return React.createElement('span', { style, className }, '—');
    }

    const pkrText = `₨ ${formatNumber(amount, 0)}`;

    if (loading || !rate || currency === 'PKR') {
      return React.createElement('span', { style, className }, pkrText);
    }

    const main = convert(amount);
    if (!main) {
      return React.createElement('span', { style, className }, pkrText);
    }

    return React.createElement(
      'span',
      { style, className },
      React.createElement('span', null, main),
      showPkrSub
        ? React.createElement(
            'span',
            {
              style: {
                display: 'block',
                fontSize: '0.65em',
                color: 'var(--ink-3)',
                fontStyle: 'normal',
                fontFamily: 'var(--mono)',
                letterSpacing: '.04em',
                marginTop: 2,
              },
            },
            `${pkrText} PKR`
          )
        : null
    );
  }
  window.PriceDisplay = PriceDisplay;

  function CurrencyBadge() {
    const { currency, city, country_name, country_code, loading, detected, source } = useCurrency();
    const [open, setOpen] = useState(false);
    const meta = getCurrencyMeta(currency);

    const locationLabel = [city, country_name || country_code].filter(Boolean).join(', ');
    const badgeText = loading ? '···' : currency;

    return React.createElement(
      'div',
      {
        style: {
          position: 'relative',
          display: 'inline-flex',
          alignItems: 'center',
        },
      },
      React.createElement(
        'button',
        {
          type: 'button',
          onMouseEnter: () => setOpen(true),
          onMouseLeave: () => setOpen(false),
          onFocus: () => setOpen(true),
          onBlur: () => setOpen(false),
          'aria-label': loading ? 'Detecting location' : `Detected currency ${currency}`,
          style: {
            display: 'inline-flex',
            alignItems: 'center',
            gap: 8,
            padding: '7px 12px',
            borderRadius: 999,
            border: '1px solid var(--line)',
            background: 'transparent',
            color: loading ? 'var(--ink-3)' : 'var(--ink)',
            fontFamily: 'var(--mono)',
            fontSize: 11,
            letterSpacing: '.18em',
            textTransform: 'uppercase',
            cursor: 'default',
            transition: 'border-color .2s, color .2s, background .2s',
            whiteSpace: 'nowrap',
          },
        },
        loading
          ? React.createElement('span', {
              style: {
                width: 6,
                height: 6,
                borderRadius: '50%',
                background: 'var(--gold)',
                animation: 'abPulse 1.2s ease-in-out infinite',
              },
            })
          : React.createElement('span', {
              style: {
                width: 6,
                height: 6,
                borderRadius: '50%',
                background: 'var(--gold)',
              },
            }),
        badgeText
      ),
      open && !loading
        ? React.createElement(
            'div',
            {
              role: 'tooltip',
              style: {
                position: 'absolute',
                top: 'calc(100% + 10px)',
                right: 0,
                minWidth: 240,
                zIndex: 1000,
                padding: '12px 14px',
                borderRadius: 14,
                border: '1px solid var(--line)',
                background: 'var(--surface)',
                boxShadow: '0 20px 40px -20px rgba(0,0,0,.45)',
                pointerEvents: 'none',
              },
            },
            React.createElement('div', {
              style: {
                fontFamily: 'var(--mono)',
                fontSize: 9,
                letterSpacing: '.2em',
                textTransform: 'uppercase',
                color: 'var(--ink-3)',
                marginBottom: 6,
              },
            }, 'Detected location'),
            React.createElement('div', {
              style: {
                fontSize: 13,
                color: 'var(--ink)',
                lineHeight: 1.45,
              },
            },
              locationLabel || 'Unknown location',
              React.createElement('div', {
                style: {
                  marginTop: 6,
                  fontFamily: 'var(--mono)',
                  fontSize: 10,
                  letterSpacing: '.12em',
                  color: 'var(--ink-3)',
                },
              }, `Currency: ${currency} · ${meta.name || currency}`),
              React.createElement('div', {
                style: {
                  marginTop: 6,
                  fontSize: 12,
                  color: 'var(--ink-2)',
                },
              }, detected ? 'Auto-detected' : `Fallback via ${source}`)
            )
          )
        : null
    );
  }
  window.CurrencyBadge = CurrencyBadge;

  // Backward-compatibility aliases used by the existing app.
  window.CurrencyDisplay = CurrencyBadge;
  window.CurrencyChip = CurrencyBadge;

  // Global CSS keyframes for the loading dot, injected once.
  if (typeof document !== 'undefined' && !document.getElementById('ab-currency-style')) {
    const style = document.createElement('style');
    style.id = 'ab-currency-style';
    style.textContent = `@keyframes abPulse { 0%,100%{opacity:.35; transform:scale(.88);} 50%{opacity:1; transform:scale(1);} }`;
    document.head.appendChild(style);
  }
})();
