/**
 * A página do convite — `/invite/:token`.
 *
 * É o único ecrã da aplicação que se abre **sem sessão nenhuma e sem login**:
 * quem chega aqui ainda não existe como utilizador. Por isso o `app.jsx`
 * trata-a antes de olhar para a sessão.
 *
 * Três estados: a verificar o link, o formulário, e o fim. O fim tem duas
 * versões, porque a conta pode ainda não estar activa — nesse caso a password
 * fica definida mas ainda não há para onde entrar, e mais vale dizê-lo do que
 * atirar a pessoa para um ecrã que a expulsa a seguir.
 */

/** O mínimo que o servidor aceita. Repetido aqui só para o botão poder esperar. */
const MINIMO_PASSWORD = 10;

function ForcaPassword({ password }) {
  const falta = MINIMO_PASSWORD - password.length;
  if (!password) return null;
  return (
    <p className={`mt-1 text-xs ${falta > 0 ? 'text-muted-foreground' : 'text-foreground'}`}>
      {falta > 0
        ? `Faltam ${falta} ${falta === 1 ? 'caractere' : 'caracteres'}.`
        : 'Comprimento suficiente.'}
    </p>
  );
}

function ScreenConvite({ token, equipa, repor }) {
  // Quatro caminhos, dois eixos: convite ou reposição, equipa ou cliente. O
  // ecrã é o mesmo porque o que a pessoa faz é o mesmo — escolher uma password
  // — e o que muda é o texto à volta e para onde vai a seguir.
  //
  // Os da equipa acabam na MFA e não numa sessão: a equipa entra sempre em dois
  // passos (D9), e mandá-la ao login só para reescrever a password que acabou
  // de escolher era um passo a mais.
  const raiz = repor
    ? (equipa ? `/api/repor/equipa/${token}` : `/api/repor/${token}`)
    : (equipa ? `/api/invites/equipa/${token}` : `/api/invites/${token}`);
  const [convite, setConvite] = React.useState(null);
  const [erroLink, setErroLink] = React.useState(null);
  const [password, setPassword] = React.useState('');
  const [repetida, setRepetida] = React.useState('');
  const [erro, setErro] = React.useState(null);
  const [aGuardar, setAGuardar] = React.useState(false);
  const [fim, setFim] = React.useState(null);
  const [passoMfa, setPassoMfa] = React.useState(null);

  React.useEffect(() => {
    api
      .get(raiz)
      .then(setConvite)
      // O 404 é o link gasto, caducado ou substituído, e o texto de baixo já o diz: a frase do servidor
      // repetia o «pede outro» (agentes, 20 Out). Outra falha mostra-se como veio.
      .catch(err => setErroLink(err.status === 404 ? true : err.message));
  }, [raiz]);

  const iguais = password.length > 0 && password === repetida;
  const pronto = password.length >= MINIMO_PASSWORD && iguais;

  async function submeter(e) {
    e.preventDefault();
    setErro(null);
    setAGuardar(true);
    try {
      const r = await api.post(`${raiz}/accept`, { password });
      // A equipa fica a meio do segundo passo: o servidor já pôs o `mfaPendente`
      // e o que falta é o QR. Recarregar levaria ao login e perdia esse estado,
      // por isso o ecrã da MFA é montado aqui mesmo.
      if (r.mfa) {
        setPassoMfa(r.mfa);
        return;
      }
      if (r.entrou) {
        // Sessão aberta do lado do servidor: recarregar leva a pessoa ao seu
        // dashboard pelo caminho normal, sem duplicar aqui a lógica do router.
        // A equipa (sem MFA, EQUIPA_MFA=0) não tem conta: vai para a raiz, que a leva ao back office.
        window.location.href = r.account_slug ? `/${r.account_slug}/dashboard` : '/';
        return;
      }
      setFim(r);
    } catch (err) {
      setErro(err.message);
      setAGuardar(false);
    }
  }

  if (passoMfa === 'configurar') {
    return (
      <MfaConfigurar
        email={convite?.email}
        onEntrou={() => window.location.assign('/admin')}
        onCancelar={() => window.location.assign('/')}
      />
    );
  }
  if (passoMfa === 'verificar') {
    return (
      <MfaVerificar
        email={convite?.email}
        onEntrou={() => window.location.assign('/admin')}
        onCancelar={() => window.location.assign('/')}
      />
    );
  }

  if (erroLink) {
    return (
      <CartaoAuth sobretitulo={repor ? 'Password' : 'Convite'} titulo="Este link já não serve">
        {erroLink !== true && <p className="mt-4 text-sm text-muted-foreground">{erroLink}</p>}
        {/* O token gasto apaga-se da base, por isso o servidor não distingue um link já usado de um
            caducado: quem já escolheu a password tem a entrada aqui, e não um «pede outro» (agentes, 20 Out). */}
        <p className="mt-4 text-sm text-muted-foreground">
          {repor ? 'Se já mudaste a password com este link' : 'Se já escolheste a password com este link'}, entra
          com o teu email e essa password.
        </p>
        <a href="/" className="mt-4 inline-flex min-h-10 items-center bg-primary px-4 py-2 text-sm text-primary-foreground hover:bg-primary/90">
          Entrar
        </a>
        <p className="mt-4 text-sm text-muted-foreground">
          Se não, pede outro a quem to enviou. Cada link serve uma vez e vale sete dias, e pedir outro desliga o
          anterior.
        </p>
      </CartaoAuth>
    );
  }

  if (fim) {
    return (
      <CartaoAuth sobretitulo="Convite" titulo="Password definida">
        <p className="mt-4 text-sm text-muted-foreground">{fim.mensagem}</p>
        <p className="mt-4 text-sm text-muted-foreground">
          Quando a conta {fim.marca ? <span className="text-foreground">{fim.marca}</span> : null} estiver
          pronta, entras em <a href="/" className="text-primary hover:underline">netscreen.ai</a> com o teu
          email e esta password.
        </p>
      </CartaoAuth>
    );
  }

  if (!convite) {
    return (
      <CartaoAuth sobretitulo="Convite" titulo="Um momento">
        <div className="mt-6 h-32 animate-pulse bg-muted" aria-label="A verificar o convite" />
      </CartaoAuth>
    );
  }

  // "Olá" e não "Bem-vindo": não sabemos o género de quem foi convidado — a
  // equipa NetScreen convida com nome e email, e mais nada. O mesmo vale para a
  // frase a seguir: "o convite é para" em vez de "foste convidado".
  return (
    <CartaoAuth
      sobretitulo={repor ? 'Password' : 'Convite'}
      titulo={repor ? 'Escolhe uma password nova' : `Olá, ${convite.nome.split(' ')[0]}`}
    >
      <p className="mt-4 text-sm text-muted-foreground">
        {repor ? (
          <>
            Para <span className="text-foreground">{convite.email}</span>
            {convite.equipa ? '' : <> na conta <span className="text-foreground">{convite.marca}</span></>}.
            {convite.equipa
              ? ' A autenticação em dois passos não muda: continuas a precisar do mesmo telemóvel.'
              : ' A password anterior deixa de funcionar, e as sessões abertas são fechadas.'}
          </>
        ) : convite.equipa ? (
          <>
            Vais passar a fazer parte da <span className="text-foreground">equipa NetScreen</span>.
            Escolhe uma password para <span className="text-foreground">{convite.email}</span>{convite.mfa === false ? '.' : <> — a
            seguir configuras a autenticação em dois passos, que é obrigatória para a equipa.</>}
          </>
        ) : (
          <>
            O convite é para a conta <span className="text-foreground">{convite.marca}</span> na
            NetScreen AI. Escolhe uma password para{' '}
            <span className="text-foreground">{convite.email}</span>.
          </>
        )}
      </p>

      <form onSubmit={submeter} className="mt-6 space-y-4" noValidate>
        <div>
          <label htmlFor="password" className="label-eyebrow block">
            Password
          </label>
          <input
            id="password"
            name="password"
            type="password"
            /* `new-password` diz ao gestor de passwords para oferecer uma nova
               em vez de tentar preencher com uma que não existe. */
            autoComplete="new-password"
            value={password}
            onChange={e => setPassword(e.target.value)}
            disabled={aGuardar}
            autoFocus
            required
            className="mt-2 w-full border border-border bg-background px-3 py-2.5 text-sm text-foreground
                       focus:border-primary focus:outline-none disabled:opacity-50"
          />
          <ForcaPassword password={password} />
        </div>

        <div>
          <label htmlFor="repetida" className="label-eyebrow block">
            Outra vez
          </label>
          <input
            id="repetida"
            name="repetida"
            type="password"
            autoComplete="new-password"
            value={repetida}
            onChange={e => setRepetida(e.target.value)}
            disabled={aGuardar}
            required
            className="mt-2 w-full border border-border bg-background px-3 py-2.5 text-sm text-foreground
                       focus:border-primary focus:outline-none disabled:opacity-50"
          />
          {repetida.length > 0 && !iguais && (
            <p className="mt-1 text-xs text-muted-foreground">As duas não são iguais.</p>
          )}
        </div>

        {erro && <ErroAuth>{erro}</ErroAuth>}

        <BotaoAuth disabled={aGuardar || !pronto}>
          {aGuardar ? 'A guardar...' : 'Definir password'}
        </BotaoAuth>
      </form>

      <p className="mt-6 text-xs text-muted-foreground">
        Pelo menos {MINIMO_PASSWORD} caracteres. Uma frase que só tu saibas é melhor do que uma palavra
        com símbolos no meio.
      </p>
    </CartaoAuth>
  );
}
