/**
 * Back office — planos.
 *
 * Os planos comerciais como estão na base, e quantas contas tem cada um. O Admin
 * edita-os (ModalEditarPlano, D9); os outros lêem. Alterar um plano mexe em contratos
 * activos — o preço fica bloqueado à assinatura —, por isso a rota tranca os limites
 * de um plano com contratos assinados.
 *
 * Serve a quem tem de responder "o que inclui o Retail Pro?" sem ir ao código:
 * o Bruno, o Rui, a Ana.
 *
 * É uma matriz de comparação — planos em colunas, atributos em linhas — e não
 * uma <Tabela> com um plano por linha: são três planos e catorze atributos, e
 * a orientação certa é a que cresce com os atributos. A primeira versão tinha
 * onze colunas e "Multi-loja / Cadeia" partia-se em cinco linhas.
 */

const ROTULO_SUPORTE = { base: 'Base', priority: 'Prioritário', dedicated: 'Gestor de conta' };

/** `null` é ilimitado. */
const limitePlano = (v) => (v == null ? 'ilimitado' : v);

/**
 * As redes sociais usam 99 como "todas", em vez de `null` como os outros limites.
 * É uma incoerência da tabela (dúvida D3 em docs/duvidas-para-rever.md) e está
 * traduzida aqui para não aparecer "99 redes" a quem lê.
 */
const redesPlano = (v) => (v >= 99 ? 'todas' : v);

/** Grupos de linhas da matriz. `booleano` desenha um visto em vez de texto. */
const MATRIZ_PLANOS = [
  {
    grupo: 'Preço',
    linhas: [
      {
        rotulo: 'Mensalidade',
        valor: (p) => (p.mensalidade == null ? 'sob consulta' : euros(p.mensalidade)),
        destaque: true,
      },
    ],
  },
  {
    grupo: 'Limites',
    linhas: [
      { rotulo: 'Utilizadores', valor: (p) => limitePlano(p.limites.utilizadores) },
      { rotulo: 'Lojas', valor: (p) => limitePlano(p.limites.lojas) },
      { rotulo: 'Campanhas activas', valor: (p) => limitePlano(p.limites.campanhas_activas) },
      { rotulo: 'Redes sociais', valor: (p) => redesPlano(p.limites.redes_sociais) },
    ],
  },
  {
    grupo: 'Inclui',
    linhas: [
      // Havia aqui "Painéis DOOH": repetia os spots de Recursos com o nome do
      // painel do cliente, que é a outra coisa (D2). O registo de 22 Set
      // mandava tirá-la com o has_dooh, e ficou esquecida.
      { rotulo: 'Agente no ponto de venda', valor: (p) => p.funcionalidades.pdv, booleano: true },
      { rotulo: 'Multi-loja', valor: (p) => p.funcionalidades.multiloja, booleano: true },
      { rotulo: 'API', valor: (p) => p.funcionalidades.api, booleano: true },
    ],
  },
  {
    grupo: 'Recursos',
    linhas: [
      {
        rotulo: 'Créditos de IA',
        valor: (p) => (p.creditos_ia ? `${euros(p.creditos_ia)} / mês` : 'negociado'),
      },
      { rotulo: 'Armazenamento', valor: (p) => `${p.armazenamento_gb} GB` },
      {
        rotulo: 'Spots Branddigital',
        // Num plano sob consulta os spots são por conta (P1, migração 014), e
        // "nenhum" dizia o contrário do que está vendido.
        valor: (p) => (p.spots_mensais ? `${p.spots_mensais} / mês` : p.publico ? 'nenhum' : 'por conta'),
      },
      { rotulo: 'Suporte', valor: (p) => ROTULO_SUPORTE[p.suporte] || p.suporte },
    ],
  },
  {
    grupo: 'Hoje',
    linhas: [{ rotulo: 'Contas neste plano', valor: (p) => p.contas, destaque: true }],
  },
];

function ScreenAdminPlanos({ me }) {
  const [planos, setPlanos] = React.useState(null);
  const [erro, setErro] = React.useState(null);
  const [aEditar, setAEditar] = React.useState(null);
  const [toast, setToast] = React.useState(null);
  const fecharToast = React.useCallback(() => setToast(null), []);

  const carregar = React.useCallback(
    () =>
      api
        .get('/api/admin/plans')
        .then((r) => setPlanos(r.planos))
        .catch((e) => setErro(e.message || 'Não foi possível ler os planos.')),
    []
  );

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

  // Preço é receita: só o Admin edita planos (D9). O servidor recusa na mesma.
  const podeEditar = me?.user?.role === 'admin';

  const cabecalho = (
    <header>
      <h1 className="mt-1 font-display text-4xl uppercase leading-none tracking-wide">Planos</h1>
      <p className="mt-2 text-sm text-muted-foreground">
        O que cada plano inclui e quantas contas o têm.
        {podeEditar
          ? ' Um plano com contratos assinados tem os limites trancados; o preço muda só para quem assinar a seguir.'
          : ' Só leitura — editar planos é do Admin.'}
      </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 planos</p>
          <p className="mt-2 text-sm text-muted-foreground">{erro}</p>
        </div>
      </div>
    );
  }

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

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

      {/* Rola na horizontal em ecrãs estreitos em vez de esmagar as colunas.
          O `relative` não é decoração: os `sr-only` das células ("incluído", "não incluído")
          são `position: absolute`, e sem um antepassado posicionado o bloco de contenção deles
          é o documento — escapam ao contentor que rola e alargam a página inteira. */}
      {/* No telemóvel a tabela desliza para o lado, e nada o dizia: lia-se «Re Pr» e «45» (agentes, 20 Out). */}
      <p className="text-xs text-muted-foreground sm:hidden">Desliza a tabela para o lado para ver todos os planos.</p>
      <div className="relative overflow-x-auto border border-border bg-card">
        <table className="w-full min-w-[520px] text-sm">
          <caption className="sr-only">Comparação dos planos comerciais</caption>
          <thead>
            <tr className="border-b border-border">
              <td className="sticky left-0 z-[1] w-32 bg-card px-3 py-4 sm:w-52 sm:px-5" />
              {planos.map((p) => (
                <th key={p.codigo} scope="col" className="px-5 py-4 text-left align-bottom">
                  <span className="font-display text-2xl font-normal uppercase leading-none tracking-wide text-foreground">
                    {p.nome}
                  </span>
                  {podeEditar && (
                    <span className="mt-2 block">
                      <button
                        type="button"
                        onClick={() => setAEditar(p)}
                        className="border border-border px-2 py-1 text-xs font-normal normal-case tracking-normal text-muted-foreground transition-colors hover:border-primary hover:text-foreground"
                      >
                        Editar
                        <span className="sr-only"> o plano {p.nome}</span>
                      </button>
                    </span>
                  )}
                  {!p.publico && (
                    <span className="mt-1 block text-xs font-normal normal-case tracking-normal text-muted-foreground">
                      só sob consulta
                    </span>
                  )}
                </th>
              ))}
            </tr>
          </thead>
          {MATRIZ_PLANOS.map((g) => (
            <tbody key={g.grupo} className="border-t border-border">
              <tr>
                <th
                  scope="colgroup"
                  colSpan={planos.length + 1}
                  className="bg-secondary/40 px-5 py-2 text-left text-xs font-normal uppercase tracking-wider text-muted-foreground"
                >
                  {g.grupo}
                </th>
              </tr>
              {g.linhas.map((l) => (
                <tr key={l.rotulo} className="border-t border-border">
                  {/* O rótulo fica à vista enquanto as colunas deslizam. */}
                  <th scope="row" className="sticky left-0 z-[1] bg-card px-3 py-3 text-left text-sm font-normal text-muted-foreground sm:px-5">
                    {l.rotulo}
                  </th>
                  {planos.map((p) => {
                    const v = l.valor(p);
                    return (
                      <td key={p.codigo} className={`px-5 py-3 ${l.destaque ? 'font-medium text-foreground' : 'text-foreground'}`}>
                        {l.booleano ? (
                          v ? (
                            <span className="inline-flex items-center gap-1.5 text-[hsl(var(--online))]">
                              <IconCheck size={14} />
                              <span className="sr-only">incluído</span>
                            </span>
                          ) : (
                            <span className="text-muted-foreground">
                              <span aria-hidden="true">—</span>
                              <span className="sr-only">não incluído</span>
                            </span>
                          )
                        ) : (
                          v
                        )}
                      </td>
                    );
                  })}
                </tr>
              ))}
            </tbody>
          ))}
        </table>
      </div>

      {/* Dizia «só leitura… por decisão do Fábio» por baixo de um «Editar» (agentes, 20 Out). */}
      <div className="border border-border bg-card p-4">
        <p className="text-xs text-muted-foreground">
          <strong className="text-foreground">Antes de mudar um plano:</strong> o preço fica bloqueado no
          contrato no momento da assinatura. Quem já assinou continua com a mensalidade do contrato, e um
          plano com contratos assinados tem os limites trancados.
        </p>
      </div>

      <ModalEditarPlano
        aberto={aEditar !== null}
        plano={aEditar}
        onFechar={() => setAEditar(null)}
        onConcluido={(mensagem) => {
          setAEditar(null);
          setToast({ id: Date.now(), mensagem });
          carregar();
        }}
      />
      <Toast toast={toast} onFechar={fecharToast} />
    </div>
  );
}
