/**
 * Configuração da conta — do lado do cliente.
 *
 * Por agora só tem utilizadores, que é a parte que já tem API
 * (`api/config.js`). O brand kit, a base de conhecimento e o agente entram
 * aqui como separadores quando existirem; a estrutura já os espera.
 *
 * O que este ecrã resolve: até agora, um cliente que quisesse dar acesso a um
 * colega tinha de pedir por email à NetScreen. Passa a fazê-lo sozinho, dentro
 * do que o plano lhe dá.
 */

const PERFIS_CLIENTE = {
  owner: { texto: 'Responsável', detalhe: 'Gere a conta, os utilizadores e a facturação' },
  editor: { texto: 'Editor', detalhe: 'Cria, edita, aprova e apaga campanhas' },
  viewer: { texto: 'Leitura', detalhe: 'Vê resultados, não altera nada' },
};

/**
 * Quantos lugares o plano dá e quantos estão ocupados.
 *
 * `null` no limite é ilimitado — e não se escreve "∞" porque ninguém diz isso
 * em voz alta. Quando faltam um ou nenhum, o aviso muda de tom: é a diferença
 * entre uma informação e uma coisa a resolver.
 */
function Lugares({ lugares }) {
  const { ocupados, limite } = lugares;
  if (limite === null) {
    return (
      <p className="text-sm text-muted-foreground">
        {ocupados} {ocupados === 1 ? 'pessoa' : 'pessoas'} nesta conta. O teu plano não tem limite.
      </p>
    );
  }

  const livres = limite - ocupados;
  return (
    <p className={`text-sm ${livres <= 0 ? 'text-foreground' : 'text-muted-foreground'}`}>
      {ocupados} de {limite} {limite === 1 ? 'lugar ocupado' : 'lugares ocupados'}
      {livres <= 0 ? (
        <>
          {' '}— <span className="text-primary">não há lugares livres</span>. Retira o acesso a alguém
          ou fala com a NetScreen para mudar de plano.
        </>
      ) : (
        `, ${livres} ${livres === 1 ? 'livre' : 'livres'}.`
      )}
    </p>
  );
}

/**
 * O plano e o consumo (28 Set): estavam no rodapé do menu e num cartão do
 * dashboard, e passam a viver na Conta, ao lado de quem lá trabalha. Os números
 * são os do `GET /api/:slug/dashboard`; se falhar, a secção diz que não deu e o
 * resto da página segue.
 */
function ContaPlano({ slug, plano }) {
  const [d, setD] = React.useState(null);
  React.useEffect(() => {
    setD(null);
    api.get(`/api/${slug}/dashboard`).then(setD).catch(() => setD(false));
  }, [slug]);
  return (
    <section className="border border-border bg-card p-5">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <h2 className="ns-seccao-titulo">O plano e o consumo</h2>
        {plano && <PlanBadge plano={plano} />}
      </div>
      {d === null ? (
        <div className="loading-skeleton mt-4 h-16" />
      ) : d === false ? (
        <p className="mt-3 text-xs text-muted-foreground">Não deu para ler o consumo agora.</p>
      ) : (
        <div className="mt-4 grid gap-5 md:grid-cols-3">
          <BarraUso rotulo="Campanhas no ar" usado={d.numeros.campanhas_activas} limite={d.numeros.max_campanhas_activas} />
          {d.carteira && (
            <BarraUso
              rotulo="Créditos de IA do mês"
              usado={d.carteira.gastos}
              limite={d.carteira.dados}
              formatar={(n) => `${Number(n).toFixed(2).replace('.', ',')} €`}
            />
          )}
          {d.espaco && (
            <BarraUso
              rotulo="Espaço da biblioteca"
              usado={d.espaco.usado}
              limite={d.espaco.limite}
              formatar={(b) => `${(b / 1e9).toFixed(1).replace('.', ',')} GB`}
            />
          )}
        </div>
      )}
      <p className="mt-4 text-xs text-muted-foreground">Para mudar de plano, fala com a NetScreen.</p>
    </section>
  );
}

function ContaRedesSociais({ slug, podeGerir }) {
  const [dados, setDados] = React.useState(null);
  const [campos, setCampos] = React.useState({ instagram: '', facebook: '' });
  const [erro, setErro] = React.useState(null);
  const [ocupado, setOcupado] = React.useState(false);
  const [guardado, setGuardado] = React.useState(false);
  const carregar = React.useCallback(() => {
    setErro(null);
    return api.get(`/api/${slug}/config/redes-sociais`).then((d) => {
      setDados(d);
      setCampos(Object.fromEntries(['instagram', 'facebook'].map((rede) => [rede, d.redes.find((r) => r.rede === rede)?.url || ''])));
    }).catch((e) => setErro(e.message || 'Não foi possível ler as redes sociais.'));
  }, [slug]);
  React.useEffect(() => { setDados(null); setGuardado(false); carregar(); }, [carregar]);
  // Vindo de uma campanha que pedia o perfil («?voltar=»): a secção aparece à vista e, guardado, há o caminho
  // de volta (utilizador virgem, 4 Nov: guardou e ficou em Conta sem saber voltar). Só campanhas desta conta.
  const voltar = React.useMemo(() => {
    const v = new URLSearchParams(window.location.search).get('voltar') || '';
    return v.startsWith(`/${slug}/campanhas/`) && !/[^\w/-]/.test(v) ? v : null;
  }, [slug]);
  const secao = React.useRef(null);
  React.useEffect(() => { if (voltar && secao.current) secao.current.scrollIntoView({ block: 'start' }); }, [voltar, dados]);
  const guardar = async (e) => {
    e.preventDefault(); setOcupado(true); setErro(null); setGuardado(false);
    try {
      const redes = Object.entries(campos).filter(([, url]) => url.trim()).map(([rede, url]) => ({ rede, url: url.trim() }));
      const d = await api.put(`/api/${slug}/config/redes-sociais`, { redes });
      setDados(d); setCampos(Object.fromEntries(['instagram', 'facebook'].map((rede) => [rede, d.redes.find((r) => r.rede === rede)?.url || '']))); setGuardado(true);
    } catch (e) { setErro(e.message || 'Não foi possível guardar as redes sociais.'); }
    finally { setOcupado(false); }
  };
  return (
    <section ref={secao} className="border border-border bg-card p-5" aria-labelledby="conta-redes-titulo">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <h2 id="conta-redes-titulo" className="ns-seccao-titulo">Redes sociais</h2>
        <span className="text-xs text-muted-foreground">Publicação manual</span>
      </div>
      <p className="mt-2 text-sm text-muted-foreground">Guarda os perfis desta conta para preparar as campanhas. A publicação é feita manualmente; guardar um perfil não autoriza a app a publicar.</p>
      {!dados ? (
        <div className="mt-3">
          {erro ? <><p role="alert" className="text-sm">{erro}</p><button type="button" onClick={carregar} className="mt-2 border border-border px-3 py-2 text-sm">Tentar novamente</button></> : <p role="status" className="text-sm text-muted-foreground">A carregar as redes sociais…</p>}
        </div>
      ) : podeGerir ? (
        <form onSubmit={guardar} className="mt-4 space-y-4">
          {/* Há duas redes: um limite maior (o 99 dos planos sem tecto) dizia «permite 99 redes sociais» (agentes, 20 Out). */}
          <p className="text-xs text-muted-foreground">{dados.limite === null || dados.limite >= 2 ? 'O plano inclui as duas redes.' : `O plano permite ${dados.limite === 1 ? 'uma rede social' : 'nenhuma rede social'}.`} Deixa o campo vazio para retirar um perfil.</p>
          <fieldset disabled={ocupado} className="grid gap-4 md:grid-cols-2">
            <legend className="sr-only">Perfis da conta</legend>
            {['instagram', 'facebook'].map((rede) => (
              <div key={rede} className="min-w-0">
                <label htmlFor={`conta-rede-${rede}`} className="text-sm">{rede === 'instagram' ? 'Instagram' : 'Facebook'}</label>
                <input id={`conta-rede-${rede}`} type="text" inputMode="url" autoCapitalize="off" spellCheck={false} value={campos[rede]} placeholder={rede === 'instagram' ? 'https://www.instagram.com/a-tua-marca/' : 'https://www.facebook.com/a-tua-marca/'} onChange={(e) => { setCampos((c) => ({ ...c, [rede]: e.target.value })); setGuardado(false); }} className="mt-1 w-full border border-border bg-background px-3 py-2 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:border-primary" />
              </div>
            ))}
          </fieldset>
          {erro && <p role="alert" className="text-sm">{erro}</p>}
          {guardado && <p role="status" className="text-sm">Perfis guardados. A NetScreen usa-os para publicar, à mão, os posts que aprovares.</p>}
          {guardado && voltar && <a href={voltar} className="ns-btn ns-btn-primario inline-block px-4 py-2 text-sm">Voltar à campanha</a>}
          <button type="submit" disabled={ocupado} className="border border-border px-4 py-2 text-sm disabled:opacity-50">{ocupado ? 'A guardar…' : 'Guardar perfis'}</button>
        </form>
      ) : (
        <ul className="mt-4 space-y-2 text-sm">
          {dados.redes.length ? dados.redes.map((r) => <li key={r.rede}><span>{r.rede === 'instagram' ? 'Instagram' : 'Facebook'}: </span><a href={r.url} target="_blank" rel="noopener noreferrer" className="break-all text-primary underline">{r.handle}</a></li>) : <li className="text-muted-foreground">Ainda não foram associados perfis a esta conta.</li>}
        </ul>
      )}
    </section>
  );
}

function ScreenConfiguracao({ slug, plano }) {
  const [dados, setDados] = React.useState(null);
  const [erro, setErro] = React.useState(null);
  const [aConvidar, setAConvidar] = React.useState(false);
  const [aMudar, setAMudar] = React.useState(null);
  const [aRetirar, setARetirar] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const fecharToast = React.useCallback(() => setToast(null), []);

  const carregar = React.useCallback(
    () =>
      api
        .get(`/api/${slug}/config/users`)
        .then(setDados)
        .catch((e) => setErro(e.message || 'Não foi possível ler os utilizadores.')),
    [slug]
  );

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

  const cabecalho = (
    <header>
      <h1 className="font-display text-4xl uppercase leading-none tracking-wide">Conta</h1>
      <p className="mt-2 text-sm text-muted-foreground">O teu plano, o que já gastaste este mês, e quem trabalha nesta conta.</p>
    </header>
  );

  if (erro) {
    return (
      <div className="space-y-6">
        {cabecalho}
        <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 os utilizadores</p>
          <p className="mt-2 text-sm text-muted-foreground">{erro}</p>
        </div>
      </div>
    );
  }

  if (!dados) {
    return (
      <div className="space-y-6">
        {cabecalho}
        <SkeletonTabela linhas={4} />
      </div>
    );
  }

  const semLugares = dados.lugares.limite !== null && dados.lugares.ocupados >= dados.lugares.limite;

  return (
    <div className="space-y-6">
      {cabecalho}

      <ContaPlano slug={slug} plano={plano} />

      <ContaRedesSociais slug={slug} podeGerir={dados.podes_gerir} />

      <section>
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div className="min-w-0">
            <h2 className="ns-seccao-titulo">Utilizadores</h2>
            <div className="mt-1">
              <Lugares lugares={dados.lugares} />
            </div>
          </div>
          {dados.podes_gerir && (
            <button
              type="button"
              disabled={semLugares}
              onClick={() => setAConvidar(true)}
              title={semLugares ? 'O plano não tem lugares livres' : undefined}
              className="shrink-0 bg-primary px-4 py-2 text-sm text-primary-foreground outline-none hover:bg-primary/90 disabled:cursor-not-allowed"
            >
              Convidar alguém
            </button>
          )}
        </div>

        <ul className="mt-3 border border-border bg-card">
          {dados.utilizadores.map((u) => (
            <li
              key={u.id}
              className="flex flex-wrap items-baseline justify-between gap-3 border-t border-border px-5 py-3 first:border-t-0"
            >
              <div className="min-w-0">
                <p className="text-sm text-foreground">
                  {u.nome}
                  {u.es_tu && <span className="ml-2 text-xs text-muted-foreground">(és tu)</span>}
                </p>
                <p className="mt-0.5 truncate text-xs text-muted-foreground">{u.email}</p>
              </div>

              <div className="flex flex-wrap items-baseline justify-end gap-3">
                <div className="text-right text-xs text-muted-foreground">
                  <p>{(PERFIS_CLIENTE[u.perfil] || {}).texto || u.perfil}</p>
                  <p>
                    {u.convidado
                      ? 'convite por aceitar'
                      : u.ultimo_acesso
                        ? `entrou ${desde(u.ultimo_acesso).texto}`
                        : 'nunca entrou'}
                  </p>
                </div>

                {/* A si próprio, não: o servidor recusa na mesma, e um botão que
                    só serve para dar erro é pior do que botão nenhum. */}
                {dados.podes_gerir && !u.es_tu && (
                  // No telemóvel, 40 px de alvo; tinham 28 (agentes, 20 Out).
                  <span className="flex gap-2">
                    <button
                      type="button"
                      onClick={() => setAMudar(u)}
                      className="min-h-10 border border-border px-2 py-1 text-xs sm:min-h-0"
                    >
                      Mudar perfil
                    </button>
                    <button
                      type="button"
                      onClick={() => setARetirar(u)}
                      className="ns-btn ns-btn-sm ns-btn-perigo h-7 min-h-10 px-2 text-xs sm:min-h-0"
                    >
                      Retirar acesso
                    </button>
                  </span>
                )}
              </div>
            </li>
          ))}
        </ul>

        <div className="mt-3 border border-border bg-card p-4">
          <p className="ns-seccao-titulo">O que cada perfil pode fazer</p>
          <dl className="mt-3 space-y-2">
            {Object.entries(PERFIS_CLIENTE).map(([k, p]) => (
              <div key={k} className="flex flex-wrap gap-x-3">
                <dt className="w-28 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>
      </section>


      <ModalConvidarCliente
        aberto={aConvidar}
        slug={slug}
        onFechar={() => setAConvidar(false)}
        onConcluido={(mensagem) => {
          setAConvidar(false);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <ModalPerfilCliente
        aberto={aMudar !== null}
        slug={slug}
        pessoa={aMudar}
        onFechar={() => setAMudar(null)}
        onConcluido={(mensagem) => {
          setAMudar(null);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <ModalRetirarCliente
        aberto={aRetirar !== null}
        slug={slug}
        pessoa={aRetirar}
        onFechar={() => setARetirar(null)}
        onConcluido={(mensagem) => {
          setARetirar(null);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <Toast toast={toast} onFechar={fecharToast} />
    </div>
  );
}
