// Auditoria: trilha REAL de mudanças de acesso (papéis, concessões, associações e catálogo), somente leitura.
// Visível a quem tem audit.view (Owner, auditor externo AUDIT_READER); exportar exige audit.export.
const AUDIT_LABEL = {
  'membership_role.assigned': 'Papel atribuído', 'membership_role.revoked': 'Papel revogado', 'membership_role.changed': 'Papel alterado',
  'permission_grant.created': 'Permissão concedida', 'permission_grant.removed': 'Permissão removida', 'permission_grant.changed': 'Permissão alterada',
  'membership.created': 'Membro adicionado', 'membership.removed': 'Membro removido', 'membership.status_changed': 'Situação do membro alterada',
  'discovery_config.created': 'Coleta: configuração criada', 'discovery_config.changed': 'Coleta: configuração alterada', 'discovery_config.removed': 'Coleta: configuração removida',
  'org_override.created': 'Exceção do tenant criada', 'org_override.changed': 'Exceção do tenant alterada', 'org_override.removed': 'Exceção do tenant removida',
  'org_profile.updated': 'Dados da organização alterados', 'profile.updated_by_other': 'Perfil de usuário alterado por outra pessoa',
  'catalog.role_permission_added': 'Catálogo: permissão adicionada a papel', 'catalog.role_permission_removed': 'Catálogo: permissão removida de papel', 'catalog.role_permission_changed': 'Catálogo: papel alterado',
};
const auditDetails = e => { const d = e.details || {}; const parts = []; if (d.role_key) parts.push('papel ' + d.role_key); if (d.permission) parts.push((d.granted === false ? 'negada ' : '') + d.permission); if (d.changed) for (const [k, v] of Object.entries(d.changed)) parts.push(k + (v && v.changed ? ' alterado' : ': ' + JSON.stringify(v.from) + ' → ' + JSON.stringify(v.to))); if (d.db_user && /^discovery_config/.test(e.action)) parts.push('via ' + d.db_user); if (d.fields) parts.push('campos ' + d.fields.join(', ')); if (d.reason) parts.push('motivo: ' + d.reason); if (d.status) parts.push('situação ' + d.status + (d.previous_status ? ' (antes ' + d.previous_status + ')' : '')); return parts.join(' · ') || '—'; };

function AuditScreen() {
  const { PageHeader, Alert, Card, Input, Button, Skeleton, EmptyState } = window.VRticeDesignSystem_d763eb;
  const { toast } = useShell();
  const [rows, setRows] = React.useState([]), [state, setState] = React.useState({ loading: true, error: '', more: false }), [q, setQ] = React.useState(''), [names, setNames] = React.useState({});
  const PAGE = 100;
  const load = async (reset) => {
    setState(s => ({ ...s, loading: true, error: '' }));
    try {
      const before = !reset && rows.length ? rows[rows.length - 1].occurred_at : null;
      const got = await window.VxAccessAdmin.listAudit(window.VxAuth.db(), { limit: PAGE, before, text: q });
      const all = reset ? got : [...rows, ...got];
      setRows(all); setState({ loading: false, error: '', more: got.length === PAGE });
      const ids = [...new Set(all.flatMap(e => [e.actor_user_id, e.target_user_id]).filter(Boolean))].filter(id => !names[id]);
      if (ids.length) { const p = await window.VxAuth.db().from('profiles').select('id,full_name,display_name').in('id', ids); if (!p.error) setNames(n => ({ ...n, ...Object.fromEntries((p.data || []).map(x => [x.id, x.full_name || x.display_name])) })); }
    } catch (e) { setState({ loading: false, error: e.message, more: false }); }
  };
  React.useEffect(() => { load(true); }, []);
  const who = id => id ? (names[id] || 'Usuário ' + String(id).slice(0, 8)) : 'Sistema';
  const notReady = /42P01|PGRST205|audit_events/i.test(state.error);
  const exportCsv = () => {
    const n = window.VxSafe.downloadCsv('auditoria-' + new Date().toISOString().slice(0, 10) + '.csv', ['Quando', 'Ação', 'Quem', 'Alvo', 'Detalhes', 'Organização'], rows.map(e => [e.occurred_at, AUDIT_LABEL[e.action] || e.action, who(e.actor_user_id), who(e.target_user_id), auditDetails(e), e.organization_id || '']));
    toast(n + ' registros exportados', 'ph-export');
  };
  return (
    <>
      <PageHeader size="lg" eyebrow="AUDITORIA" title="Auditoria" description="Registro de mudanças de acesso: quem concedeu ou revogou o quê, e quando. Somente leitura." actions={<PBtn perm="audit.export" variant="secondary" icon="ph-export" onClick={exportCsv} disabled={!rows.length}>Exportar CSV</PBtn>} />
      <Alert tone="info" title="O que a trilha registra">Atribuição e revogação de papéis, concessões de permissão, entrada, saída e suspensão de membros e mudanças do catálogo de permissões. Não registra conteúdo de negócio. Os registros não podem ser alterados nem apagados.</Alert>
      <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'flex-end' }}>
        <div style={{ flex: '1 1 260px', maxWidth: 420 }}><Input icon="ph-magnifying-glass" placeholder="Filtrar por ação (ex.: papel, permissão, membro)" value={q} onChange={e => setQ(e.target.value)} /></div>
        <Button variant="secondary" onClick={() => load(true)}>Buscar</Button>
      </div>
      {state.loading && !rows.length ? <Skeleton height={220} radius={20} />
        : notReady ? <Alert tone="warning" title="Trilha de auditoria ainda não ativada neste ambiente">A tabela de auditoria ainda não existe no banco deste ambiente. Ela é criada por uma migration que aguarda aprovação para ser aplicada.</Alert>
        : state.error ? <Alert tone="danger" title="Não foi possível carregar">{state.error}</Alert>
        : !rows.length ? <EmptyState variant="block" icon="ph-list-magnifying-glass" title="Nenhum evento registrado">Ainda não há mudanças de acesso registradas para o que você pode ver.</EmptyState>
        : <Card variant="flat" padding={0} gap={0} style={{ overflow: 'hidden' }}>
          <VxTable id="auditoria" cellX={20} rowY={12} minWidth={900} rows={rows} columns={[
            { key: 'occurred_at', label: 'Quando', width: '160px', render: e => vxDateTime(e.occurred_at) },
            { key: 'action', label: 'Ação', width: '280px', sort: e => AUDIT_LABEL[e.action] || e.action, render: e => <strong style={{ fontWeight: 600 }}>{AUDIT_LABEL[e.action] || e.action}</strong> },
            { key: 'actor', label: 'Quem fez', width: '200px', sort: e => who(e.actor_user_id), render: e => who(e.actor_user_id) },
            { key: 'target', label: 'Afetado', width: '200px', sort: e => who(e.target_user_id), render: e => e.target_user_id ? who(e.target_user_id) : <span style={{ color: 'var(--text-muted)' }}>—</span> },
            { key: 'details', label: 'Detalhes', width: '320px', sortable: false, render: e => <span style={{ overflowWrap: 'anywhere' }}>{auditDetails(e)}</span> },
          ]} />
          {state.more && <div style={{ padding: 16 }}><Button variant="secondary" onClick={() => load(false)} disabled={state.loading}>{state.loading ? 'Carregando…' : 'Carregar mais'}</Button></div>}
        </Card>}
    </>
  );
}
window.AuditScreen = AuditScreen;
