// Telas 2 e 3 — Inventário de dispositivos + Lista branca.
const DSd = window.WiFi_eeb21e;
const { Card: CardD, CardContent: CardContentD, CardHeader: CardHeaderD, CardTitle: CardTitleD, Badge: BadgeD, Button: BtnD, Input: InputD, Label: LabelD, Alert: AlertD, AlertTitle: AlertTitleD, AlertDescription: AlertDescD } = DSd;
const { GTh: ThD, GTd: TdD, ChipFiltro: ChipD, BtnMini: BtnMiniD, TermoDica: TermoD, SelectG: SelD, mkLinha: mkD } = window;

const FILTROS_INV = [
 { id: 'todos', rot: 'Todos', f: () => true },
 { id: 'com', rot: 'Comunicando', f: d => d.conexoes > 0 },
 { id: 'lib', rot: 'Liberados', f: d => d.liberado },
 { id: 'iot', rot: 'IoT', f: d => /IoT/.test(d.veredito) },
 { id: 'nav', rot: 'Com navegador', f: d => /NAVEGADOR/.test(d.veredito) },
 { id: 'rep', rot: 'Repetidores', f: d => /REPETIDOR/.test(d.veredito) }];

function TelaInventario({ site, sitesSel, openCmd }) {
 const meta = window.GESTAO_META;
 const list = sitesSel && sitesSel.length ? sitesSel : [site];
 const multi = list.length > 1;
 const carga = window.useCarrega(() => Promise.all(list.map(k => window.GestaoAPI.inventario(k)
   .then(r => (r.dispositivos || []).map(d => ({ ...d, __k: k, __rot: meta[k].label })))))
   .then(a => a.flat()), [list.join(',')]);
 const [filtro, setFiltro] = React.useState('todos');
 const hoje = new Date().toISOString().slice(0, 10);
 const liberar = d => { const s = meta[d.__k]; openCmd({
  titulo: 'Liberar MAC na lista branca', alvo: s.alvo, slug: d.__k, acao: 'binding-add',
  onSucesso: () => carga.recarrega(),
  mac: d.mac, comment: `CHARLES ${(d.hostname || d.vendor).toUpperCase()} ${hoje}`,
  linhas: [mkD(s.alvo, `/ip hotspot ip-binding add mac-address=${d.mac} type=bypassed server=${s.server} comment="CHARLES ${(d.hostname || d.vendor).toUpperCase()} ${hoje}"`)],
  nota: 'O vínculo pertence ao server, não ao profile — sobrevive a qualquer troca de portal. Comentário sempre preenchido: é o que identifica o aparelho daqui a um ano.'
 }); };
 const remover = d => { const s = meta[d.__k]; openCmd({
  titulo: 'Remover MAC da lista branca', alvo: s.alvo, slug: d.__k, acao: 'binding-del', mac: d.mac, onSucesso: () => carga.recarrega(),
  linhas: [mkD(s.alvo, `/ip hotspot ip-binding remove [find where mac-address=${d.mac}]`), mkD(s.alvo, '/ip hotspot ip-binding print where type=bypassed')],
  nota: 'A segunda linha confere o resultado. O aparelho volta a cair no portal na próxima conexão.'
 }); };
 const base = carga.dados || [];
 const rows = base.filter(FILTROS_INV.find(x => x.id === filtro).f);
 return <div>
  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 14, alignItems: 'center' }}>
   {FILTROS_INV.map(f => <ChipD key={f.id} ativo={filtro === f.id} onClick={() => setFiltro(f.id)}>{f.rot}</ChipD>)}
   <div style={{ flex: 1 }} />
   <div style={{ fontSize: 12.5, color: 'hsl(var(--muted-foreground))' }}>{`${base.length} MACs · ${base.filter(d => d.conexoes > 0).length} comunicando · ${base.filter(d => d.liberado).length} liberados`}</div>
  </div>
  <window.CargaBox carregando={carga.carregando} erro={carga.erro} onTentar={carga.recarrega} linhas={6}>
  <CardD>
   <CardContentD style={{ padding: '4px 8px', overflowX: 'auto' }}>
    <table style={{ width: '100%', borderCollapse: 'collapse' }}>
     <thead><tr>{multi ? <ThD>Ponto</ThD> : null}<ThD>MAC</ThD><ThD>Fabricante</ThD><ThD>SSID</ThD><ThD>IP</ThD><ThD right>Conexões</ThD><ThD>Liberado</ThD><ThD>Veredito</ThD><ThD>Ação</ThD></tr></thead>
     <tbody>
      {rows.map((d, i) => <tr key={d.__k + d.mac}>
       {multi ? <TdD>{d.__rot}</TdD> : null}
       <TdD mono>{d.mac}{d.aleatorio ? <div style={{ fontSize: 10.5, color: 'hsl(var(--muted-foreground))' }}><TermoD dica="Endereço rotativo de privacidade do celular — muda a cada rede">aleatório</TermoD></div> : null}</TdD>
       <TdD>{d.vendor}{d.hostname ? <div style={{ fontSize: 11, color: 'hsl(var(--muted-foreground))' }}>{d.hostname}</div> : null}</TdD>
       <TdD>{d.ssid}</TdD><TdD mono>{d.ip}</TdD><TdD right>{d.conexoes || '—'}</TdD>
       <TdD>{d.liberado ? <BadgeD variant="secondary">{d.comentario || 'sim'}</BadgeD> : <span style={{ color: 'hsl(var(--muted-foreground))' }}>não</span>}</TdD>
       <TdD wrap><div style={{ maxWidth: 300, fontSize: 12.5, lineHeight: 1.45 }}>{d.veredito}{d.sinais.length ? <div style={{ color: 'hsl(var(--muted-foreground))', fontSize: 11.5 }}>{d.sinais.join(' · ')}</div> : null}</div></TdD>
       <TdD>{d.liberado ? <BtnMiniD tom="perigo" onClick={() => remover(d)}>Remover</BtnMiniD> : <BtnMiniD onClick={() => liberar(d)}>Liberar</BtnMiniD>}</TdD>
      </tr>)}
     </tbody>
    </table>
   </CardContentD>
  </CardD>
  </window.CargaBox>
  <div style={{ fontSize: 12, color: 'hsl(var(--muted-foreground))', marginTop: 10, lineHeight: 1.5 }}>Veredito do <TermoD dica="ops/inventario.py — cruza associação WiFi, leases, conexões vivas e cache DNS">inventário por tráfego</TermoD>: quem emite sonda de portal tem navegador; nuvem de fabricante indica IoT; OUI de equipamento de rede com tráfego de celular indica repetidor com <TermoD dica="O repetidor esconde os aparelhos atrás dele — o tráfego visto é dos clientes, não dele">NAT</TermoD>.</div>
 </div>;
}

function macValido(m) { return /^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/.test(m); }

function TelaListaBranca({ site, sitesSel, openCmd }) {
 const meta = window.GESTAO_META;
 const list = sitesSel && sitesSel.length ? sitesSel : [site];
 const multi = list.length > 1;
 const [alvo, setAlvo] = React.useState(list[0]);
 React.useEffect(() => setAlvo(a => list.includes(a) ? a : list[0]), [list.join(',')]);
 const s = meta[alvo];
 const carga = window.useCarrega(() => Promise.all(list.map(k => window.GestaoAPI.bindings(k)
   .then(r => (r.bindings || []).map(b => ({ ...b, __k: k, __rot: meta[k].label })))))
   .then(a => a.flat()), [list.join(',')]);
 const vRows = carga.dados || [];
 const cgCount = vRows.filter(b => b.__k === 'campogas').length;
 const [mac, setMac] = React.useState('');
 const [com, setCom] = React.useState('');
 const pronto = macValido(mac) && com.trim().length >= 3;
 const hoje = new Date().toISOString().slice(0, 10);
 const incluir = () => openCmd({
  titulo: 'Incluir MAC na lista branca', alvo: s.alvo, slug: alvo, acao: 'binding-add', onSucesso: () => carga.recarrega(),
  mac: mac.toUpperCase(), comment: `CHARLES ${com.trim().toUpperCase()} ${hoje}`,
  linhas: [mkD(s.alvo, `/ip hotspot ip-binding add mac-address=${mac.toUpperCase()} type=bypassed server=${s.server} comment="CHARLES ${com.trim().toUpperCase()} ${hoje}"`), mkD(s.alvo, `/ip hotspot ip-binding print where mac-address=${mac.toUpperCase()}`)],
  nota: 'bypassed = nunca passa pelo portal. A segunda linha confere o vínculo criado.'
 });
 const remover = b => { const sb = meta[b.__k]; openCmd({
  titulo: 'Remover vínculo da lista branca', alvo: sb.alvo, slug: b.__k, acao: 'binding-del', mac: b.mac, onSucesso: () => carga.recarrega(),
  linhas: [mkD(sb.alvo, `/ip hotspot ip-binding remove [find where mac-address=${b.mac}]`)],
  nota: `Vínculo atual: "${b.comment || '(sem comentário)'}". O aparelho volta a cair no portal na próxima conexão.`
 }); };
 return <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0,1fr) 300px', gap: 16, alignItems: 'start' }}>
  <div>
   {list.includes('campogas') ? <AlertD style={{ marginBottom: 14 }}>
    <AlertTitleD>Rede crítica da empresa — Campo Gás</AlertTitleD>
    <AlertDescD>{`${cgCount || 'Os'} vínculos sustentam DVR, relógio de ponto, alarme, impressoras e PCs — 100% do tráfego real. Nunca recriar, renomear ou remover o hotspot server: os vínculos estão amarrados a server=${meta.campogas.server}.`}</AlertDescD>
   </AlertD> : null}
   <window.CargaBox carregando={carga.carregando} erro={carga.erro} onTentar={carga.recarrega} linhas={6}>
   <CardD>
    <CardHeaderD style={{ paddingBottom: 6 }}><CardTitleD as="h2" style={{ fontSize: 16 }}>{multi ? 'Vínculos bypassed — pontos selecionados' : `Vínculos bypassed — ${s.label}`}</CardTitleD></CardHeaderD>
    <CardContentD style={{ paddingTop: 0, overflowX: 'auto' }}>
     <table style={{ width: '100%', borderCollapse: 'collapse' }}>
      <thead><tr>{multi ? <ThD>Ponto</ThD> : null}<ThD>MAC</ThD><ThD>IP</ThD><ThD>Comentário</ThD><ThD>Server</ThD><ThD>Ação</ThD></tr></thead>
      <tbody>
       {vRows.map((b) => <tr key={b.__k + b.mac}>
        {multi ? <TdD>{b.__rot}</TdD> : null}<TdD mono>{b.mac}</TdD><TdD mono>{b.ip}</TdD><TdD>{b.comment}</TdD><TdD mono>{b.server || meta[b.__k].server}</TdD>
        <TdD><BtnMiniD tom="perigo" onClick={() => remover(b)}>Remover</BtnMiniD></TdD>
       </tr>)}
      </tbody>
     </table>
     {!vRows.length ? <div style={{ fontSize: 12.5, color: 'hsl(var(--muted-foreground))', padding: '14px 10px' }}>Nenhum vínculo bypassed neste ponto.</div> : null}
    </CardContentD>
   </CardD>
   </window.CargaBox>
  </div>
  <CardD>
   <CardHeaderD style={{ paddingBottom: 6 }}><CardTitleD as="h2" style={{ fontSize: 16 }}>Incluir MAC</CardTitleD></CardHeaderD>
   <CardContentD style={{ paddingTop: 4 }}>
    {multi ? <div style={{ marginBottom: 12 }}>
     <LabelD htmlFor="lb-ponto">Ponto de destino</LabelD>
     <div style={{ height: 6 }} />
     <SelD id="lb-ponto" value={alvo} onChange={e => setAlvo(e.target.value)}>{list.map(k => <option key={k} value={k}>{dados[k].label}</option>)}</SelD>
    </div> : null}
    <LabelD htmlFor="lb-mac">MAC do aparelho</LabelD>
    <div style={{ height: 6 }} />
    <InputD id="lb-mac" placeholder="AA:BB:CC:DD:EE:FF" value={mac} onChange={e => setMac(e.target.value)} style={{ fontFamily: 'var(--app-font-mono)' }} />
    <div style={{ height: 12 }} />
    <LabelD htmlFor="lb-com">Comentário (obrigatório)</LabelD>
    <div style={{ height: 6 }} />
    <InputD id="lb-com" placeholder="ex.: IMPRESSORA HP RECEPCAO" value={com} onChange={e => setCom(e.target.value)} />
    <div style={{ height: 12 }} />
    <div style={{ fontSize: 12, color: 'hsl(var(--muted-foreground))', lineHeight: 1.5, marginBottom: 12 }}>{`Server fixo do ponto: ${s.server}. O comentário identifica o aparelho no futuro — sem ele, a lista vira adivinhação.`}</div>
    <BtnD disabled={!pronto} onClick={incluir} style={{ width: '100%' }}>Gerar comando</BtnD>
   </CardContentD>
  </CardD>
 </div>;
}
Object.assign(window, { TelaInventario, TelaListaBranca });
