/**
 * Back office — equipa NetScreen.
 *
 * Quem tem acesso ao back office, com que perfil, e se tem a MFA configurada.
 *
 * **A MFA é obrigatória para toda a equipa** (D9 do spec, "não negociável") e o
 * login exige-a desde 21 Set. Quem aparecer aqui sem ela ainda não a configurou
 * — vai ser obrigado a isso no próximo login, e não entra sem. O alerta conta
 * quantos são, calculado dos dados, e desaparece sozinho quando for zero.
 */

const ROTULO_PERFIL_EQUIPA = {
  admin: { texto: 'Admin', detalhe: 'Vê e altera tudo, incluindo receita e cancelamentos' },
  operator: { texto: 'Operador', detalhe: 'Trabalho do dia a dia — sem receita nem cancelamentos' },
};

function ScreenAdminEquipa({ me }) {
  const [dados, setDados] = React.useState(null);
  const [erro, setErro] = React.useState(null);
  const [aConvidar, setAConvidar] = React.useState(false);
  const [mudancaAcesso, setMudancaAcesso] = React.useState(null);
  const [aRepor, setARepor] = React.useState(null);
  const [aReporMfa, setAReporMfa] = React.useState(null);
  const [aMudarPerfil, setAMudarPerfil] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const fecharToast = React.useCallback(() => setToast(null), []);

  const carregar = React.useCallback(
    () =>
      api
        .get('/api/admin/netscreen-users')
        .then(setDados)
        .catch((e) => setErro(e.message || 'Não foi possível ler a equipa.')),
    []
  );

  React.useEffect(() => {
    carregar();
  }, [carregar]);

  // Só o Admin convida (o servidor recusa na mesma; isto é o ecrã a não
  // oferecer um botão que dá 403).
  const podeConvidar = me?.user?.role === 'admin';

  const colunas = [
    {
      chave: 'nome', rotulo: 'Pessoa', principal: true, ordenavel: true,
      render: (u) => (
        <span>
          {u.nome}
          <span className="mt-0.5 block text-xs font-normal text-muted-foreground">{u.email}</span>
        </span>
      ),
    },
    {
      chave: 'perfil', rotulo: 'Perfil', ordenavel: true,
      render: (u) => {
        const p = ROTULO_PERFIL_EQUIPA[u.perfil] || { texto: u.perfil };
        return <Badge variante={u.perfil === 'admin' ? 'primario' : 'contorno'}>{p.texto}</Badge>;
      },
    },
    {
      chave: 'mfa', rotulo: 'MFA',
      valorOrdenacao: (u) => (u.mfa_configurada ? 1 : 0),
      render: (u) =>
        u.mfa_configurada ? (
          <Badge variante="sucesso">configurada</Badge>
        ) : u.convidado ? (
          // Vai configurá-la ao aceitar o convite. Marcar isto a vermelho era
          // pedir uma acção a quem não a pode fazer.
          <span className="text-xs text-muted-foreground">ao aceitar</span>
        ) : (
          <Badge variante="erro">por configurar</Badge>
        ),
    },
    {
      chave: 'ultimo_acesso', rotulo: 'Último acesso',
      valorOrdenacao: (u) => (u.ultimo_acesso ? new Date(u.ultimo_acesso).getTime() : null),
      render: (u) => {
        const d = desde(u.ultimo_acesso);
        return d ? d.texto : <span className="text-muted-foreground">nunca</span>;
      },
    },
    {
      chave: 'estado', rotulo: 'Estado',
      // Três estados e não dois. "Convidado" estava a aparecer como "activo",
      // o que fazia a lista contar como equipa quem nunca entrou.
      render: (u) => {
        if (u.desactivado) return <Badge variante="contorno">desactivado</Badge>;
        if (u.convidado) {
          const dias = u.convite_expira_em ? diasAte(u.convite_expira_em) : null;
          return (
            <span>
              <Badge variante="primario">convidado</Badge>
              <span className="mt-0.5 block text-xs font-normal text-muted-foreground">
                {dias === null ? 'sem convite' : dias < 0 ? 'convite caducado' : `caduca em ${dias} ${dias === 1 ? 'dia' : 'dias'}`}
              </span>
            </span>
          );
        }
        return <Badge variante="sucesso">activo</Badge>;
      },
    },
    // A coluna das acções só existe para o Admin. Para o Operator nem cabeçalho
    // tem: uma coluna vazia é uma pergunta sem resposta.
    ...(podeConvidar
      ? [
          {
            chave: 'accoes', rotulo: '', alinhamento: 'direita',
            render: (u) =>
              // A si próprio, não. O servidor recusa na mesma; isto evita
              // oferecer o botão que só serve para dar erro.
              u.id === me.user.id ? (
                <span className="text-xs text-muted-foreground">és tu</span>
              ) : (
                <span className="flex justify-end gap-2">
                  {/* Repor a password só faz sentido para quem já tem uma. Quem
                      foi convidado e não aceitou não tem password nenhuma. */}
                  {!u.desactivado && !u.convidado && (
                    <>
                      <button
                        type="button"
                        onClick={() => setAMudarPerfil(u)}
                        className="border border-border px-2 py-1 text-xs text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
                      >
                        {u.perfil === 'admin' ? 'Despromover' : 'Promover'}
                      </button>
                      <button
                        type="button"
                        onClick={() => setARepor(u)}
                        className="border border-border px-2 py-1 text-xs text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
                      >
                        Repor password
                      </button>
                      {/* Só faz sentido para quem já a configurou. */}
                      {u.mfa_configurada && (
                        <button
                          type="button"
                          onClick={() => setAReporMfa(u)}
                          className="border border-border px-2 py-1 text-xs text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
                        >
                          Repor MFA
                        </button>
                      )}
                    </>
                  )}
                  <button
                    type="button"
                    onClick={() => setMudancaAcesso({ pessoa: u, activo: u.desactivado })}
                    className="border border-border px-2 py-1 text-xs text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
                  >
                    {u.desactivado ? 'Devolver acesso' : u.convidado ? 'Anular convite' : 'Tirar acesso'}
                  </button>
                </span>
              ),
          },
        ]
      : []),
  ];

  if (erro) {
    return (
      <div className="space-y-6">
        <header>
          <h1 className="mt-1 font-display text-4xl uppercase leading-none tracking-wide">Equipa</h1>
        </header>
        <div className="border border-border bg-card px-6 py-12 text-center">
          <p className="font-display text-xl tracking-wide">Não deu para ler a equipa</p>
          <p className="mt-2 text-sm text-muted-foreground">{erro}</p>
        </div>
      </div>
    );
  }

  // Quem tem mesmo acesso: sem contar desactivados nem convites por aceitar.
  // Contar um convidado como "pessoa activa" fazia a lista dizer que a equipa
  // é maior do que é.
  const comAcesso = dados ? dados.utilizadores.filter((u) => !u.desactivado && !u.convidado).length : 0;
  const convidados = dados ? dados.utilizadores.filter((u) => !u.desactivado && u.convidado).length : 0;

  return (
    <div className="space-y-6">
      <header className="flex flex-wrap items-start justify-between gap-4">
        <div className="min-w-0">
          <h1 className="mt-1 font-display text-4xl uppercase leading-none tracking-wide">Equipa</h1>
          {dados && (
            <p className="mt-2 text-sm text-muted-foreground">
              {comAcesso} {comAcesso === 1 ? 'pessoa' : 'pessoas'} com acesso ao back office
              {convidados > 0 &&
                `, ${convidados} ${convidados === 1 ? 'convite por aceitar' : 'convites por aceitar'}`}
            </p>
          )}
        </div>
        {podeConvidar && (
          <button
            type="button"
            onClick={() => setAConvidar(true)}
            className="shrink-0 bg-primary px-4 py-2 text-xs uppercase tracking-wider text-primary-foreground outline-none hover:bg-primary/90 focus-visible:ring-1 focus-visible:ring-accent"
          >
            Convidar
          </button>
        )}
      </header>

      {dados && dados.sem_mfa > 0 && (
        <div className="border border-[hsl(var(--offline))] border-l-2 bg-[hsl(var(--offline)/0.08)] p-4" role="alert">
          <p className="text-sm text-foreground">
            <strong>
              {dados.sem_mfa} de {comAcesso} ainda sem MFA configurada.
            </strong>{' '}
            O login exige-a: quem estiver nesta situação vai ter de configurar a autenticação em dois
            passos no próximo acesso, e não entra sem isso. Não é preciso fazer nada daqui.
          </p>
        </div>
      )}

      <Tabela
        colunas={colunas}
        linhas={dados ? dados.utilizadores : []}
        carregando={!dados}
        chaveLinha={(u) => u.id}
        contagem={false}
        ordemInicial={{ chave: 'perfil', sentido: 'asc' }}
        vazio={{ titulo: 'Sem equipa', descricao: 'Não há ninguém com acesso ao back office. Corre o seed.' }}
      />

      <div className="border border-border bg-card p-4">
        <p className="label-eyebrow">O que cada perfil pode fazer</p>
        <dl className="mt-3 space-y-2">
          {Object.entries(ROTULO_PERFIL_EQUIPA).map(([k, p]) => (
            <div key={k} className="flex flex-wrap gap-x-3">
              <dt className="w-20 shrink-0 text-xs uppercase tracking-wider text-foreground">{p.texto}</dt>
              <dd className="text-xs text-muted-foreground">{p.detalhe}</dd>
            </div>
          ))}
        </dl>
      </div>

      <ModalConvidar
        aberto={aConvidar}
        equipa
        marca="NetScreen"
        onFechar={() => setAConvidar(false)}
        onConvidado={(mensagem) => {
          setAConvidar(false);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <ModalAcessoEquipa
        aberto={mudancaAcesso !== null}
        pessoa={mudancaAcesso?.pessoa}
        activo={mudancaAcesso?.activo}
        onFechar={() => setMudancaAcesso(null)}
        onConcluido={(mensagem) => {
          setMudancaAcesso(null);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <ModalReporPassword
        aberto={aRepor !== null}
        pessoa={aRepor}
        equipa
        onFechar={() => setARepor(null)}
        onConcluido={(mensagem) => {
          setARepor(null);
          setToast({ id: Date.now(), mensagem });
        }}
      />
      <ModalPerfilEquipa
        aberto={aMudarPerfil !== null}
        pessoa={aMudarPerfil}
        onFechar={() => setAMudarPerfil(null)}
        onConcluido={(mensagem) => {
          setAMudarPerfil(null);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <ModalReporMfa
        aberto={aReporMfa !== null}
        pessoa={aReporMfa}
        onFechar={() => setAReporMfa(null)}
        onConcluido={(mensagem) => {
          setAReporMfa(null);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <Toast toast={toast} onFechar={fecharToast} />
    </div>
  );
}
