/* ===== Mapa da equipe e Mapa de processos (14/11) ===================
   As duas telas pedidas: mostram o que está na tabela `mapas` do banco.

   REGRAS DELE, e onde cada uma está no código:
   1. Master e admin editam; os outros só veem.
      → `bancoPodeEditar()` pergunta ao próprio banco. Quem não pode
        não vê botão nenhum. E mesmo que visse, o banco recusaria.
   2. Ao salvar, carimbar `atualizado` (Date.now()) e `atualizado_por`
      = "app".  → feito dentro de `bancoSalvarMapa`, não aqui, para
        não existir caminho de gravação que esqueça o carimbo.
   3. Nada de cópia no navegador. → não há usePersist nem localStorage
        nestas telas. Toda abertura relê do banco; depois de salvar,
        relê de novo em vez de confiar no que está na tela.

   A estrutura da tabela não foi tocada. `campos` é uma lista de pares
   [rótulo, valor] e é editada como tal.
   ================================================================== */

const MB_ESTADOS = {
  fato:          {rot:'Fato confirmado', pill:'p-base'},
  interpretacao: {rot:'Interpretação',   pill:'p-rota'},
  hipotese:      {rot:'Hipótese',        pill:'p-carregando'},
  esclarecer:    {rot:'A esclarecer',    pill:'p-manutencao'},
};

const mbQuando = (ms) => {
  if(!ms) return 'sem data';
  const d = new Date(Number(ms)); const dd = (n)=>(n<10?'0':'')+n;
  return `${dd(d.getDate())}/${dd(d.getMonth()+1)}/${d.getFullYear()} ${dd(d.getHours())}:${dd(d.getMinutes())}`;
};

/* ---- edição de um item ------------------------------------------ */
function MbEditor({item, onFechar, onGravado, notify}){
  const [nome,setNome] = useState(item.nome||'');
  const [estado,setEstado] = useState(item.estado||'fato');
  const [fonte,setFonte] = useState(item.fonte||'');
  const [campos,setCampos] = useState(()=> (item.campos||[]).map(p=>[p[0]||'', p[1]||'']));
  const [salvando,setSalvando] = useState(false);
  const [erro,setErro] = useState('');

  const mudarCampo = (i,j,v) => setCampos(c=>c.map((p,k)=> k===i ? (j===0?[v,p[1]]:[p[0],v]) : p));
  const somar = () => setCampos(c=>[...c,['','']]);
  const tirar = (i) => setCampos(c=>c.filter((p,k)=>k!==i));

  const gravar = async () => {
    setSalvando(true); setErro('');
    try{
      await bancoSalvarMapa(item.id, {
        nome: nome.trim(), estado, fonte: fonte.trim(),
        campos: campos.filter(p=>p[0].trim()||p[1].trim()).map(p=>[p[0].trim(), p[1].trim()]),
      });
      notify && notify('Alteração gravada no banco.');
      onGravado();
    }catch(e){ setErro(e.message || 'Não deu para gravar.'); }
    setSalvando(false);
  };

  return <div className="np-modal" role="dialog" aria-modal="true" aria-label={'Editar ' + (item.nome||'item')}>
    <div className="np-cx mb-cx">
      <p className="np-cx-tit">Editar</p>

      <label className="field mb-f"><span>Nome</span>
        <input value={nome} onChange={e=>setNome(e.target.value)}/></label>

      <label className="field mb-f"><span>Estado</span>
        <select value={estado} onChange={e=>setEstado(e.target.value)}>
          {Object.keys(MB_ESTADOS).map(k=><option key={k} value={k}>{MB_ESTADOS[k].rot}</option>)}
        </select></label>

      <label className="field mb-f"><span>Fonte</span>
        <input value={fonte} onChange={e=>setFonte(e.target.value)} placeholder="De onde veio esta informação"/></label>

      <p className="mb-f-rot">Campos</p>
      <div className="mb-campos">
        {campos.map((p,i)=><div key={i} className="mb-par">
          <input value={p[0]} onChange={e=>mudarCampo(i,0,e.target.value)} placeholder="Rótulo" aria-label="Rótulo"/>
          <input value={p[1]} onChange={e=>mudarCampo(i,1,e.target.value)} placeholder="Valor" aria-label="Valor"/>
          <button className="mb-x" onClick={()=>tirar(i)} aria-label="Remover este campo">–</button>
        </div>)}
        <button className="secondary mb-add" onClick={somar}>Adicionar campo</button>
      </div>

      {erro && <p className="rs bad mb-erro">{erro}</p>}
      <p className="calc-note">Ao gravar, o sistema carimba a data e marca que a alteração veio do <b>app</b> — é assim que o Hub sabe qual versão é a mais nova.</p>

      <div className="np-cx-acoes">
        <button className="secondary" onClick={onFechar} disabled={salvando}>Cancelar</button>
        <button className="primary" onClick={gravar} disabled={salvando||!nome.trim()}>{salvando?'Gravando...':'Gravar no banco'}</button>
      </div>
    </div>
  </div>;
}

/* ---- histórico de um item --------------------------------------- */
function MbHistorico({item, onFechar}){
  const [linhas,setLinhas] = useState(null);
  const [erro,setErro] = useState('');
  useEffect(()=>{ let vivo=true;
    bancoHistorico(item.id).then(d=>{ if(vivo) setLinhas(d||[]); })
      .catch(e=>{ if(vivo) setErro(e.message||'Não deu para ler o histórico.'); });
    return ()=>{ vivo=false; };
  },[item.id]);

  return <div className="np-modal" role="dialog" aria-modal="true" aria-label="Histórico">
    <div className="np-cx mb-cx">
      <p className="np-cx-tit">Histórico de {item.nome}</p>
      {erro && <p className="rs bad mb-erro">{erro}</p>}
      {!linhas && !erro && <p className="mm-det">Lendo o banco...</p>}
      {linhas && linhas.length===0 && <p className="mm-det">Nenhuma alteração registrada ainda.</p>}
      {linhas && linhas.map((l,i)=><div key={i} className="mb-h">
        <div className="mm-top"><b>{l.operacao||'alteração'}</b>
          <span className="pill p-base">{l.origem||'?'}</span>
          <em className="mb-h-q">{mbQuando(l.em)}</em></div>
        <p className="mm-det">{l.por||'sem autor'}</p>
      </div>)}
      <div className="np-cx-acoes"><button className="secondary" onClick={onFechar}>Fechar</button></div>
    </div>
  </div>;
}

/* ---- a tela ------------------------------------------------------ */
function MapaBanco({tipo, titulo, rotulo, sub, notify, sessao}){
  const [itens,setItens] = useState(null);
  const [erro,setErro] = useState('');
  const [podeEditar,setPodeEditar] = useState(false);
  const [editando,setEditando] = useState(null);
  const [vendoHist,setVendoHist] = useState(null);
  const [recarga,setRecarga] = useState(0);

  useEffect(()=>{ let vivo=true;
    if(!sessao){ setItens(null); setErro(''); return; }
    setItens(null); setErro('');
    bancoMapas(tipo).then(d=>{ if(vivo) setItens(d||[]); })
      .catch(e=>{ if(vivo) setErro(e.message||'Não deu para ler o banco.'); });
    bancoPodeEditar().then(p=>{ if(vivo) setPodeEditar(p); });
    return ()=>{ vivo=false; };
  },[tipo, sessao, recarga]);

  const recarregar = ()=>setRecarga(n=>n+1);
  const maisNovo = (itens||[]).reduce((m,i)=>Math.max(m, Number(i.atualizado)||0), 0);

  return <div className="content mb-content">
    <div className="page-heading">
      <div><p>{rotulo}</p><h1>{titulo}</h1><span>{sub}</span></div>
      {sessao && <div className="heading-actions">
        <button className="secondary" onClick={recarregar}>Recarregar</button>
      </div>}
    </div>

    {!sessao
      ? <section className="panel mb-vazio">
          <p><b>Esta tela lê o banco, não os dados de demonstração.</b></p>
          <p>Saia e entre de novo escolhendo <b>Entrar com minha conta</b>. Sem login de verdade o banco não devolve nenhuma linha.</p>
        </section>
      : <>
        <section className="ai-tip mb-tip">
          <span>✦</span>
          <div>
            <strong>{podeEditar ? 'Você pode editar estes mapas' : 'Você está vendo, não editando'}</strong>
            <p>{podeEditar
              ? 'Toda alteração é gravada no banco com data e marcada como vinda do app — é assim que o Hub sabe qual versão é a mais nova.'
              : 'Só os papéis master e admin editam. Quem decide isso é o banco, não esta tela.'}</p>
          </div>
        </section>

        {erro && <section className="panel mb-vazio"><p><b>Não deu para ler o banco.</b></p><p>{erro}</p></section>}
        {!itens && !erro && <section className="panel mb-vazio"><p>Lendo o banco...</p></section>}
        {itens && itens.length===0 && !erro &&
          <section className="panel mb-vazio"><p><b>Nenhum item deste tipo no banco.</b></p>
            <p>Se você esperava ver algo aqui, confira se o seu e-mail está na lista de autorizados.</p></section>}

        {itens && itens.length>0 && <div className="mb-lista">
          {itens.map(it=>{
            const e = MB_ESTADOS[it.estado] || {rot: it.estado||'sem estado', pill:'p-carregando'};
            return <article key={it.id} className="panel mb-item">
              <div className="mb-it-topo">
                <b>{it.nome}</b>
                <span className={'pill ' + e.pill}>{e.rot}</span>
                <em className="mb-it-q">{it.atualizado ? mbQuando(it.atualizado)+' · ' : ''}{it.atualizado_por||'sem autor'}</em>
              </div>
              <dl className="mb-it-campos">
                {(it.campos||[]).map((p,i)=><div key={i}>
                  <dt>{p[0]}</dt><dd>{p[1]}</dd>
                </div>)}
              </dl>
              {it.fonte && <p className="mb-it-fonte">Fonte: {it.fonte}</p>}
              <div className="mb-it-acoes">
                {podeEditar && <button className="secondary" onClick={()=>setEditando(it)}>Editar</button>}
                <button className="link-btn" onClick={()=>setVendoHist(it)}>Ver histórico</button>
              </div>
            </article>;
          })}
        </div>}

        <p className="calc-note">Vem da tabela <b>mapas</b> do banco da Iunes, a mesma que o Hub da ValorIA sincroniza.
          Nada fica guardado neste navegador: cada abertura lê do banco.
          {maisNovo>0 && <> Alteração mais recente: <b>{mbQuando(maisNovo)}</b>.</>}</p>
      </>}

    {editando && <MbEditor item={editando} notify={notify}
      onFechar={()=>setEditando(null)}
      onGravado={()=>{ setEditando(null); recarregar(); }}/>}
    {vendoHist && <MbHistorico item={vendoHist} onFechar={()=>setVendoHist(null)}/>}
  </div>;
}

/* Logo depois do Mapa mental: os três falam da mesma operação. */
(function(){
  const i = navItems.findIndex(x=>x.id==='mapa');
  navItems.splice(i<0?navItems.length:i+1, 0,
    {id:'mb-equipe', label:'Mapa da equipe', short:'Equipe', icon:'◍'},
    {id:'mb-processos', label:'Mapa de processos', short:'Processos', icon:'◰'});
})();

/* ===== A mesma tabela, dentro do Mapa mental (14/11) ================
   Decisão dele: "a tabela mapas do banco é a fonte única. As abas
   Gente e Processos do Mapa mental, que estão escritas no código,
   devem passar a ler a tabela."

   Este componente é a versão de LEITURA, sem edição, para viver dentro
   de uma aba. Editar continua sendo nas telas Mapa da equipe e Mapa de
   processos — ali é o lugar com formulário e histórico.

   ⚠️ Enquanto ele não decidir, o conteúdo antigo continua no código
   de js/mapa-mental.jsx, sem ser usado. Nada foi apagado.
   ================================================================== */
function MbDoBanco({tipo, telaRot}){
  const [itens,setItens] = useState(null);
  const [erro,setErro] = useState('');
  const temSessao = !!bancoLerSessao();

  useEffect(()=>{ let vivo = true;
    if(!temSessao){ setItens([]); return; }
    setItens(null); setErro('');
    bancoMapas(tipo).then(d=>{ if(vivo) setItens(d||[]); })
      .catch(e=>{ if(vivo){ setItens([]); setErro(e.message || 'Não deu para ler o banco.'); } });
    return ()=>{ vivo = false; };
  },[tipo, temSessao]);

  if(!temSessao) return <section className="panel mb-vazio">
    <p><b>Esta aba lê a tabela do banco, não o código do app.</b></p>
    <p>Saia e entre escolhendo <b>Entrar com minha conta</b>. Sem login de verdade o banco não devolve nenhuma linha.</p>
  </section>;

  if(erro) return <section className="panel mb-vazio"><p><b>Não deu para ler o banco.</b></p><p>{erro}</p></section>;
  if(itens === null) return <section className="panel mb-vazio"><p>Lendo o banco...</p></section>;
  if(!itens.length) return <section className="panel mb-vazio">
    <p><b>Nenhum item deste tipo na tabela.</b></p>
    <p>Confira se o seu e-mail está na lista de autorizados.</p></section>;

  const maisNovo = itens.reduce((m,i)=>Math.max(m, Number(i.atualizado)||0), 0);

  return <div className="mb-lista">
    {itens.map(it=>{
      const e = MB_ESTADOS[it.estado] || {rot: it.estado||'sem estado', pill:'p-carregando'};
      return <article key={it.id} className="panel mb-item">
        <div className="mb-it-topo">
          <b>{it.nome}</b>
          <span className={'pill ' + e.pill}>{e.rot}</span>
          <em className="mb-it-q">{it.atualizado ? mbQuando(it.atualizado)+' · ' : ''}{it.atualizado_por||'sem autor'}</em>
        </div>
        <dl className="mb-it-campos">
          {(it.campos||[]).map((p,i)=><div key={i}><dt>{p[0]}</dt><dd>{p[1]}</dd></div>)}
        </dl>
        {it.fonte && <p className="mb-it-fonte">Fonte: {it.fonte}</p>}
      </article>;
    })}
    <p className="calc-note">Vem da tabela <b>mapas</b> do banco — a mesma que o Hub sincroniza e que a tela <b>{telaRot}</b> edita.
      Nada aqui está escrito no código do app.{maisNovo ? <> Última alteração: <b>{mbQuando(maisNovo)}</b>.</> : ' Nenhum item foi editado pelo app ainda.'}</p>
  </div>;
}
