
const { useState, useEffect, useRef } = React;

/* Real-time prices.
   Strategy:
   1. If user has set localStorage.iws_finnhub_key → use Finnhub direct (CORS-enabled).
   2. Otherwise → Yahoo Finance via corsproxy.io (no key, ~free).
*/

const TICKERS = [
  { sym: 'AAPL',  display: 'AAPL',     name: 'Apple' },
  { sym: 'MSFT',  display: 'MSFT',     name: 'Microsoft' },
  { sym: 'NVDA',  display: 'NVDA',     name: 'NVIDIA' },
  { sym: 'GOOGL', display: 'GOOGL',    name: 'Alphabet' },
  { sym: 'AMZN',  display: 'AMZN',     name: 'Amazon' },
  { sym: 'TSLA',  display: 'TSLA',     name: 'Tesla' },
  { sym: 'META',  display: 'META',     name: 'Meta' },
  { sym: 'SPY',   display: 'S&P 500',  name: 'SPY' },
  { sym: 'QQQ',   display: 'NASDAQ',   name: 'QQQ' },
  { sym: 'DIA',   display: 'DOW',      name: 'Dow Jones' },
];

async function fetchYahoo() {
  const symbols = TICKERS.map(t => t.sym).join(',');
  // Yahoo Finance v7 quote endpoint, proxied through corsproxy.io
  const yahooUrl = `https://query1.finance.yahoo.com/v7/finance/quote?symbols=${symbols}`;
  const proxied = `https://corsproxy.io/?${encodeURIComponent(yahooUrl)}`;
  const res = await fetch(proxied);
  if (!res.ok) throw new Error('Yahoo fetch failed');
  const json = await res.json();
  const quotes = json?.quoteResponse?.result || [];
  const map = {};
  quotes.forEach(q => {
    const tk = TICKERS.find(t => t.sym === q.symbol);
    if (!tk) return;
    map[tk.display] = {
      symbol: q.symbol,
      close: q.regularMarketPrice,
      change: q.regularMarketChange,
      pct: q.regularMarketChangePercent,
      name: tk.name,
    };
  });
  return map;
}

async function fetchFinnhub(key) {
  // Finnhub doesn't have a multi-quote endpoint on free tier; loop one at a time
  const map = {};
  await Promise.all(TICKERS.map(async tk => {
    try {
      const res = await fetch(`https://finnhub.io/api/v1/quote?symbol=${tk.sym}&token=${key}`);
      if (!res.ok) return;
      const q = await res.json();
      if (q && typeof q.c === 'number' && q.c > 0) {
        map[tk.display] = {
          symbol: tk.sym,
          close: q.c,
          change: q.d,
          pct: q.dp,
          name: tk.name,
        };
      }
    } catch {}
  }));
  return map;
}

/* Fallback: synthesize plausible quotes locally so the bar always shows something
   if both network sources fail (e.g. offline / proxy down). */
const FALLBACK_BASE = {
  'AAPL': 232.15, 'MSFT': 421.40, 'NVDA': 138.20, 'GOOGL': 178.30,
  'AMZN': 215.50, 'TSLA': 358.75, 'META': 580.10,
  'S&P 500': 591.20, 'NASDAQ': 510.85, 'DOW': 444.30,
};
function fallbackPrices() {
  const map = {};
  TICKERS.forEach(tk => {
    const base = FALLBACK_BASE[tk.display] || 100;
    const pct = (Math.random() - 0.45) * 2.4;
    const change = base * pct / 100;
    map[tk.display] = {
      symbol: tk.sym, close: base + change, change, pct, name: tk.name,
    };
  });
  return map;
}

function useLivePrices() {
  const [prices, setPrices] = useState({});
  const [loading, setLoading] = useState(true);
  const [updated, setUpdated] = useState(null);
  const [source, setSource] = useState('');

  const fetchPrices = async () => {
    const finnhubKey = localStorage.getItem('iws_finnhub_key');
    try {
      let map = {};
      if (finnhubKey) {
        map = await fetchFinnhub(finnhubKey);
        if (Object.keys(map).length) {
          setSource('Finnhub');
        } else {
          throw new Error('Finnhub empty');
        }
      } else {
        map = await fetchYahoo();
        if (Object.keys(map).length) {
          setSource('Yahoo');
        } else {
          throw new Error('Yahoo empty');
        }
      }
      setPrices(map);
      setUpdated(new Date());
    } catch (e) {
      // network failed entirely — show synthesized fallback so UI isn't empty
      setPrices(fallbackPrices());
      setUpdated(new Date());
      setSource('Demo');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchPrices();
    const interval = setInterval(fetchPrices, 30000); // refresh every 30s
    return () => clearInterval(interval);
  }, []);

  return { prices, loading, updated, source };
}

function LiveTickerBar({ lang }) {
  const { prices, loading, updated, source } = useLivePrices();
  const orderedTickers = TICKERS.filter(t => prices[t.display]);

  return (
    <div style={{
      background: 'var(--bg2)',
      borderBottom: '1px solid var(--border)',
      overflow: 'hidden',
      position: 'relative',
      height: 36,
      display: 'flex',
      alignItems: 'center',
      flexShrink: 0,
    }}>
      <div style={{
        display: 'flex',
        alignItems: 'center',
        gap: 8,
        padding: '0 12px',
        borderRight: '1px solid var(--border)',
        background: 'var(--card)',
        height: '100%',
        flexShrink: 0,
        zIndex: 2,
      }}>
        <span style={{
          width: 6, height: 6, borderRadius: '50%',
          background: source === 'Demo' ? 'var(--gold)' : 'var(--green)',
          animation: 'livepulse 1.5s ease-in-out infinite',
        }}></span>
        <span style={{ fontFamily: 'Barlow, sans-serif', fontWeight: 700, fontSize: 10, letterSpacing: '0.1em', color: 'var(--text2)' }}>
          {source === 'Demo' ? (lang === 'es' ? 'DEMO' : 'DEMO') : (lang === 'es' ? 'EN VIVO' : 'LIVE')}
        </span>
        <style>{`
          @keyframes livepulse {
            0%, 100% { opacity: 1; transform: scale(1); }
            50% { opacity: 0.4; transform: scale(0.7); }
          }
          @keyframes ticker-slide {
            from { transform: translateX(0); }
            to   { transform: translateX(-50%); }
          }
        `}</style>
      </div>
      <div style={{ flex: 1, overflow: 'hidden', height: '100%', display: 'flex', alignItems: 'center' }}>
        {loading ? (
          <div style={{ padding: '0 16px', fontSize: 11, color: 'var(--muted)' }}>
            {lang === 'es' ? 'Cargando precios en tiempo real...' : 'Loading live prices...'}
          </div>
        ) : (
          <div style={{
            display: 'flex',
            whiteSpace: 'nowrap',
            animation: 'ticker-slide 60s linear infinite',
            willChange: 'transform',
          }}>
            {[...orderedTickers, ...orderedTickers].map((tk, i) => {
              const p = prices[tk.display];
              if (!p) return null;
              const up = p.change >= 0;
              return (
                <div key={i} style={{
                  display: 'flex', alignItems: 'center', gap: 8, padding: '0 18px',
                  borderRight: '1px solid var(--border2)',
                }}>
                  <span style={{ fontFamily: 'Barlow, sans-serif', fontWeight: 700, fontSize: 11, color: 'var(--gold)', letterSpacing: '0.04em' }}>
                    {tk.display}
                  </span>
                  <span style={{ fontFamily: 'Barlow, sans-serif', fontWeight: 600, fontSize: 12, color: 'var(--text)' }}>
                    ${p.close.toFixed(2)}
                  </span>
                  <span style={{ fontSize: 11, color: up ? 'var(--green)' : 'var(--red)', fontWeight: 600, display: 'flex', alignItems: 'center', gap: 2 }}>
                    {up ? '▲' : '▼'} {Math.abs(p.pct).toFixed(2)}%
                  </span>
                </div>
              );
            })}
          </div>
        )}
      </div>
      {updated && (
        <div className="hide-mobile" style={{
          padding: '0 12px', fontSize: 10, color: 'var(--muted)',
          borderLeft: '1px solid var(--border)', height: '100%',
          display: 'flex', alignItems: 'center', flexShrink: 0,
          background: 'var(--bg2)', zIndex: 2,
          gap: 6,
        }}>
          <span>{source}</span>
          <span style={{ opacity: 0.5 }}>·</span>
          <span>{updated.toLocaleTimeString().slice(0,5)}</span>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { LiveTickerBar });
