// Live data hook — free public APIs, no auth required.
//
//  Crypto        → CoinGecko v3  (https://api.coingecko.com)  — CORS ✓, no key
//  Forex         → Frankfurter   (https://api.frankfurter.app) — ECB rates, CORS ✓
//  Indices/Cmdty → Yahoo Finance  v8 chart                     — CORS ✓ from browser
//
// Refreshes every 60 s. Falls back to seed values on any failure.

window.useLiveTicker = function useLiveTicker() {
  const seed = [
    { sym: 'BTC·USD', px: '94,820',  ch: '+1.42%', positive: true  },
    { sym: 'ETH·USD', px: '3,318',   ch: '+0.86%', positive: true  },
    { sym: 'SOL·USD', px: '178.4',   ch: '−0.92%', positive: false },
    { sym: 'SPX',     px: '5,712.4', ch: '+0.34%', positive: true  },
    { sym: 'NDX',     px: '20,184',  ch: '+0.51%', positive: true  },
    { sym: 'DXY',     px: '105.92',  ch: '−0.18%', positive: false },
    { sym: 'EUR·USD', px: '1.0814',  ch: '+0.12%', positive: true  },
    { sym: 'USD·JPY', px: '154.62',  ch: '+0.28%', positive: true  },
    { sym: 'GOLD',    px: '2,418',   ch: '+0.42%', positive: true  },
    { sym: 'WTI',     px: '78.14',   ch: '−0.56%', positive: false },
    { sym: 'US10Y',   px: '4.382%',  ch: '+0.6bp', positive: true  },
    { sym: 'VIX',     px: '14.82',   ch: '−1.2%',  positive: false },
  ];

  const [ticks,     setTicks]     = React.useState(seed);
  const [status,    setStatus]    = React.useState('seed');
  const [updatedAt, setUpdatedAt] = React.useState(null);

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

    // ── helpers ───────────────────────────────────────────────────────────
    const fmt = (n, dec = 2) =>
      isFinite(n) ? Number(n).toLocaleString('en-US', { minimumFractionDigits: dec, maximumFractionDigits: dec }) : '—';
    const pct = n => (n >= 0 ? '+' : '−') + Math.abs(n).toFixed(2) + '%';

    async function safeJson(url, opts = {}) {
      try {
        const r = await fetch(url, { cache: 'no-store', ...opts });
        if (!r.ok) return null;
        return await r.json();
      } catch { return null; }
    }

    // ── CoinGecko — all crypto in one request ─────────────────────────────
    async function coingecko() {
      const url = 'https://api.coingecko.com/api/v3/simple/price'
        + '?ids=bitcoin,ethereum,solana'
        + '&vs_currencies=usd'
        + '&include_24hr_change=true';
      return await safeJson(url);
    }

    // ── Frankfurter — ECB forex rates ─────────────────────────────────────
    // Returns { close, ch } or null.
    async function frankfurter(from, to) {
      // Previous business day (go back 3 days to skip weekends)
      const prevDate = new Date(Date.now() - 3 * 864e5).toISOString().slice(0, 10);
      const [latest, prev] = await Promise.all([
        safeJson(`https://api.frankfurter.app/latest?from=${from}&to=${to}`),
        safeJson(`https://api.frankfurter.app/${prevDate}?from=${from}&to=${to}`),
      ]);
      const close = latest?.rates?.[to];
      if (!isFinite(close)) return null;
      const prevClose = prev?.rates?.[to];
      const ch = (isFinite(prevClose) && prevClose > 0) ? ((close - prevClose) / prevClose) * 100 : 0;
      return { close, prevClose, ch };
    }

    // ── Yahoo Finance — indices, commodities, DXY ─────────────────────────
    // Returns { close, prevClose, ch } or null.
    async function yahoo(symbol) {
      const enc = encodeURIComponent(symbol);
      // Try query1 then query2
      for (const host of ['query1', 'query2']) {
        const url = `https://${host}.finance.yahoo.com/v8/finance/chart/${enc}?interval=1d&range=5d`;
        const data = await safeJson(url);
        const meta = data?.chart?.result?.[0]?.meta;
        if (!meta) continue;
        const close     = meta.regularMarketPrice;
        const prevClose = meta.chartPreviousClose ?? meta.previousClose;
        if (!isFinite(close)) continue;
        const ch = (isFinite(prevClose) && prevClose > 0) ? ((close - prevClose) / prevClose) * 100 : 0;
        return { close, prevClose, ch };
      }
      return null;
    }

    // ── Main load ─────────────────────────────────────────────────────────
    async function loadAll() {
      const out = [];

      // === CRYPTO via CoinGecko ===
      const cgMap = { bitcoin: 'BTC·USD', ethereum: 'ETH·USD', solana: 'SOL·USD' };
      const cgData = await coingecko();
      if (cgData) {
        for (const [id, label] of Object.entries(cgMap)) {
          const item = cgData[id];
          if (!item) continue;
          const price = item.usd;
          const chPct = item.usd_24h_change ?? 0;
          const dec   = price > 1000 ? 0 : price > 10 ? 1 : 2;
          out.push({ sym: label, px: fmt(price, dec), ch: pct(chPct), positive: chPct >= 0 });
        }
      }

      // === FOREX via Frankfurter ===
      const [eurusd, usdjpy] = await Promise.all([
        frankfurter('EUR', 'USD'),
        frankfurter('USD', 'JPY'),
      ]);
      if (eurusd) out.push({ sym: 'EUR·USD', px: fmt(eurusd.close, 4), ch: pct(eurusd.ch), positive: eurusd.ch >= 0 });
      if (usdjpy) out.push({ sym: 'USD·JPY', px: fmt(usdjpy.close, 2), ch: pct(usdjpy.ch), positive: usdjpy.ch >= 0 });

      // === MARKETS via Yahoo Finance ===
      const yf = [
        { sym: 'SPX',   code: '^GSPC',     dec: 1 },
        { sym: 'NDX',   code: '^NDX',      dec: 0 },
        { sym: 'DXY',   code: 'DX-Y.NYB',  dec: 2 },
        { sym: 'GOLD',  code: 'GC=F',      dec: 0 },
        { sym: 'WTI',   code: 'CL=F',      dec: 2 },
        { sym: 'US10Y', code: '^TNX',      dec: 3, isYield: true },
        { sym: 'VIX',   code: '^VIX',      dec: 2 },
      ];

      const yfResults = await Promise.all(yf.map(item => yahoo(item.code)));

      yf.forEach((item, i) => {
        const r = yfResults[i];
        if (!r) return;

        if (item.isYield) {
          // ^TNX is the yield in %; change in basis points
          const bpsRaw = isFinite(r.prevClose) ? (r.close - r.prevClose) * 100 : null;
          const bpsStr = bpsRaw !== null
            ? (bpsRaw >= 0 ? '+' : '−') + Math.abs(bpsRaw).toFixed(1) + 'bp'
            : pct(r.ch);
          out.push({ sym: item.sym, px: fmt(r.close, 3) + '%', ch: bpsStr, positive: r.ch >= 0 });
          return;
        }

        out.push({ sym: item.sym, px: fmt(r.close, item.dec), ch: pct(r.ch), positive: r.ch >= 0 });
      });

      // Restore display order
      const order = ['BTC·USD','ETH·USD','SOL·USD','SPX','NDX','DXY','EUR·USD','USD·JPY','GOLD','WTI','US10Y','VIX'];
      out.sort((a, b) => {
        const ia = order.indexOf(a.sym), ib = order.indexOf(b.sym);
        return (ia < 0 ? 999 : ia) - (ib < 0 ? 999 : ib);
      });

      if (!alive) return;
      if (out.length >= 3) {
        setTicks(out);
        setStatus('live');
        setUpdatedAt(new Date());
      } else {
        setStatus('seed');
      }
    }

    loadAll();
    const id = setInterval(loadAll, 60_000);
    return () => { alive = false; clearInterval(id); };
  }, []);

  return { ticks, status, updatedAt };
};
