/* ===== Manutenção da frota (14/11) ==================================
   Pedido dele: a conta de "caminhão parado" estava grosseira demais.
   O caminhão não fica o mês inteiro parado — fica ALGUNS DIAS, e isso
   depende do SERVIÇO. Revisão demora X dias e custa Y; pneu demora
   outro tanto. Então a área nasce com um catálogo de serviços, com
   preço e dias, e tudo editável.

   E quando um caminhão for ou voltar da oficina, alguém lança o que
   foi feito, quando e quanto custou. Quem alimenta é a pessoa que ele
   contratou para a frota. Daí sai o histórico por caminhão.

   DE ONDE VIERAM OS PREÇOS (fonte citada na própria tela)
   Blog Caminhões e Carretas, "Custo Operacional de Caminhão: Como
   Calcular por Km Rodado", publicado em 25/06/2026 e atualizado em
   21/09/2026. Usei o MEIO de cada faixa que o artigo dá.

   ⚠️ O QUE NÃO TEM FONTE: os DIAS PARADOS. O artigo fala de preço e
   intervalo, não de quanto tempo o caminhão fica na oficina. Esses
   números são suposição nossa e estão marcados como tal na tela.
   Por isso toda linha é editável.

   ⚠️ Os dados lançados aqui ficam no navegador, como o resto do app
   fora das telas do banco. Quando houver tabela no Supabase para
   manutenção, isto migra.
   ================================================================== */

/* cadaKm e custo: do artigo (meio da faixa). dias: suposição nossa. */
const MN_SERVICOS = [
  {id:'lub',     nome:'Lubrificação geral',        cadaKm:12500,  dias:0.5, custo:450,
   faixa:'R$ 300 a 600 · a cada 10.000 a 15.000 km'},
  {id:'oleo',    nome:'Troca de óleo e filtros',   cadaKm:45000,  dias:1,   custo:3500,
   faixa:'R$ 2.500 a 4.500 · a cada 30.000 a 60.000 km'},
  {id:'freio',   nome:'Revisão de freios',         cadaKm:80000,  dias:2,   custo:4500,
   faixa:'R$ 3.000 a 6.000 · a cada 60.000 a 100.000 km'},
  {id:'recap',   nome:'Recapagem do jogo de pneus', cadaKm:75000, dias:2,   custo:20900,
   faixa:'R$ 700 a 1.200 por pneu · 60.000 a 90.000 km de rodagem · 22 pneus'},
  {id:'correia', nome:'Correias e tensores',       cadaKm:125000, dias:1,   custo:2250,
   faixa:'R$ 1.500 a 3.000 · a cada 100.000 a 150.000 km'},
  {id:'pneu',    nome:'Troca do jogo de pneus',    cadaKm:125000, dias:2,   custo:47300,
   faixa:'R$ 1.800 a 2.500 por pneu · 100.000 a 150.000 km · 22 pneus'},
  {id:'embr',    nome:'Embreagem',                 cadaKm:300000, dias:3,   custo:8500,
   faixa:'R$ 5.000 a 12.000 · a cada 200.000 a 400.000 km'},
];

const MN_FONTE = 'Blog Caminhões e Carretas · "Custo Operacional de Caminhão" · 25/06/2026, atualizado em 21/09/2026';

/* Histórico de exemplo, só na visualização simulada. Datas geradas em
   relação a hoje, pelo mesmo motivo do consumo: a demonstração não pode
   envelhecer sozinha e deixar o painel de desempenho sem nada no período. */
function mnAtras(n){
  const d = new Date(); d.setDate(d.getDate()-n);
  const dd = (x)=>(x<10?'0':'')+x;
  return `${dd(d.getDate())}/${dd(d.getMonth()+1)}/${d.getFullYear()}`;
}
const initialManutencoes = [
  {id:'MN-1', truck:'TRK-03', servico:'embr', nome:'Embreagem', data:mnAtras(6), custo:9200, dias:3,
   obs:'Troca completa. Peça pedida com 2 dias de antecedência.'},
  {id:'MN-2', truck:'TRK-05', servico:'oleo', nome:'Troca de óleo e filtros', data:mnAtras(18), custo:3380, dias:1, obs:''},
  {id:'MN-3', truck:'TRK-01', servico:'lub', nome:'Lubrificação geral', data:mnAtras(25), custo:420, dias:0.5, obs:''},
  {id:'MN-4', truck:'TRK-05', servico:'freio', nome:'Revisão de freios', data:mnAtras(52), custo:4900, dias:2,
   obs:'Lona do segundo eixo trocada fora do previsto.'},
];

const mnNum = (v) => { const n = parseFloat(String(v).replace(',','.').replace(/[^0-9.-]/g,'')); return isNaN(n)?0:n; };
const mnDias = (d) => (Math.round(d*10)/10).toFixed(1).replace('.',',');

/* Qual o próximo serviço de cada caminhão, pelo KM rodado */
function mnPrevisao(t, servicos){
  const lista = servicos.map(s=>{
    const prox = Math.ceil((t.odo||0)/s.cadaKm)*s.cadaKm;
    const faltaKm = Math.max(0, prox - (t.odo||0));
    const faltaDias = t.dailyKm ? faltaKm/t.dailyKm : 999;
    return {s, prox, faltaKm, faltaDias};
  }).sort((a,b)=>a.faltaKm-b.faltaKm);
  return {proximo: lista[0], todos: lista};
}

function MnCampo({v, onChange, largura}){
  return <input className="mg-in" style={largura?{width:largura}:null} inputMode="decimal"
    value={v==null?'':String(v).replace('.',',')}
    onChange={e=>onChange(mnNum(e.target.value))} aria-label="valor"/>;
}

/* ---- lançar um serviço feito ------------------------------------ */
function MnLancar({fleet, servicos, onLancar, onFechar}){
  const hoje = new Date();
  const dd = (n)=>(n<10?'0':'')+n;
  const [f,setF] = useState({truck: fleet[0]?fleet[0].id:'', servico: servicos[0]?servicos[0].id:'',
    data: `${dd(hoje.getDate())}/${dd(hoje.getMonth()+1)}/${hoje.getFullYear()}`, custo:'', dias:'', obs:''});
  const set=(k,v)=>setF(c=>({...c,[k]:v}));
  const sv = servicos.find(s=>s.id===f.servico);
  const pronto = f.truck && sv && f.data.trim();

  return <div className="np-modal" role="dialog" aria-modal="true" aria-label="Lançar serviço">
    <div className="np-cx mb-cx">
      <p className="np-cx-tit">Lançar serviço feito</p>
      <label className="field mb-f"><span>Caminhão</span>
        <select value={f.truck} onChange={e=>set('truck',e.target.value)}>
          {fleet.map(t=><option key={t.id} value={t.id}>{t.id} · {t.plate}</option>)}
        </select></label>
      <label className="field mb-f"><span>O que foi feito</span>
        <select value={f.servico} onChange={e=>set('servico',e.target.value)}>
          {servicos.map(s=><option key={s.id} value={s.id}>{s.nome}</option>)}
        </select></label>
      <label className="field mb-f"><span>Quando</span>
        <input value={f.data} onChange={e=>set('data',e.target.value)} placeholder="dd/mm/aaaa"/></label>
      <label className="field mb-f"><span>Quanto custou (R$)</span>
        <input value={f.custo} onChange={e=>set('custo',e.target.value)} inputMode="decimal"
          placeholder={sv?String(sv.custo):''}/></label>
      <label className="field mb-f"><span>Dias parado</span>
        <input value={f.dias} onChange={e=>set('dias',e.target.value)} inputMode="decimal"
          placeholder={sv?String(sv.dias):''}/></label>
      <label className="field mb-f"><span>Observação</span>
        <input value={f.obs} onChange={e=>set('obs',e.target.value)} placeholder="O que apareceu fora do previsto"/></label>
      <p className="calc-note">Deixando custo ou dias em branco, entra o valor do catálogo. O que for digitado aqui é o que aconteceu de verdade — é ele que vai corrigir o catálogo com o tempo.</p>
      <div className="np-cx-acoes">
        <button className="secondary" onClick={onFechar}>Cancelar</button>
        <button className="primary" disabled={!pronto} onClick={()=>onLancar({
          id:'MN-'+Date.now().toString(36).toUpperCase().slice(-5),
          truck:f.truck, servico:sv.id, nome:sv.nome, data:f.data.trim(),
          custo: f.custo?mnNum(f.custo):sv.custo, dias: f.dias?mnNum(f.dias):sv.dias, obs:f.obs.trim(),
        })}>Lançar</button>
      </div>
    </div>
  </div>;
}

/* ---- a tela ------------------------------------------------------ */
function Manutencao({fleet, notify, readOnly}){
  const [ajustes,setAjustes] = usePersist('mn-servicos', {});
  /* Simulada: navegador. Real: tabela frota_manutencao no banco. */
  const dados = useFrotaDados('frota_manutencao', 'manutencoes', initialManutencoes,
    (h)=>({id:h.id, caminhao:h.truck, servico:h.servico, nome:h.nome,
           data: bancoDataIso(h.data), custo:h.custo, dias:h.dias, obs:h.obs}),
    (r)=>({id:r.id, truck:r.caminhao, servico:r.servico, nome:r.nome,
           data: bancoDataBr(r.data), custo:Number(r.custo)||0, dias:Number(r.dias)||0, obs:r.obs||''}));
  const hist = dados.linhas;
  const [lancando,setLancando] = useState(false);
  const [verTruck,setVerTruck] = useState('Todos');

  const servicos = MN_SERVICOS.map(s=>Object.assign({}, s, ajustes[s.id]||{}));
  const mudar = (id,campo,v)=>setAjustes(c=>({...c, [id]:Object.assign({}, c[id]||{}, {[campo]:v})}));

  const previsoes = (fleet||[]).map(t=>({t, p: mnPrevisao(t, servicos)}));
  /* o que vence nos próximos 30 dias */
  const noMes = previsoes.map(x=>({t:x.t, itens:x.p.todos.filter(i=>i.faltaDias<=30)}))
                         .filter(x=>x.itens.length>0);
  const diasMes = noMes.reduce((s,x)=>s+x.itens.reduce((a,i)=>a+i.s.dias,0),0);
  const custoMes = noMes.reduce((s,x)=>s+x.itens.reduce((a,i)=>a+i.s.custo,0),0);

  const histVisto = hist.filter(h=>verTruck==='Todos'||h.truck===verTruck);
  const gastoHist = histVisto.reduce((s,h)=>s+(h.custo||0),0);
  const diasHist = histVisto.reduce((s,h)=>s+(h.dias||0),0);

  return <div className="content mn-content">
    <div className="page-heading">
      <div><p>FROTA · MANUTENÇÃO</p><h1>Manutenção preditiva</h1>
        <span>Quando cada caminhão vai parar, por quanto tempo e quanto custa.</span></div>
      {!readOnly && !dados.precisaConta && <div className="heading-actions">
        <button className="primary" onClick={()=>setLancando(true)}>Lançar serviço feito</button></div>}
    </div>

    {dados.noBanco && <p className={'rs '+(dados.precisaConta?'warn':dados.erro?'bad':'good')+' mn-fonte'}>
      {dados.precisaConta
        ? 'Visualização Real: o histórico vem do banco e pede login. Saia e entre com a sua conta.'
        : dados.erro ? dados.erro
        : dados.carregando ? 'Lendo o banco...'
        : 'Histórico vindo do banco: o que for lançado aqui aparece em qualquer computador.'}
    </p>}

    {dados.noBanco && !dados.precisaConta && !(fleet||[]).length &&
      <section className="panel mn-sem-frota">
        <p><b>Os lançamentos funcionam, mas não há caminhão cadastrado.</b></p>
        <p>Na visualização Real o cadastro da frota ainda não existe: ele vive no código, não no banco.
          Enquanto a tabela de frota não for criada, esta tela consegue ler e gravar no banco,
          mas não tem a quem atribuir o serviço.</p>
      </section>}

    <section className="panel mn-topo">
      <div className="mg-kpis">
        <div><span>Nos próximos 30 dias</span><b>{noMes.reduce((s,x)=>s+x.itens.length,0)} serviços</b>
          <small>em {noMes.length} de {(fleet||[]).length} caminhões</small></div>
        <div><span>Dias de caminhão parado</span><b>{mnDias(diasMes)}</b>
          <small>somando todos os serviços do mês</small></div>
        <div className="hl"><span>Custo previsto</span><b>{brl(Math.round(custoMes))}</b>
          <small>só o serviço, sem o que deixa de rodar</small></div>
      </div>
    </section>

    <section className="panel mn-tab">
      <div className="panel-title"><div><h2>O que vem por aí, caminhão por caminhão</h2>
        <p>Calculado pelo KM rodado de cada um e pela média de km por dia.</p></div></div>
      <div className="table-wrap"><table>
        <thead><tr><th>Caminhão</th><th className="num">KM</th><th>Próximo serviço</th>
          <th className="num">Faltam</th><th className="num">Dias parado</th><th className="num">Custo</th></tr></thead>
        <tbody>{previsoes.map(({t,p})=>{
          const i = p.proximo; if(!i) return null;
          const perto = i.faltaDias <= 15;
          return <tr key={t.id} className={perto?'row-on':''}>
            <td><b className="strong">{t.id}</b><small className="cell-sub">{t.plate} · {t.driver}</small></td>
            <td className="num">{fmt(t.odo||0)}</td>
            <td>{i.s.nome}{perto&&<small className="cell-sub mn-perto">em {Math.round(i.faltaDias)} {Math.round(i.faltaDias)===1?'dia':'dias'}</small>}</td>
            <td className="num">{fmt(i.faltaKm)} km</td>
            <td className="num">{mnDias(i.s.dias)}</td>
            <td className="num strong">{brl(i.s.custo)}</td>
          </tr>;
        })}</tbody>
      </table></div>
      <p className="calc-note">Quem estiver a 15 dias ou menos aparece destacado. O revezamento inteligente — não deixar dois caminhões caírem na mesma semana — é o próximo passo desta tela.</p>
    </section>

    {typeof MnPlano!=='undefined' && <MnPlano fleet={fleet} servicos={servicos}/>}

    <section className="panel mn-tab">
      <div className="panel-title"><div><h2>Catálogo de serviços</h2>
        <p>Preço e intervalo com fonte. Os dias parados são suposição nossa. Tudo editável.</p></div></div>
      <div className="table-wrap"><table>
        <thead><tr><th>Serviço</th><th className="num">A cada (km)</th><th className="num">Dias parado</th>
          <th className="num">Custo (R$)</th><th>Faixa da fonte</th></tr></thead>
        <tbody>{servicos.map(s=><tr key={s.id}>
          <td><b className="strong">{s.nome}</b></td>
          <td className="num"><MnCampo v={s.cadaKm} onChange={v=>mudar(s.id,'cadaKm',v)} largura="96px"/></td>
          <td className="num"><MnCampo v={s.dias} onChange={v=>mudar(s.id,'dias',v)} largura="62px"/></td>
          <td className="num"><MnCampo v={s.custo} onChange={v=>mudar(s.id,'custo',v)} largura="96px"/></td>
          <td><small className="cell-sub">{s.faixa}</small></td>
        </tr>)}</tbody>
      </table></div>
      <p className="calc-note">
        <b>Preço e intervalo</b> saíram do meio das faixas publicadas em: {MN_FONTE}.
        <b> Os dias parados não têm fonte</b> — são estimativa nossa, porque o artigo fala de dinheiro e km, não de tempo de oficina.
        O número de pneus (22) é de uma configuração parecida, não da frota dele: <b>confirmar com o Paulo</b>.
      </p>
    </section>

    <section className="panel mn-tab">
      <div className="panel-title"><div><h2>Histórico de serviços</h2>
        <p>{histVisto.length} {histVisto.length===1?'serviço lançado':'serviços lançados'} · {brl(Math.round(gastoHist))} · {mnDias(diasHist)} dias de caminhão parado</p></div>
        <div className="heading-actions">
          <label className="seller-filter">Caminhão
            <select value={verTruck} onChange={e=>setVerTruck(e.target.value)}>
              <option value="Todos">Todos</option>
              {(fleet||[]).map(t=><option key={t.id} value={t.id}>{t.id}</option>)}
            </select></label>
        </div>
      </div>
      {histVisto.length===0
        ? <p className="mn-vazio">{dados.carregando?'Lendo o banco...':'Nada lançado ainda. Quem cuida da frota lança aqui o que foi feito, quando e quanto custou — é desse histórico que sai a previsão boa.'}</p>
        : <div className="table-wrap"><table>
            <thead><tr><th>Quando</th><th>Caminhão</th><th>O que foi feito</th><th className="num">Dias</th><th className="num">Custo</th></tr></thead>
            <tbody>{histVisto.map(h=><tr key={h.id}>
              <td>{h.data}</td>
              <td><b className="strong">{h.truck}</b></td>
              <td>{h.nome}{h.obs&&<small className="cell-sub">{h.obs}</small>}</td>
              <td className="num">{mnDias(h.dias||0)}</td>
              <td className="num strong">{brl(Math.round(h.custo||0))}</td>
            </tr>)}</tbody>
          </table></div>}
    </section>

    <p className="calc-note">Quem alimenta esta tela é a pessoa que ele contratou para a frota. O sistema não substitui ela — depende dela.
      Sem alguém lançando o que foi feito, a previsão nunca sai do chute.
      {dados.noBanco
        ? ' Na visualização Real os lançamentos vão para o banco, com data e autor.'
        : ' Na visualização Simulada nada é gravado de verdade: é demonstração. Troque para Real e entre com a sua conta para valer.'}</p>

    {lancando && <MnLancar fleet={fleet||[]} servicos={servicos}
      onFechar={()=>setLancando(false)}
      onLancar={async (h)=>{ const r = await dados.inserir(h); setLancando(false);
        notify && notify(r.ok ? ('Serviço lançado '+(r.onde==='banco'?'no banco.':'no histórico.')) : r.erro); }}/>}
  </div>;
}

/* Logo depois de Frota: é a mesma área */
(function(){
  const i = navItems.findIndex(x=>x.id==='frota');
  navItems.splice(i<0?navItems.length:i+1, 0,
    {id:'manutencao', label:'Manutenção', short:'Oficina', icon:'◓'});
})();
