'use client';

import Link from 'next/link';
import { RequireRole } from '@/lib/auth-context';
import type { UserRole } from '@/lib/auth';
import { ROLE_BADGES, ROLE_LABELS } from '@/lib/services/users';
import { BackLink, PageHeader } from '@/components/app/ui';

export default function PermissoesPage() {
  return (
    <RequireRole roles={['admin']}>
      <PermissionsView />
    </RequireRole>
  );
}

/** full = acesso total · own = apenas os próprios registros · none = sem acesso */
type Access = 'full' | 'own' | 'none';

interface Permission {
  action: string;
  access: Record<UserRole, Access>;
}

interface PermissionArea {
  area: string;
  icon: string;
  permissions: Permission[];
}

const STAFF_ONLY: Record<UserRole, Access> = {
  admin: 'full',
  receptionist: 'full',
  dentist: 'full',
  patient: 'none',
};

const STAFF_AND_OWN: Record<UserRole, Access> = { ...STAFF_ONLY, patient: 'own' };

const ADMIN_ONLY: Record<UserRole, Access> = {
  admin: 'full',
  receptionist: 'none',
  dentist: 'none',
  patient: 'none',
};

// Espelha os @Roles dos controllers da API (apps/api/src/modules/*/*.controller.ts).
// Ao mudar uma regra lá, atualize esta tabela.
const MATRIX: PermissionArea[] = [
  {
    area: 'Pacientes',
    icon: 'bi-people',
    permissions: [
      { action: 'Consultar cadastro', access: STAFF_AND_OWN },
      { action: 'Cadastrar e editar', access: STAFF_ONLY },
      { action: 'Excluir', access: ADMIN_ONLY },
      { action: 'Contatos — ver', access: STAFF_AND_OWN },
      { action: 'Contatos — gerenciar', access: STAFF_ONLY },
      { action: 'Consentimentos (LGPD)', access: STAFF_AND_OWN },
      {
        action: 'Histórico clínico — ver',
        access: { admin: 'full', receptionist: 'none', dentist: 'full', patient: 'own' },
      },
      {
        action: 'Histórico clínico — editar',
        access: { admin: 'full', receptionist: 'none', dentist: 'full', patient: 'none' },
      },
      { action: 'Documentos — ver', access: STAFF_AND_OWN },
      { action: 'Documentos — enviar e remover', access: STAFF_ONLY },
    ],
  },
  {
    area: 'Agenda',
    icon: 'bi-calendar3',
    permissions: [
      { action: 'Ver agenda da clínica', access: STAFF_ONLY },
      { action: 'Agendar, cancelar e remarcar', access: STAFF_AND_OWN },
      { action: 'Alterar status e observações', access: STAFF_ONLY },
      { action: 'Bloqueios de agenda', access: STAFF_ONLY },
      {
        action: 'Concluir / falta (dentista: só as próprias consultas)',
        access: { admin: 'full', receptionist: 'full', dentist: 'own', patient: 'none' },
      },
    ],
  },
  {
    area: 'Tratamentos e orçamentos',
    icon: 'bi-clipboard2-check',
    permissions: [
      { action: 'Catálogo de procedimentos — ver', access: STAFF_ONLY },
      { action: 'Catálogo de procedimentos — gerenciar', access: ADMIN_ONLY },
      {
        action: 'Ver planos e orçamentos',
        access: { admin: 'full', receptionist: 'full', dentist: 'own', patient: 'own' },
      },
      {
        action: 'Criar, editar e enviar orçamento',
        access: { admin: 'full', receptionist: 'none', dentist: 'own', patient: 'none' },
      },
      {
        action: 'Aprovar / recusar orçamento',
        access: { admin: 'full', receptionist: 'full', dentist: 'own', patient: 'own' },
      },
      {
        action: 'Registrar procedimento realizado / cancelar plano',
        access: { admin: 'full', receptionist: 'none', dentist: 'own', patient: 'none' },
      },
    ],
  },
  {
    area: 'Exames',
    icon: 'bi-file-earmark-medical',
    permissions: [
      { action: 'Ver pedidos de exame', access: STAFF_AND_OWN },
      { action: 'Marcar data e local', access: STAFF_ONLY },
      {
        action: 'Pedir exame e liberar resultado',
        access: { admin: 'full', receptionist: 'none', dentist: 'full', patient: 'none' },
      },
      {
        action: 'Ver laudo e arquivos de resultado',
        access: { admin: 'full', receptionist: 'none', dentist: 'full', patient: 'own' },
      },
    ],
  },
  {
    area: 'Financeiro',
    icon: 'bi-cash-coin',
    permissions: [
      {
        action: 'Cobranças, recebimentos e recibos',
        access: { admin: 'full', receptionist: 'full', dentist: 'none', patient: 'own' },
      },
      {
        action: 'Pagar online (portal)',
        access: { admin: 'none', receptionist: 'none', dentist: 'none', patient: 'own' },
      },
      { action: 'Estornar pagamento', access: ADMIN_ONLY },
      {
        action: 'Relatórios',
        access: { admin: 'full', receptionist: 'full', dentist: 'own', patient: 'none' },
      },
    ],
  },
  {
    area: 'Dentistas',
    icon: 'bi-person-badge',
    permissions: [
      { action: 'Cadastrar, excluir e enviar foto', access: ADMIN_ONLY },
      {
        action: 'Editar perfil e horários de atendimento',
        access: { admin: 'full', receptionist: 'none', dentist: 'own', patient: 'none' },
      },
    ],
  },
  {
    area: 'Especialidades',
    icon: 'bi-clipboard2-pulse',
    permissions: [{ action: 'Cadastrar, editar e remover', access: ADMIN_ONLY }],
  },
  {
    area: 'Mensagens de contato',
    icon: 'bi-envelope',
    permissions: [
      {
        action: 'Ler e alterar status',
        access: { admin: 'full', receptionist: 'full', dentist: 'none', patient: 'none' },
      },
      { action: 'Excluir', access: ADMIN_ONLY },
    ],
  },
  {
    area: 'Site e configurações',
    icon: 'bi-window-stack',
    permissions: [
      { action: 'Páginas do site', access: ADMIN_ONLY },
      { action: 'Configurações da clínica — editar', access: ADMIN_ONLY },
    ],
  },
  {
    area: 'Administração',
    icon: 'bi-person-gear',
    permissions: [
      { action: 'Usuários e senhas', access: ADMIN_ONLY },
      { action: 'Trilha de auditoria', access: ADMIN_ONLY },
    ],
  },
];

const ROLES = Object.keys(ROLE_LABELS) as UserRole[];

function AccessCell({ access }: { access: Access }) {
  if (access === 'full') {
    return (
      <>
        <i className="bi bi-check-circle-fill text-success" aria-hidden="true" />
        <span className="visually-hidden">Permitido</span>
      </>
    );
  }
  if (access === 'own') {
    return <span className="badge text-bg-warning">só os próprios</span>;
  }
  return (
    <>
      <i className="bi bi-dash text-secondary" aria-hidden="true" />
      <span className="visually-hidden">Sem acesso</span>
    </>
  );
}

function PermissionsView() {
  return (
    <>
      <BackLink href="/painel/usuarios" label="Usuários" />
      <PageHeader
        title="Permissões por papel"
        subtitle="O que cada papel pode fazer no sistema"
      />

      <div className="alert alert-info d-flex" role="note">
        <i className="bi bi-info-circle-fill me-2 mt-1" />
        <div>
          As permissões são fixas por papel. Para mudar o que alguém pode fazer,
          altere o papel do usuário em{' '}
          <Link href="/painel/usuarios" className="alert-link">
            Usuários
          </Link>
          . Consulta de dentistas, especialidades e horários livres é pública
          (site e agendamento online).
        </div>
      </div>

      <div className="card border-0 shadow-sm">
        <div className="table-responsive">
          <table className="table align-middle mb-0">
            <thead className="table-light">
              <tr>
                <th scope="col">Ação</th>
                {ROLES.map((role) => (
                  <th key={role} scope="col" className="text-center">
                    <span className={`badge ${ROLE_BADGES[role]}`}>
                      {ROLE_LABELS[role]}
                    </span>
                  </th>
                ))}
              </tr>
            </thead>
            {MATRIX.map((group) => (
              <tbody key={group.area}>
                <tr className="table-group-divider">
                  <th scope="rowgroup" colSpan={ROLES.length + 1} className="bg-light">
                    <i className={`bi ${group.icon} me-2`} aria-hidden="true" />
                    {group.area}
                  </th>
                </tr>
                {group.permissions.map((permission) => (
                  <tr key={permission.action}>
                    <td>{permission.action}</td>
                    {ROLES.map((role) => (
                      <td key={role} className="text-center">
                        <AccessCell access={permission.access[role]} />
                      </td>
                    ))}
                  </tr>
                ))}
              </tbody>
            ))}
          </table>
        </div>
      </div>
    </>
  );
}
