// ═══ GENESIS BUILD dbexplorer-f1 · 2026-07-12 ═══
// Tidal — DB Explorer: o banco como planilha (somente leitura, só admin)

const DBX_TK = () => localStorage.getItem('genesis_token');
const DBX_HDR = () => ({ 'Authorization': `Bearer ${DBX_TK()}` });

const dbxCelula = (v) => {
  if (v === null || v === undefined) return <span style={{ color: 'var(--muted)', fontStyle: 'italic', opacity: 0.6 }}>NULL</span>;
  if (v === true || v === 'true') return <span style={{ color: 'var(--leaf)', fontWeight: 700 }}>true</span>;
  if (v === false || v === 'false') return <span style={{ color: 'var(--rose)', fontWeight: 700 }}>false</span>;
  return String(v);
};

const DBExplorer = ({ state, setState, setPage }) => {
  const toast = useToast();
  const isMobile = useMobile();
  const me = state.currentUser || {};

  const [tabelas, setTabelas] = useState(null);
  const [filtroTab, setFiltroTab] = useState('');
  const [tab, setTab] = useState(null);              // nome da tabela aberta
  const [dados, setDados] = useState(null);          // {colunas, rows, total, ...}
  const [carregando, setCarregando] = useState(false);
  const [q, setQ] = useState('');
  const [qAplicado, setQAplicado] = useState('');
  const [ordem, setOrdem] = useState(null);          // {col, dir}
  const [pagina, setPagina] = useState(0);
  const [celula, setCelula] = useState(null);        // {col, valor} pra ver o valor inteiro
  const porPagina = 50;

  useEffect(() => {
    fetch('/api/dbexplorer/tabelas', { headers: DBX_HDR() })
      .then(r => r.ok ? r.json() : null)
      .then(d => setTabelas(d ? d.tabelas : []))
      .catch(() => setTabelas([]));
  }, []);

  useEffect(() => {
    if (!tab) return;
    setCarregando(true);
    const p = new URLSearchParams({ limit: String(porPagina), offset: String(pagina * porPagina) });
    if (qAplicado) p.set('q', qAplicado);
    if (ordem) { p.set('ordem', ordem.col); p.set('dir', ordem.dir); }
    fetch(`/api/dbexplorer/tabela/${tab}?${p.toString()}`, { headers: DBX_HDR() })
      .then(r => r.ok ? r.json() : null)
      .then(d => { setDados(d); setCarregando(false); })
      .catch(() => { setDados(null); setCarregando(false); toast.push({ icon: 'x', title: 'Erro ao carregar a tabela' }); });
  }, [tab, qAplicado, ordem, pagina]);

  const abrirTabela = (nome) => { setTab(nome); setDados(null); setQ(''); setQAplicado(''); setOrdem(null); setPagina(0); };
  const ordenarPor = (col) => { setPagina(0); setOrdem(o => (o && o.col === col) ? { col, dir: o.dir === 'asc' ? 'desc' : 'asc' } : { col, dir: 'asc' }); };

  if (me.role !== 'admin') {
    return (
      <main style={{ padding: '40px 20px', flex: 1, maxWidth: 1180, margin: '0 auto', width: '100%', boxSizing: 'border-box' }}>
        <div className="empty" style={{ textAlign: 'center', padding: 60 }}>🔒 área restrita ao administrador.</div>
      </main>
    );
  }

  const totalPaginas = dados ? Math.max(1, Math.ceil(dados.total / porPagina)) : 1;
  const listaTabelas = (tabelas || []).filter(t => !filtroTab || t.nome.includes(filtroTab.toLowerCase()));

  return (
    <main style={{ padding: isMobile ? '16px 12px 80px' : '26px 20px 56px', flex: 1, maxWidth: 1180, margin: '0 auto', width: '100%', boxSizing: 'border-box' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', gap: 12, flexWrap: 'wrap', marginBottom: 16 }}>
        <div>
          <div className="t-eyebrow">ferramenta de diagnóstico · somente leitura</div>
          <h1 style={{ fontFamily: 'var(--fs)', fontSize: 32, letterSpacing: '-0.8px', fontWeight: 400, margin: 0 }}>DB Explo<em style={{ fontStyle: 'italic', color: 'var(--accent)' }}>rer.</em></h1>
        </div>
        {tab ? <div style={{ fontFamily: 'var(--fm)', fontSize: 11, color: 'var(--muted)' }}>🗄 {tab} · {dados ? `${dados.total} linha${dados.total === 1 ? '' : 's'}` : '…'}</div> : null}
      </div>

      <div style={{ display: 'flex', gap: 14, alignItems: 'flex-start' }}>
        {/* ── lista de tabelas ── */}
        {(!isMobile || !tab) ? (
          <div style={{ background: 'var(--surface)', border: '1px solid var(--line-soft)', borderTop: '3px solid var(--teal)', borderRadius: 16, boxShadow: 'var(--shadow-sm)', width: isMobile ? '100%' : 250, flexShrink: 0, padding: '11px 9px 13px', boxSizing: 'border-box', position: isMobile ? 'static' : 'sticky', top: 16, maxHeight: isMobile ? 'none' : 'calc(100vh - 110px)', overflowY: 'auto' }}>
            <div style={{ fontFamily: 'var(--fm)', fontSize: 10, letterSpacing: 1, textTransform: 'uppercase', color: 'var(--teal)', padding: '0 5px 8px' }}>🗄 tabelas do banco</div>
            <input className="input" style={{ width: '100%', boxSizing: 'border-box', marginBottom: 8, padding: '8px 10px', fontSize: 12.5 }} placeholder="🔍 filtrar…" value={filtroTab} onChange={e => setFiltroTab(e.target.value)} />
            {tabelas === null ? <div className="empty" style={{ padding: 14, fontSize: 12 }}>carregando…</div>
              : !listaTabelas.length ? <div className="empty" style={{ padding: 14, fontSize: 12 }}>nada com "{filtroTab}".</div>
              : listaTabelas.map(t => (
                <button key={t.nome} onClick={() => abrirTabela(t.nome)}
                  style={{ width: '100%', display: 'flex', alignItems: 'center', gap: 6, border: 'none', textAlign: 'left', cursor: 'pointer', padding: '6px 8px', borderRadius: 8, fontFamily: 'var(--fm)', fontSize: 11.5, background: tab === t.nome ? 'color-mix(in srgb, var(--teal) 13%, transparent)' : 'transparent', color: tab === t.nome ? 'var(--teal)' : 'var(--ink)', fontWeight: tab === t.nome ? 700 : 400, minWidth: 0 }}>
                  <span style={{ flex: 1, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{t.nome}</span>
                  <span style={{ flexShrink: 0, fontSize: 9.5, color: 'var(--muted)', fontWeight: 400 }}>{t.linhas == null ? '?' : t.linhas}</span>
                </button>
              ))}
          </div>
        ) : null}

        {/* ── grade ── */}
        {(!isMobile || tab) ? (
          <div style={{ flex: 1, minWidth: 0 }}>
            {isMobile && tab ? <button className="btn btn-sm" onClick={() => { setTab(null); setDados(null); }} style={{ marginBottom: 10 }}>← tabelas</button> : null}
            {!tab ? (
              <div className="empty" style={{ background: 'var(--surface)', border: '1px solid var(--line-soft)', borderTop: '3px solid var(--teal)', borderRadius: 16, textAlign: 'center', padding: '54px 20px', color: 'var(--muted)' }}>
                ‹ escolhe uma tabela pra ver como planilha<div style={{ fontSize: 11, fontFamily: 'var(--fm)', marginTop: 6 }}>tudo aqui é somente leitura — pode fuçar sem medo 🔍</div>
              </div>
            ) : (
              <div style={{ background: 'var(--surface)', border: '1px solid var(--line-soft)', borderTop: '3px solid var(--teal)', borderRadius: 16, boxShadow: 'var(--shadow-sm)', padding: '12px 14px', boxSizing: 'border-box', maxHeight: isMobile ? 'none' : 'calc(100vh - 110px)', display: 'flex', flexDirection: 'column' }}>
                <div style={{ display: 'flex', gap: 8, marginBottom: 10, alignItems: 'center', flexWrap: 'wrap' }}>
                  <input className="input" style={{ flex: 1, minWidth: 160, boxSizing: 'border-box', padding: '8px 11px', fontSize: 12.5 }} placeholder="🔍 buscar em todas as colunas… (Enter)" value={q}
                    onChange={e => setQ(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') { setPagina(0); setQAplicado(q.trim()); } }} />
                  <button className="btn btn-primary btn-sm" onClick={() => { setPagina(0); setQAplicado(q.trim()); }}>🔎</button>
                  {qAplicado ? <button className="btn ghost btn-sm" onClick={() => { setQ(''); setQAplicado(''); setPagina(0); }}>✕ limpar</button> : null}
                </div>

                <div style={{ flex: 1, minHeight: 0, overflow: 'auto', border: '1px solid var(--line-soft)', borderRadius: 10 }}>
                  {carregando || !dados ? <div className="empty" style={{ padding: 30 }}>{carregando ? 'carregando…' : 'erro ao carregar.'}</div> : (
                    <table style={{ borderCollapse: 'collapse', fontSize: 11.5, fontFamily: 'var(--fm)', minWidth: '100%' }}>
                      <thead>
                        <tr>
                          {dados.colunas.map(c => (
                            <th key={c.nome} onClick={() => ordenarPor(c.nome)} title={`${c.tipo} — clica pra ordenar`}
                              style={{ position: 'sticky', top: 0, zIndex: 1, background: 'var(--cream-2)', borderBottom: '2px solid var(--line)', borderRight: '1px solid var(--line-soft)', padding: '7px 10px', textAlign: 'left', whiteSpace: 'nowrap', cursor: 'pointer', fontSize: 10, letterSpacing: 0.5, textTransform: 'uppercase', color: ordem && ordem.col === c.nome ? 'var(--teal)' : 'var(--muted)', fontWeight: 700 }}>
                              {c.nome}{ordem && ordem.col === c.nome ? (ordem.dir === 'asc' ? ' ▲' : ' ▼') : ''}
                            </th>
                          ))}
                        </tr>
                      </thead>
                      <tbody>
                        {!dados.rows.length ? (
                          <tr><td colSpan={dados.colunas.length} style={{ padding: 24, textAlign: 'center', color: 'var(--muted)' }}>nenhuma linha{qAplicado ? ` com "${qAplicado}"` : ''}.</td></tr>
                        ) : dados.rows.map((r, i) => (
                          <tr key={i} style={{ background: i % 2 ? 'color-mix(in srgb, var(--cream-2) 55%, transparent)' : 'transparent' }}>
                            {dados.colunas.map(c => {
                              const v = r[c.nome];
                              const texto = v === null || v === undefined ? '' : String(v);
                              return (
                                <td key={c.nome} onClick={() => texto.length > 34 ? setCelula({ col: c.nome, valor: texto }) : null}
                                  style={{ borderBottom: '1px solid var(--line-soft)', borderRight: '1px solid var(--line-soft)', padding: '5px 10px', whiteSpace: 'nowrap', maxWidth: 260, overflow: 'hidden', textOverflow: 'ellipsis', cursor: texto.length > 34 ? 'zoom-in' : 'default' }}>
                                  {dbxCelula(v)}
                                </td>
                              );
                            })}
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  )}
                </div>

                <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingTop: 10, flexWrap: 'wrap' }}>
                  <span style={{ fontFamily: 'var(--fm)', fontSize: 10.5, color: 'var(--muted)', flex: 1 }}>
                    {dados ? `${dados.total} linha${dados.total === 1 ? '' : 's'}${qAplicado ? ` · filtro "${qAplicado}"` : ''} · página ${pagina + 1} de ${totalPaginas}` : ''}
                  </span>
                  <button className="btn ghost btn-sm" disabled={pagina <= 0} onClick={() => setPagina(p => Math.max(0, p - 1))}>‹ anterior</button>
                  <button className="btn ghost btn-sm" disabled={pagina >= totalPaginas - 1} onClick={() => setPagina(p => p + 1)}>próxima ›</button>
                </div>
              </div>
            )}
          </div>
        ) : null}
      </div>

      {/* ── valor inteiro da célula ── */}
      {celula ? (
        <div onClick={() => setCelula(null)} style={{ position: 'fixed', inset: 0, zIndex: 9300, background: 'rgba(31,42,46,0.45)', display: 'flex', alignItems: 'flex-start', justifyContent: 'center', padding: '10vh 14px', overflowY: 'auto' }}>
          <div onClick={e => e.stopPropagation()} style={{ width: '100%', maxWidth: 560, background: 'var(--cream)', borderRadius: 16, border: '1px solid var(--line-soft)', borderTop: '3px solid var(--sky)', padding: '16px 18px', boxShadow: 'var(--shadow-lg)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
              <span style={{ fontFamily: 'var(--fm)', fontSize: 11, color: 'var(--teal)', textTransform: 'uppercase', letterSpacing: 0.8 }}>{celula.col}</span>
              <button className="btn ghost btn-sm" onClick={() => setCelula(null)}>✕</button>
            </div>
            <pre style={{ fontFamily: 'var(--fm)', fontSize: 12, whiteSpace: 'pre-wrap', wordBreak: 'break-word', background: 'var(--cream-2)', borderRadius: 10, padding: '10px 12px', maxHeight: '55vh', overflowY: 'auto', margin: 0 }}>{celula.valor}</pre>
          </div>
        </div>
      ) : null}
    </main>
  );
};
