/* ===== Mercado: cotações ao vivo (Vercel /api/quotes) com fotografia de 21/09/2026 como reserva ===== */
const SNAPSHOT_DATE = '21/09/2026';
const GALAO_L = 3.78541;
const quotes = [
  { key:'brent', group:'Internacional', name:'Petróleo Brent', unit:'US$/barril', v:101.30, dec:2, change:-2.49, ref:'Fotografia de 21/09/2026', why:'Base da paridade de importação usada pela Petrobras e pelos importadores. Move o custo de diesel e gasolina A.', src:'ICE (via Yahoo Finance)', url:'https://finance.yahoo.com/quote/BZ%3DF/', short:'Brent' },
  { key:'wti', group:'Internacional', name:'Petróleo WTI', unit:'US$/barril', v:97.61, dec:2, change:-2.68, ref:'Fotografia de 21/09/2026', why:'Referência americana. O spread contra o Brent sinaliza o custo relativo de produtos vindos do Golfo do México.', src:'NYMEX (via Yahoo Finance)', url:'https://finance.yahoo.com/quote/CL%3DF/', short:'WTI' },
  { key:'ulsd', group:'Internacional', name:'Diesel NY Harbor (ULSD)', unit:'US$/galão', v:4.910, dec:3, change:-2.91, perL:true, ref:'Fotografia de 21/09/2026', why:'Principal referência de preço do diesel importado pelo Brasil. É o termômetro mais direto para o diesel S10/S500.', src:'NYMEX (via Yahoo Finance)', url:'https://finance.yahoo.com/quote/HO%3DF/', short:'Diesel NYH' },
  { key:'rbob', group:'Internacional', name:'Gasolina RBOB', unit:'US$/galão', v:3.481, dec:3, change:-1.32, perL:true, ref:'Fotografia de 21/09/2026', why:'Referência da gasolina importada. Influencia o preço da gasolina A e, por consequência, a gasolina C.', src:'NYMEX (via Yahoo Finance)', url:'https://finance.yahoo.com/quote/RB%3DF/', short:'RBOB' },
  { key:'usd', group:'Brasil', name:'Dólar comercial', unit:'R$/US$', v:5.14, dec:3, change:null, changeText:'+0,4% na semana', ref:'Fechamento de 18/09/2026', why:'Converte todas as referências internacionais em reais. Dólar alto encarece o combustível importado mesmo com petróleo estável.', src:'AwesomeAPI / Yahoo Finance', url:'https://economia.awesomeapi.com.br/json/last/USD-BRL', short:'Dólar' },
  { key:null, weekly:true, group:'Brasil', name:'Etanol hidratado — CEPEA/ESALQ (SP)', unit:'R$/litro', v:null, dec:4, change:null, changeText:'Preços sustentados', ref:'Setembro/2026 · indicador semanal', why:'Custo de compra do etanol nas usinas paulistas. Chuvas atrasaram a moagem e sustentaram os preços em SP.', src:'CEPEA', url:'https://www.cepea.org.br/br/indicador/etanol.aspx', short:'Etanol' },
  { key:null, weekly:true, group:'Brasil', name:'Diesel S10 — média nas bombas (ANP)', unit:'R$/litro', v:6.97, dec:2, change:1.31, ref:'Pesquisa semanal de 06 a 12/09/2026', why:'Preço final ao consumidor. Ajuda a ler a margem disponível para o posto e o espaço de negociação com o cliente.', src:'ANP', url:'https://www.gov.br/anp/pt-br/assuntos/precos-e-defesa-da-concorrencia/precos/levantamento-de-precos-de-combustiveis-ultimas-semanas-pesquisadas', short:'S10 bomba' },
  { key:null, weekly:true, group:'Brasil', name:'Gasolina comum — média nas bombas (ANP)', unit:'R$/litro', v:6.53, dec:2, change:0, ref:'Pesquisa semanal de 06 a 12/09/2026', why:'Preço final ao consumidor, média nacional. Comparar com o etanol ajuda a prever a troca de produto pelo consumidor.', src:'ANP', url:'https://www.gov.br/anp/pt-br/assuntos/precos-e-defesa-da-concorrencia/precos/levantamento-de-precos-de-combustiveis-ultimas-semanas-pesquisadas', short:'Gasolina bomba' },
];
const sources = [
  { area:'Petróleo e derivados — mundo', items:[
    { name:'ICE — Brent Crude Futures', url:'https://www.ice.com/products/219/Brent-Crude-Futures', what:'Bolsa oficial do contrato Brent' },
    { name:'CME Group — NY Harbor ULSD', url:'https://www.cmegroup.com/markets/energy/refined-products/heating-oil.html', what:'Contrato futuro do diesel de referência' },
    { name:'CME Group — RBOB Gasoline', url:'https://www.cmegroup.com/markets/energy/refined-products/rbob-gasoline.html', what:'Contrato futuro da gasolina de referência' },
    { name:'Investing.com — Brent', url:'https://www.investing.com/commodities/brent-oil', what:'Cotação e histórico de fácil leitura' },
    { name:'EIA — Petroleum & Other Liquids', url:'https://www.eia.gov/petroleum/', what:'Estoques e preços oficiais dos EUA' },
  ]},
  { area:'Brasil — preço de compra', items:[
    { name:'Petrobras — preços às distribuidoras', url:'https://precos.petrobras.com.br/', what:'Preço de venda de diesel A e gasolina A' },
    { name:'CEPEA/ESALQ — Indicador Etanol', url:'https://www.cepea.org.br/br/indicador/etanol.aspx', what:'Hidratado e anidro nas usinas de SP' },
    { name:'Abicom — defasagem de preços', url:'https://abicom.com.br/', what:'Diferença entre preço Petrobras e paridade de importação' },
  ]},
  { area:'Brasil — mercado e câmbio', items:[
    { name:'ANP — Levantamento de preços', url:'https://www.gov.br/anp/pt-br/assuntos/precos-e-defesa-da-concorrencia/precos/levantamento-de-precos-de-combustiveis-ultimas-semanas-pesquisadas', what:'Preços semanais na bomba por município' },
    { name:'ANP — Síntese semanal', url:'https://www.gov.br/anp/pt-br/assuntos/precos-e-defesa-da-concorrencia/precos/sintese-semanal-do-comportamento-dos-precos-dos-combustiveis', what:'Resumo do comportamento dos preços' },
    { name:'Banco Central — PTAX', url:'https://www.bcb.gov.br/estabilidadefinanceira/historicocotacoes', what:'Dólar oficial usado em contratos' },
  ]},
];
const num=(v,d)=>v==null?'—':v.toLocaleString('pt-BR',{minimumFractionDigits:d,maximumFractionDigits:d});
const pct=(n)=>(n>0?'+':'')+n.toFixed(2).replace('.',',')+'%';
const hhmm=(t)=>new Date(t).toLocaleTimeString('pt-BR',{hour:'2-digit',minute:'2-digit',timeZone:'America/Sao_Paulo'});

function useLiveQuotes(){
  const [live,setLive]=useState({status:'loading'});
  useEffect(()=>{
    let stop=false;
    const load=async()=>{
      try{
        const r=await fetch('/api/quotes',{cache:'no-store'});
        if(!r.ok) throw new Error('http');
        const j=await r.json();
        if(!j.items||!Object.keys(j.items).length) throw new Error('vazio');
        if(!stop) setLive({status:'live',data:j.items,at:Date.now()});
      }catch(e){ if(!stop) setLive(p=>p.status==='live'||p.status==='stale'?{...p,status:'stale'}:{status:'off'}); }
    };
    load(); const id=setInterval(load,60000);
    return ()=>{stop=true;clearInterval(id);};
  },[]);
  return live;
}
function mergeQuotes(live){
  const usdLive=live.data&&live.data.usd&&live.data.usd.price;
  const usd=usdLive||quotes.find(q=>q.key==='usd').v;
  return quotes.map(q=>{
    const d=q.key&&live.data&&live.data[q.key];
    let out={...q,live:false};
    if(d&&d.price){
      const change=d.prev?((d.price-d.prev)/d.prev*100):(d.pct!=null?d.pct:null);
      out={...q,v:d.price,change,changeText:null,live:true,ref:`Ao vivo · ${hhmm(d.time||live.at)}`};
    }
    if(q.perL&&out.v) out.perL=out.v*usd/GALAO_L;
    return out;
  });
}

function Change({q}) {
  if (q.change === null || q.change === undefined) return <span className="chg flat">{q.changeText || '—'}</span>;
  const cls = q.change>0.005 ? 'up' : q.change<-0.005 ? 'down' : 'flat';
  const arrow = cls==='up' ? '▲' : cls==='down' ? '▼' : '■';
  return <span className={`chg ${cls}`}>{arrow} {cls==='flat'?'estável':pct(q.change)}</span>;
}
function LiveBadge({live}){
  if(live.status==='live') return <span className="live-badge on"><i/>Ao vivo · {hhmm(live.at)}</span>;
  if(live.status==='stale') return <span className="live-badge stale"><i/>Última leitura {hhmm(live.at)}</span>;
  if(live.status==='loading') return <span className="live-badge"><i/>Conectando…</span>;
  return <span className="live-badge off"><i/>Fotografia de {SNAPSHOT_DATE}</span>;
}

function MarketStrip({go,live}) {
  const all=mergeQuotes(live);
  const list=['Brent','Diesel NYH','Dólar','S10 bomba','Etanol'].map(s=>all.find(q=>q.short===s));
  return <section className="market-strip" aria-label="Mercado hoje">
    <div className="ms-label"><span>MERCADO</span><LiveBadge live={live}/></div>
    <div className="ms-items">{list.map(q=><button key={q.short} onClick={()=>go('mercado')} className="ms-item"><span>{q.short}</span><strong>{num(q.v,q.dec)}</strong><Change q={q}/></button>)}</div>
    <button className="ms-more" onClick={()=>go('mercado')}>Ver mercado →</button>
  </section>;
}

function QuoteCard({q}) {
  return <article className={`quote ${q.live?'is-live':''}`}>
    <header><span className="q-name">{q.name}</span><span className="q-unit">{q.unit}{q.weekly?<em className="q-week">semanal</em>:null}</span></header>
    <div className="q-value">{q.v!=null ? <strong>{num(q.v,q.dec)}</strong> : <strong className="q-missing">—</strong>}<Change q={q}/></div>
    {q.perL&&<p className="q-perl">≈ <b>{brl3(q.perL)}/L</b> em reais, sem frete, impostos e margens</p>}
    {q.v==null && <p className="q-note">Valor numérico não coletado. Consulte a fonte.</p>}
    <p className="q-why">{q.why}</p>
    <footer><span>{q.live?<i className="dot-live"/>:null}{q.ref}</span><a href={q.url} target="_blank" rel="noopener noreferrer">{q.src} ↗</a></footer>
  </article>;
}

function Market({live}) {
  const all=mergeQuotes(live);
  const groups=['Internacional','Brasil'];
  const on=live.status==='live'||live.status==='stale';
  return <div className="content market-content">
    <div className="page-heading"><div><p>INTELIGÊNCIA DE MERCADO</p><h1>Mercado e cotações</h1><span>Referências de preço que mexem no custo de compra, no repasse e na margem.</span></div><div className="heading-actions"><LiveBadge live={live}/></div></div>
    {on?<section className="snapshot-note live"><span className="sn-icon">●</span><div><strong>Cotações ao vivo · atualizam sozinhas a cada 1 minuto</strong><p>Petróleo, diesel e gasolina: contratos futuros das bolsas ICE e NYMEX, lidos via Yahoo Finance (podem ter alguns minutos de atraso). Dólar: AwesomeAPI (reserva: Yahoo Finance). ANP e CEPEA são pesquisas <b>semanais</b> por natureza: nesses cartões vale a data indicada.</p></div></section>
    :<section className="snapshot-note"><span className="sn-icon">i</span><div><strong>{live.status==='loading'?'Buscando cotações ao vivo…':`Sem conexão com as cotações ao vivo: mostrando a fotografia de ${SNAPSHOT_DATE}`}</strong><p>A versão ao vivo funciona no link publicado na Vercel. Nesta visualização os valores são os coletados manualmente em 21/09/2026. Confira a fonte antes de usar um número para negociar.</p></div></section>}
    <section className="market-alert"><div className="ma-tag">PETROBRAS · 17/09/2026</div><div className="ma-body"><strong>Diesel A: reajuste de R$ 1,00/L neutralizado por subvenção federal</strong><p>A Petrobras elevou o preço do diesel A em R$ 1,00/L, mas o desconto do governo (MP 1.391/2026, Portaria MF 2.813) mantém inalterado o preço às distribuidoras. Vigência informada: 30 dias.</p><p className="ma-watch"><b>Ponto de atenção:</b> se a subvenção não for renovada, o reajuste pode chegar ao custo da distribuidora por volta de 17/10 (data estimada, a confirmar).</p></div><a href="https://www.opovo.com.br/noticias/economia/2026/09/17/petrobras-eleva-preco-do-diesel-as-distribuidoras-mas-medida-do-governo-deixa-valor-inalterado.html" target="_blank" rel="noopener noreferrer">Ler notícia ↗</a></section>
    {groups.map(g=><section key={g} className="quote-group"><h2>{g==='Internacional'?'Referências internacionais':'Brasil — câmbio, usina e bomba'}</h2><div className="quote-grid">{all.filter(q=>q.group===g).map(q=><QuoteCard key={q.name} q={q}/>)}</div></section>)}
    <section className="panel sources"><div className="panel-title"><div><h2>Onde acompanhar</h2><p>Fontes oficiais e de referência para cada preço que importa para a distribuidora</p></div></div>
      <div className="source-cols">{sources.map(s=><div key={s.area} className="source-col"><h3>{s.area}</h3><ul>{s.items.map(i=><li key={i.name}><a href={i.url} target="_blank" rel="noopener noreferrer">{i.name} ↗</a><small>{i.what}</small></li>)}</ul></div>)}</div>
    </section>
  </div>;
}
