/* ===== Rastreamento da frota — SIMULADO (na versão real, posições vêm do rastreador do caminhão) ===== */
navItems.splice(navItems.findIndex(i=>i.id==='frota')+1,0,{id:'rastreamento',label:'Rastreamento',short:'Rastreio',icon:'◎',tag:'simulado'});

const LIMITE_VEL=80; // km/h, alerta de excesso (hipótese)
const PEDAGIO_KM=0.32; // R$ por km em trecho pedagiado (fictício)

/* Estrada aproximada: linha com uma curva no meio, sempre a mesma nos dois sentidos */
function legPoly(a,b){
  const [p,q]=[a,b].sort(); const [la1,lo1]=cities[p],[la2,lo2]=cities[q];
  const h=[...(p+q)].reduce((s,c)=>s+c.charCodeAt(0),0); const s=h%2?1:-1, k=0.14;
  const mid=[(la1+la2)/2+s*(lo2-lo1)*k,(lo1+lo2)/2-s*(la2-la1)*k];
  const poly=[[la1,lo1],mid,[la2,lo2]];
  return p===a?poly:poly.slice().reverse();
}
function pointAt(poly,f){
  const segs=[]; let tot=0;
  for(let i=0;i<poly.length-1;i++){const d=Math.hypot(poly[i+1][0]-poly[i][0],poly[i+1][1]-poly[i][1]);segs.push(d);tot+=d;}
  let target=f*tot;
  for(let i=0;i<segs.length;i++){ if(target<=segs[i]||i===segs.length-1){const r=segs[i]?Math.min(1,target/segs[i]):0;return [poly[i][0]+(poly[i+1][0]-poly[i][0])*r,poly[i][1]+(poly[i+1][1]-poly[i][1])*r];} target-=segs[i]; }
  return poly[poly.length-1];
}

/* Programação simulada das viagens (minutos a partir das 11:30) */
const SIM_DEFS=[
  {id:'TRK-04',t0:-45,speed:62,loop:true,legs:[{from:'Barretos',to:'Bebedouro',dwell:30,label:'Entrega Posto Avenida'},{from:'Bebedouro',to:'Barretos',dwell:40,label:'Carregamento na base'}]},
  {id:'TRK-05',t0:-55,speed:58,loop:true,legs:[{from:'Barretos',to:'Bebedouro',dwell:25,label:'Entrega em Bebedouro'},{from:'Bebedouro',to:'Monte Azul Paulista',dwell:25,label:'Encaixe #PED-2845'},{from:'Monte Azul Paulista',to:'Barretos',dwell:40,label:'Carregamento na base'}]},
  {id:'TRK-09',t0:-40,speed:60,loop:true,legs:[{from:'Barretos',to:'Olímpia',dwell:35,label:'Entrega Posto Imperial'},{from:'Olímpia',to:'Barretos',dwell:40,label:'Carregamento na base'}]},
  {id:'TRK-10',t0:-30,speed:77,loop:true,legs:[{from:'Barretos',to:'Terra Roxa',dwell:30,label:'Entrega Rede Terra Roxa'},{from:'Terra Roxa',to:'Viradouro',dwell:25,label:'Entrega em Viradouro'},{from:'Viradouro',to:'Barretos',dwell:40,label:'Carregamento na base'}]},
  {id:'TRK-12',t0:-20,speed:64,loop:false,legs:[{from:'Severínia',to:'Barretos',dwell:0,label:'Chegada à base',stops:[{f:0.45,dur:18,label:'Parada não prevista'}]}]},
  {id:'TRK-02',t0:50,speed:62,loop:true,wait:'Carregando · saída 13:20',legs:[{from:'Barretos',to:'Guaíra',dwell:30,label:'Entrega Auto Posto Guaíra'},{from:'Guaíra',to:'Barretos',dwell:40,label:'Carregamento na base'}]},
  {id:'TRK-07',t0:210,speed:60,loop:true,wait:'Programada · saída 15:00',legs:[{from:'Barretos',to:'Colina',dwell:30,label:'Entrega Posto Nogueira'},{from:'Colina',to:'Barretos',dwell:40,label:'Carregamento na base'}]},
];

function buildPlan(def){
  const segs=[];
  def.legs.forEach((leg,li)=>{
    const km=dist(leg.from,leg.to), full=km/def.speed*60;
    let f=0;
    for(const s of (leg.stops||[])){ segs.push({type:'move',li,f0:f,f1:s.f,dur:full*(s.f-f),km:km*(s.f-f)}); segs.push({type:'stop',li,f:s.f,dur:s.dur,label:s.label}); f=s.f; }
    segs.push({type:'move',li,f0:f,f1:1,dur:full*(1-f),km:km*(1-f)});
    if(leg.dwell) segs.push({type:'dwell',li,city:leg.to,dur:leg.dwell,label:leg.label});
  });
  return {...def,segs,total:segs.reduce((s,x)=>s+x.dur,0),polys:def.legs.map(l=>legPoly(l.from,l.to))};
}
const SIM_PLANS=SIM_DEFS.map(buildPlan);

function simState(plan,t,idx){
  let tt=t-plan.t0;
  if(tt<0) return {phase:'wait',pos:cities[plan.legs[0].from],label:plan.wait,key:'wait',speed:0,kmToday:0};
  let cycle=0;
  if(plan.loop){cycle=Math.floor(tt/plan.total); tt=tt%plan.total;}
  else if(tt>=plan.total){const last=plan.legs[plan.legs.length-1];return {phase:'done',pos:cities[last.to],label:'Na base',key:'done',speed:0,kmToday:plan.segs.reduce((s,x)=>s+(x.km||0),0)};}
  let km=0;
  for(let i=0;i<plan.segs.length;i++){
    const s=plan.segs[i];
    if(tt<=s.dur||i===plan.segs.length-1){
      const r=s.dur?Math.min(1,tt/s.dur):1, leg=plan.legs[s.li];
      const key=`${cycle}-${i}`;
      if(s.type==='move'){
        const f=s.f0+(s.f1-s.f0)*r;
        const kmLeft=dist(leg.from,leg.to)*(1-f);
        const speed=Math.round(plan.speed+7*Math.sin(t/5+idx*1.7));
        return {phase:'move',pos:pointAt(plan.polys[s.li],f),leg,f,key,speed,kmLeft,eta:t+(kmLeft/plan.speed*60),kmToday:km+s.km*r,label:`A caminho de ${leg.to}`};
      }
      if(s.type==='stop') return {phase:'stop',pos:pointAt(plan.polys[s.li],s.f),leg,key,speed:0,label:s.label,since:t-tt+0,left:s.dur-tt,kmToday:km};
      return {phase:'dwell',pos:cities[s.city],leg,key,speed:0,label:s.label,left:s.dur-tt,kmToday:km};
    }
    km+=s.km||0; tt-=s.dur;
  }
}

const TRECHOS=[
  {a:'Barretos',b:'Bebedouro',real:71,n:14},{a:'Barretos',b:'Olímpia',real:57,n:11},{a:'Barretos',b:'Terra Roxa',real:58,n:9},
  {a:'Barretos',b:'Guaíra',real:55,n:8},{a:'Bebedouro',b:'Monte Azul Paulista',real:33,n:6},{a:'Severínia',b:'Barretos',real:52,n:7},
];
const phaseColor={move:'#2f7ddd',dwell:'#e0a030',stop:'#d4533f',wait:'#8265d7',done:'#8a94a6',base:'#8a94a6',manutencao:'#b6c0cf'};
const phaseText={move:'Em movimento',dwell:'Parado no cliente/base',stop:'Parada não prevista',wait:'Aguardando saída',done:'Na base',base:'Na base',manutencao:'Na oficina'};

function Tracking({fleet,bases}) {
  const [sim,setSim]=useState(0); // minutos simulados desde 11:30
  const [rate,setRate]=useState(60); // segundos simulados por segundo real
  const [sel,setSel]=useState('TRK-10');
  const [events,setEvents]=useState([{t:0,tone:'info',text:'Rastreamento simulado iniciado · posições atualizadas a cada segundo'}]);
  const prev=React.useRef({}); const lastSpeed=React.useRef({});
  useEffect(()=>{ if(!rate) return; const id=setInterval(()=>setSim(s=>s+rate/60),1000); return ()=>clearInterval(id); },[rate]);
  const states=useMemo(()=>{
    const m={};
    SIM_PLANS.forEach((p,i)=>{m[p.id]=simState(p,sim,i);});
    fleet.forEach(t=>{ if(!m[t.id]) m[t.id]={phase:t.status==='manutencao'?'manutencao':'base',pos:cities[t.pos]||cities['Barretos'],label:t.status==='manutencao'?t.note:'Na base',speed:0,kmToday:0}; });
    return m;
  },[sim,fleet]);
  useEffect(()=>{
    const ev=[];
    SIM_PLANS.forEach(p=>{
      const s=states[p.id], old=prev.current[p.id];
      if(old&&old!==s.key){
        if(s.phase==='dwell') ev.push({t:sim,tone:'info',text:`${p.id} chegou em ${s.leg.to} · ${s.label}`});
        if(s.phase==='move'&&s.f<0.05) ev.push({t:sim,tone:'info',text:`${p.id} saiu de ${s.leg.from} rumo a ${s.leg.to}`});
        if(s.phase==='stop') ev.push({t:sim,tone:'bad',text:`${p.id} parou fora do previsto entre ${s.leg.from} e ${s.leg.to}`});
        if(s.phase==='done') ev.push({t:sim,tone:'info',text:`${p.id} chegou à base`});
      }
      if(s.phase==='move'&&s.speed>LIMITE_VEL&&(lastSpeed.current[p.id]==null||sim-lastSpeed.current[p.id]>30)){ lastSpeed.current[p.id]=sim; ev.push({t:sim,tone:'warn',text:`${p.id} a ${s.speed} km/h entre ${s.leg.from} e ${s.leg.to} (limite ${LIMITE_VEL})`}); }
      prev.current[p.id]=s.key;
    });
    if(ev.length) setEvents(list=>[...ev.reverse(),...list].slice(0,40));
  },[states]);
  const ids=fleet.map(t=>t.id);
  const count=(ph)=>ids.filter(id=>ph.includes(states[id].phase)).length;
  const alerts=events.filter(e=>e.tone!=='info').length;
  const t=fleet.find(x=>x.id===sel)||fleet[0]; const st=states[t.id]; const plan=SIM_PLANS.find(p=>p.id===t.id);
  const garage=(bases.find(b=>b.garage)||{city:'Barretos'}).city;
  let routes=null;
  if(st&&st.leg){ const km=dist(st.leg.from,st.leg.to); const a={km,min:Math.round(km/62*60),toll:km*PEDAGIO_KM}; const b={km:Math.round(km*1.12),min:Math.round(km*1.12/55*60),toll:0}; a.cost=a.km*CUSTO_KM+a.toll; b.cost=b.km*CUSTO_KM; routes={a,b,best:a.cost<=b.cost?'a':'b'}; }
  return <div className="content tracking-content">
    <div className="page-heading"><div><p>FROTA · TEMPO REAL</p><h1>Rastreamento</h1><span>Onde cada caminhão está agora, para onde vai e o que foge do previsto.</span></div><div className="heading-actions"><span className="sim-clock"><i/>Relógio simulado <b>{clock(sim/60)}</b></span><div className="seg" role="group" aria-label="Velocidade da simulação">{[[0,'Pausar'],[1,'Tempo real'],[60,'60×'],[300,'300×']].map(([r,l])=><button key={r} className={rate===r?'on':''} onClick={()=>setRate(r)}>{l}</button>)}</div></div></div>
    <section className="sim-banner"><b>Simulação.</b> Os caminhões andam por rotas de exemplo, em velocidade acelerada. Na versão real (opção A combinada), as posições virão do rastreador que os caminhões já têm, e esta mesma tela passa a mostrar os dados verdadeiros.</section>
    <section className="log-metrics"><article><span>Em movimento</span><strong>{count(['move'])}</strong><small>com sinal ativo</small></article><article><span>Parados em cliente ou base</span><strong>{count(['dwell','wait'])}</strong><small>entregando ou carregando</small></article><article><span>Na garagem</span><strong>{count(['base','done'])}</strong><small>+ {count(['manutencao'])} na oficina</small></article><article><span>Alertas</span><strong className={alerts?'warn-num':''}>{alerts}</strong><small>velocidade e paradas</small></article></section>
    <div className="track-grid">
      <section className="panel map-panel"><div className="panel-title"><div><h2>Mapa da frota</h2><p>Clique num caminhão · linha tracejada = trecho em andamento</p></div></div>
        <svg viewBox="0 0 640 530" className="cmap" role="img" aria-label="Mapa com a posição simulada dos caminhões">
          <rect x="0" y="0" width="640" height="530" rx="12" fill="#f3f6fa"/>
          {[...new Set(SIM_PLANS.flatMap(p=>p.legs.map(l=>[l.from,l.to].sort().join('|'))))].map(k=>{const [a,b]=k.split('|');const pl=legPoly(a,b);return <polyline key={k} points={pl.map(([la,lo])=>`${MAP_X(lo)},${MAP_Y(la)}`).join(' ')} fill="none" stroke="#d5dce6" strokeWidth="3" strokeLinecap="round"/>;})}
          {Object.entries(cities).map(([n,[la,lo]])=><g key={n}><circle cx={MAP_X(lo)} cy={MAP_Y(la)} r="3" fill="#b6c0cf"/><text x={MAP_X(lo)>560?MAP_X(lo)-6:MAP_X(lo)+6} y={MAP_Y(la)-6} fontSize="11" fill="#7a8597" textAnchor={MAP_X(lo)>560?'end':'start'}>{n}</text></g>)}
          {bases.map((b,i)=>{const [la,lo]=cities[b.city];const same=bases.filter((x,j)=>j<i&&x.city===b.city).length;return <g key={b.id}><title>{b.name}</title><rect x={MAP_X(lo)-9+same*20} y={MAP_Y(la)-9} width="18" height="18" rx="5" fill={b.kind==='Usina'?'#1f7a50':'#111c32'} stroke="#fff" strokeWidth="2"/><text x={MAP_X(lo)+same*20} y={MAP_Y(la)+4} fontSize="9" fill="#fff" textAnchor="middle" fontWeight="800">{baseLetter[b.kind]||'B'}</text></g>;})}
          {SIM_PLANS.map(p=>{const s=states[p.id];if(!s.leg||s.phase==='done')return null;const pl=p.polys[p.legs.indexOf(s.leg)];return <polyline key={'r'+p.id} points={pl.map(([la,lo])=>`${MAP_X(lo)},${MAP_Y(la)}`).join(' ')} fill="none" stroke={phaseColor[s.phase]} strokeOpacity={sel===p.id?0.9:0.35} strokeWidth={sel===p.id?3:2} strokeDasharray="6 5"/>;})}
          {(()=>{const seen={};return fleet.filter(x=>states[x.id].phase!=='base'&&states[x.id].phase!=='manutencao'||x.id===sel).map(x=>{const s=states[x.id];const [la,lo]=s.pos;const key=`${Math.round(MAP_X(lo))},${Math.round(MAP_Y(la))}`;const k=seen[key]=(seen[key]||0)+1;const cx=MAP_X(lo)+(k-1)*16,cy=MAP_Y(la)+(s.phase==='move'?0:18);const on=sel===x.id;return <g key={x.id} className="truck-pin" onClick={()=>setSel(x.id)} role="button" tabIndex={0} aria-label={`${x.id}: ${phaseText[s.phase]}`} onKeyDown={e=>{if(e.key==='Enter')setSel(x.id);}}><title>{`${x.id} · ${phaseText[s.phase]}${s.speed?` · ${s.speed} km/h`:''}`}</title>{on&&<circle cx={cx} cy={cy} r="15" fill={phaseColor[s.phase]} fillOpacity="0.18"/>}<circle cx={cx} cy={cy} r={on?9:7} fill={phaseColor[s.phase]} stroke="#fff" strokeWidth="2"/><text x={cx} y={cy-13} fontSize="10" fontWeight="800" fill="#1f2b40" textAnchor="middle">{x.id.replace('TRK-','')}</text></g>;});})()}
          <g transform="translate(20,486)"><rect width="560" height="30" rx="8" fill="#fff" stroke="#e1e6ee"/>{[['move','Em movimento',0],['dwell','Parado no cliente/base',112],['stop','Parada não prevista',262],['wait','Aguardando saída',400]].map(([k,l,x])=><g key={k} transform={`translate(${14+x},15)`}><circle r="6" fill={phaseColor[k]}/><text x="11" y="4" fontSize="10" fill="#445067">{l}</text></g>)}</g>
        </svg>
      </section>
      <section className="panel truck-panel">
        <div className="panel-title"><div><h2>{t.id} · {t.plate}</h2><p>{t.driver} · {fmt(t.cap)} L</p></div><span className="phase-pill" style={{background:phaseColor[st.phase]}}>{phaseText[st.phase]}</span></div>
        <div className="truck-body">
          <div className="tk-grid"><p><span>Velocidade</span><b className={st.speed>LIMITE_VEL?'bad-num':''}>{st.speed} km/h</b></p><p><span>{st.phase==='move'?'Próximo destino':'Local'}</span><b>{st.leg?(st.phase==='move'?st.leg.to:(st.phase==='stop'?`Entre ${st.leg.from} e ${st.leg.to}`:st.leg.to)):(t.pos||garage)}</b></p><p><span>{st.phase==='move'?'Chegada prevista':'Situação'}</span><b>{st.phase==='move'?clock(st.eta/60):(st.left?`mais ~${Math.round(st.left)} min`:st.label||'—')}</b></p><p><span>Km rodados hoje</span><b>{fmt(Math.round(st.kmToday||0))} km</b></p></div>
          <p className="tk-status">{st.label}{st.phase==='move'?` · faltam ${Math.round(st.kmLeft)} km`:''}</p>
          <p className="tk-signal"><i/>Sinal GPS simulado · última posição {clock(sim/60)}</p>
          {routes&&<div className="routes"><h3>Rota sugerida para este trecho</h3>{[['a','Mais rápida (com pedágio)',routes.a],['b','Sem pedágio',routes.b]].map(([k,l,r])=><div key={k} className={`route ${routes.best===k?'best':''}`}><div><b>{l}</b>{routes.best===k&&<em>Recomendada</em>}</div><p>{r.km} km · {r.min} min · pedágio {r.toll?brl2(r.toll):'R$ 0'}</p><small>Custo do trecho: {brl(r.cost)}</small></div>)}<p className="calc-note">Simulação: {routes.best==='a'?'neste trecho, desviar do pedágio roda mais km e sai mais caro':'neste trecho, evitar o pedágio compensa'}. Na versão real, rotas, pedágios, trânsito e obras virão de um serviço de mapas (ex.: Google Routes, que é pago por uso).</p></div>}
          {!plan&&<p className="calc-note">Caminhão sem viagem simulada agora.</p>}
        </div>
      </section>
    </div>
    <div className="rep-grid">
      <section className="panel"><div className="panel-title"><div><h2>Ocorrências</h2><p>Geradas automaticamente pelo rastreamento</p></div></div><ul className="ev-list">{events.map((e,i)=><li key={i} className={e.tone}><span>{clock(e.t/60)}</span><p>{e.text}</p></li>)}</ul></section>
      <section className="panel"><div className="panel-title"><div><h2>Aprendizado por trecho</h2><p>Tempo planejado × tempo real médio · histórico fictício</p></div></div>
        <div className="learn">{TRECHOS.map(r=>{const plan=Math.round(dist(r.a,r.b)/VEL_MEDIA*60);const d=r.real-plan;const max=80;return <div key={r.a+r.b} className="lr"><div className="lr-name"><b>{r.a} → {r.b}</b><small>{r.n} viagens</small></div><div className="lr-bars"><div><i className="pl" style={{width:`${plan/max*100}%`}}/><span>{plan} min planejado</span></div><div><i className={d>5?'late':'ok'} style={{width:`${r.real/max*100}%`}}/><span>{r.real} min real</span></div></div><b className={d>5?'bad-num':'ok-num'}>{d>0?'+':''}{d} min</b></div>;})}</div>
        <p className="calc-note pad">Com o rastreador real, esta tabela se monta sozinha a cada viagem. A sugestão de caminhão passa a usar o tempo real de cada trecho em vez da média de {VEL_MEDIA} km/h.</p>
      </section>
    </div>
  </div>;
}
