// Acessos e permissões da organização cliente (MINHA ORGANIZAÇÃO): matriz Área × Ação por papel, origem de cada
// permissão (padrão do papel, exceção do tenant, bloqueio do teto), exceções por papel e histórico auditado.
// Tudo vem do banco (get_org_permission_matrix / audit_events); a tela só pede a exceção e o servidor decide:
// hierarquia, teto da persona e "não conceder acima do que detém" são validados lá, nunca aqui.
const VX_ROLE_ORDER = ['CLIENT_OWNER', 'CLIENT_ADMIN', 'CLIENT_MANAGER', 'CLIENT_OPERATOR', 'CLIENT_VIEWER'];
const VX_ROLE_LABEL = { CLIENT_OWNER: 'Proprietário', CLIENT_ADMIN: 'Administrador', CLIENT_MANAGER: 'Gestor', CLIENT_OPERATOR: 'Operador', CLIENT_VIEWER: 'Visualizador' };
const VX_ACTIONS = ['view', 'create', 'edit', 'delete', 'export', 'approve', 'manage'];
const VX_ACTION_LABEL = { view: 'Ver', create: 'Criar', edit: 'Editar', delete: 'Excluir', export: 'Exportar', approve: 'Aprovar', manage: 'Gerir' };
const VX_ORIGIN_LABEL = { default: 'Padrão do papel', override_grant: 'Liberado pela organização', override_deny: 'Restringido pela organização', ceiling: 'Bloqueado (uso interno Vértice)', none: 'Sem acesso por padrão' };

function AccessScreen() {
  const { PageHeader, Alert, Card, Badge, Skeleton, EmptyState, Button } = window.VRticeDesignSystem_d763eb;
  const { toast } = useShell();
  const { can } = useAccess();
  const orgSt = useActiveOrg();
  const org = orgSt.org;
  const [roleKey, setRoleKey] = React.useState('CLIENT_OPERATOR');
  const [busy, setBusy] = React.useState('');
  const [st, reload] = useRemote(() => org ? window.VxAccessAdmin.loadOrgMatrix(window.VxAuth.db(), org.id) : Promise.resolve(null), [org && org.id]);
  const [hist, reloadHist] = useRemote(() => org ? window.VxAccessAdmin.listAccessAudit(window.VxAuth.db(), { orgId: org.id, limit: 40 }) : Promise.resolve([]), [org && org.id]);
  const cells = (st.data && st.data[roleKey]) || [];
  const byRes = cells.reduce((a, c) => { (a[c.resource] = a[c.resource] || {})[c.action] = c; return a; }, {});
  const resources = Object.keys(byRes).filter(r => Object.values(byRes[r]).some(c => c.origin !== 'ceiling')).sort();
  const locked = roleKey === 'CLIENT_OWNER';

  async function toggle(c) {
    // default/liberado -> restringe; sem acesso/restringido -> libera; a exceção que já existe volta ao padrão.
    const next = c.origin === 'override_grant' || c.origin === 'override_deny' ? null : !c.effective;
    setBusy(c.key);
    try {
      await window.VxAccessAdmin.setRoleOverride(window.VxAuth.db(), { orgId: org.id, roleKey, permissionKey: c.key, granted: next, reason: 'Ajuste pela tela Acessos e permissões' });
      toast(next === null ? 'Voltou ao padrão do papel' : next ? 'Permissão liberada para o papel' : 'Permissão restringida para o papel', 'ph-check-circle');
      reload(); reloadHist();
      try { window.dispatchEvent(new Event('vx-context-changed')); } catch (e) { /* recarrega as permissões da própria sessão */ }
    } catch (e) { toast(e.message || 'Não foi possível alterar.', 'ph-warning'); }
    finally { setBusy(''); }
  }

  const tone = c => c.origin === 'ceiling' ? 'neutral' : c.effective ? (c.origin === 'override_grant' ? 'info' : 'success') : (c.origin === 'override_deny' ? 'warning' : 'neutral');
  return (
    <>
      <PageHeader size="lg" eyebrow="MINHA ORGANIZAÇÃO" title="Acessos e permissões" description="O que cada papel da sua organização pode ver e fazer, por área e ação. Ajustes valem só para a sua organização." />
      {!can('users.manage') && <Alert tone="warning" title="Somente leitura">Alterar permissões exige a permissão de administrar usuários.</Alert>}
      <Alert tone="info" title="Como funciona">O padrão de cada papel é definido pela plataforma. Você pode restringir ou liberar uma permissão para um papel da sua organização, dentro do limite do seu próprio acesso. Aprovações, exportações, financeiro e administração de usuários têm permissões próprias. Itens de uso interno da Vértice não podem ser liberados.</Alert>
      {orgSt.loading || st.loading ? <Skeleton height={260} radius={20} />
        : !org ? <EmptyState variant="block" icon="ph-buildings" title="Nenhuma organização ativa">Selecione uma organização para ver as permissões.</EmptyState>
        : st.error ? <Alert tone="danger" title="Não foi possível carregar">{st.error}</Alert>
        : <>
          <div role="tablist" aria-label="Papel" style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            {VX_ROLE_ORDER.map(k => <button key={k} type="button" role="tab" aria-selected={roleKey === k} onClick={() => setRoleKey(k)} className="vx-row" style={{ cursor: 'pointer', padding: '8px 14px', borderRadius: 999, border: '1px solid var(--border-subtle)', background: roleKey === k ? 'var(--overlay-06)' : 'transparent', color: 'inherit', fontFamily: 'inherit', fontSize: 14, fontWeight: roleKey === k ? 600 : 400 }}>{VX_ROLE_LABEL[k]}</button>)}
          </div>
          {locked && <Alert tone="info" title="Proprietário">O proprietário administra a organização e não pode ser restringido por exceção.</Alert>}
          <Card variant="flat" padding="20px 24px" gap={0}>
            <div style={{ overflowX: 'auto' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 14 }}>
                <thead><tr><th style={{ textAlign: 'left', padding: '8px 10px', fontWeight: 600 }}>Área</th>{VX_ACTIONS.map(a => <th key={a} style={{ padding: '8px 10px', fontWeight: 600 }}>{VX_ACTION_LABEL[a]}</th>)}</tr></thead>
                <tbody>{resources.map(r => <tr key={r} style={{ borderTop: '1px solid var(--border-subtle)' }}>
                  <td style={{ padding: '8px 10px', fontFamily: 'var(--font-mono)', fontSize: 13 }}>{r}</td>
                  {VX_ACTIONS.map(a => { const c = byRes[r][a]; return <td key={a} style={{ textAlign: 'center', padding: '6px 8px' }}>
                    {!c ? <span aria-hidden="true" style={{ color: 'var(--text-muted)' }}>·</span>
                      : <button type="button" disabled={locked || !can('users.manage') || busy === c.key || c.origin === 'ceiling'} onClick={() => toggle(c)} title={VX_ORIGIN_LABEL[c.origin]} aria-label={r + ' ' + VX_ACTION_LABEL[a] + ': ' + (c.effective ? 'permitido' : 'negado') + ' — ' + VX_ORIGIN_LABEL[c.origin]} style={{ cursor: locked || !can('users.manage') ? 'default' : 'pointer', background: 'none', border: 'none', padding: 2 }}>
                        <Badge variant="meta" tone={tone(c)}>{c.effective ? 'Sim' : 'Não'}{c.origin === 'override_grant' || c.origin === 'override_deny' ? ' *' : ''}</Badge>
                      </button>}
                  </td>; })}
                </tr>)}</tbody>
              </table>
            </div>
            <span style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 12 }}>* exceção da sua organização (clique para voltar ao padrão). A decisão final é sempre do servidor.</span>
          </Card>
          <Card variant="flat" padding="20px 24px" gap={10}>
            <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>Histórico de alterações</h3>
            {hist.loading ? <Skeleton height={80} radius={12} />
              : hist.error ? <span style={{ color: 'var(--text-muted)' }}>Histórico indisponível para a sua conta.</span>
              : !(hist.data || []).length ? <span style={{ color: 'var(--text-muted)' }}>Nenhuma alteração registrada ainda.</span>
              : (hist.data || []).map(h => <div key={h.id} style={{ display: 'flex', gap: 10, flexWrap: 'wrap', borderTop: '1px solid var(--border-subtle)', paddingTop: 8, fontSize: 13 }}>
                <span style={{ color: 'var(--text-muted)', minWidth: 130 }}>{new Date(h.occurred_at).toLocaleString('pt-BR')}</span>
                <span style={{ fontFamily: 'var(--font-mono)' }}>{h.permission_key || '—'}</span>
                <span>{h.entity === 'organization_role_overrides' ? (VX_ROLE_LABEL[h.role_key] || h.role_key) : h.entity === 'permission_grants' ? 'usuário' : h.entity === 'membership_roles' ? 'papel de ' + (VX_ROLE_LABEL[h.role_key] || h.role_key) : h.entity === 'org_profile' ? 'dados da organização' : h.entity === 'profile' ? 'perfil' : 'vínculo'}</span>
                <Badge variant="meta" tone={h.granted === false || /removed|revoked/.test(h.action) ? 'warning' : 'info'}>{/removed|revoked/.test(h.action) ? 'removida' : h.granted === false ? 'restringida' : /created|assigned/.test(h.action) ? 'liberada' : 'alterada'}</Badge>
                {h.reason && <span style={{ color: 'var(--text-muted)' }}>{h.reason}</span>}
              </div>)}
          </Card>
        </>}
    </>
  );
}
window.AccessScreen = AccessScreen;
