"use client";

import { useEffect, useMemo, useState } from "react";
import Image from "next/image";
import { motion, useReducedMotion } from "framer-motion";
import { CRITERIOS_DA_GALERA, type LojaDaGalera, type Totais } from "./tipos";
import { useGaleraAoVivo } from "./useGaleraAoVivo";
import { useNumeroAnimado } from "@/lib/numero-animado";
import { getReadableTextColor, getRelativeLuminance, normalizeHexColor } from "@/lib/color-contrast";

export type { LojaDaGalera } from "./tipos";

/*
  A Galera da Ktalogu como TABELA DE CAMPEONATO: posição, escudo (o logo da
  loja), colunas de números e a seta de quem subiu ou caiu desde a última
  leitura. Lista corrida, sem cartão solto; abas com sublinhado; a cor forte
  fica em pontos pequenos (a faixa da zona, o número da aba, a barra do valor),
  nunca em superfície inteira. Os sinais (seta, lupa, triângulos) são
  desenhados aqui, sem biblioteca de ícones.

  Fontes (app/lojas/layout.tsx): Plus Jakarta nos textos, Space Grotesk nos
  números, JetBrains Mono nos rótulos de placar.
*/

const TINTA = "#140B2B";
const VIOLETA = "#6D28D9";
const LILAS = "#A78BFA";
const TEXTO = "#5B5675";
const LINHA = "#EEEDF3";
const OURO = "#F5A524";
const PRATA = "#A3A9B8";
const BRONZE = "#C2622D";
const SUBIU = "#16A34A";
const CAIU = "#E11D48";

const NUM = "[font-family:var(--fonte-galera-numeros),ui-sans-serif,sans-serif] tabular-nums";
const MONO = "[font-family:var(--fonte-galera-mono),ui-monospace,monospace]";

const nf = new Intl.NumberFormat("pt-BR");
const moeda = new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL", maximumFractionDigits: 0 });

/** 13958 vira "14 mil": no placar, escala comunica melhor que precisão. */
function curto(valor: number) {
  const v = Math.round(valor);
  if (v >= 1000) {
    const mil = v / 1000;
    return `${mil >= 10 ? Math.round(mil) : mil.toFixed(1).replace(".0", "").replace(".", ",")} mil`;
  }
  return nf.format(v);
}

const ABAS = [
  { id: "score", rotulo: "Ranking geral" },
  { id: "vendas", rotulo: "Mais vendem" },
  { id: "acessos", rotulo: "Mais acessadas" },
  { id: "alta", rotulo: "Em alta" },
  { id: "acervo", rotulo: "Maiores catálogos" },
] as const;

type AbaId = (typeof ABAS)[number]["id"];

/* As colunas da tabela, na ordem em que aparecem; a da aba escolhida acende. */
const COLUNAS: { aba: AbaId; titulo: string; detalhe: string }[] = [
  { aba: "vendas", titulo: "Pedidos", detalhe: "30 dias" },
  { aba: "acessos", titulo: "Visitantes", detalhe: "30 dias" },
  { aba: "alta", titulo: "Semana", detalhe: "7 dias" },
  { aba: "acervo", titulo: "Produtos", detalhe: "no ar" },
  { aba: "score", titulo: "Pontos", detalhe: "de 100" },
];

/* O número que cada aba ordena e mostra. Os critérios estão em tipos.ts
   (CRITERIOS_DA_GALERA) e na migration 220. */
function numeroDaAba(loja: LojaDaGalera, aba: AbaId) {
  if (aba === "acessos") return { valor: loja.visitantes30d, rotulo: "visitantes em 30 dias" };
  if (aba === "alta") return { valor: loja.visitantes7d, rotulo: "visitantes na semana" };
  if (aba === "vendas") return { valor: loja.pedidos30d, rotulo: "pedidos em 30 dias" };
  if (aba === "acervo") return { valor: loja.produtos, rotulo: "produtos no ar" };
  return { valor: loja.score, rotulo: "pontos" };
}

function ordenar(lojas: LojaDaGalera[], aba: AbaId) {
  /* Empate na aba: decide o ranking geral (que já vem em ordem do banco). */
  return [...lojas].sort((a, b) => numeroDaAba(b, aba).valor - numeroDaAba(a, aba).valor || a.posicao - b.posicao);
}

function selos(loja: LojaDaGalera) {
  const lista: { texto: string; cor: string }[] = [];
  /* Bombando: a última semana trouxe mais de 40% das visitas do mês (o normal
     seria ~23%), com gente de verdade (30 pessoas ou mais). */
  if (loja.visitantes7d >= 30 && loja.visitantes7d / Math.max(1, loja.visitantes30d) > 0.4) {
    lista.push({ texto: "Bombando", cor: CAIU });
  }
  if (loja.pedidos30d >= 20) lista.push({ texto: "Vende todo dia", cor: SUBIU });
  if (loja.produtos >= 150) lista.push({ texto: "Catálogo gigante", cor: VIOLETA });
  return lista.slice(0, 2);
}

function iniciais(nome: string) {
  return nome
    .split(/\s+/)
    .filter((p) => /[\p{L}\p{N}]/u.test(p))
    .slice(0, 2)
    .map((p) => p.replace(/[^\p{L}\p{N}]/gu, "")[0] || "")
    .join("")
    .toUpperCase();
}

/* --------------------------------------------------------- sinais */

function Seta({ className = "" }: { className?: string }) {
  return (
    <svg viewBox="0 0 16 16" className={className} fill="none" aria-hidden="true">
      <path d="M4.5 11.5 11.5 4.5M6 4.5h5.5V10" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

function Lupa({ className = "" }: { className?: string }) {
  return (
    <svg viewBox="0 0 16 16" className={className} fill="none" aria-hidden="true">
      <circle cx="7" cy="7" r="4.6" stroke="currentColor" strokeWidth="1.6" />
      <path d="m10.4 10.4 3.1 3.1" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
    </svg>
  );
}

function Movimento({ delta }: { delta: number }) {
  if (!delta) return <span className="block h-[2px] w-2.5 rounded-full bg-[#D9D6E4]" aria-label="Manteve a posição" />;
  const subiu = delta > 0;
  return (
    <span
      className={`inline-flex items-center gap-0.5 text-[11px] font-bold ${NUM}`}
      style={{ color: subiu ? SUBIU : CAIU }}
      aria-label={subiu ? `Subiu ${delta}` : `Caiu ${-delta}`}
    >
      <svg viewBox="0 0 8 8" className="h-2 w-2" aria-hidden="true">
        <path d={subiu ? "M4 1 7.5 7h-7z" : "M4 7 .5 1h7z"} fill="currentColor" />
      </svg>
      {Math.abs(delta)}
    </span>
  );
}

function NumeroVivo({ valor, formato = "inteiro" }: { valor: number; formato?: "inteiro" | "curto" | "moeda" }) {
  const animado = useNumeroAnimado(valor);
  if (formato === "moeda") return <>{moeda.format(Math.round(animado))}</>;
  if (formato === "curto") return <>{curto(animado)}</>;
  return <>{nf.format(Math.round(animado))}</>;
}

/*
  Logo claro em fundo transparente (feito para o cabeçalho colorido da loja)
  sumia no branco desta página. O navegador mede o logo uma vez (32 × 32, só
  os pixels visíveis) e, se for claro, o escudo ganha fundo: a cor da loja
  quando ela é escura, senão a tinta da página. As imagens do depósito vêm
  com CORS liberado; se a leitura falhar, fica o fundo branco de sempre.
*/
const leituraDosLogos = new Map<string, boolean>();

function useLogoClaro(url: string | null) {
  const [lido, setLido] = useState<{ url: string; claro: boolean } | null>(null);
  useEffect(() => {
    if (!url || leituraDosLogos.has(url)) return;
    let vivo = true;
    const imagem = new window.Image();
    imagem.crossOrigin = "anonymous";
    imagem.onload = () => {
      try {
        const lado = 32;
        const tela = document.createElement("canvas");
        tela.width = lado;
        tela.height = lado;
        const ctx = tela.getContext("2d", { willReadFrequently: true });
        if (!ctx) return;
        ctx.drawImage(imagem, 0, 0, lado, lado);
        const { data } = ctx.getImageData(0, 0, lado, lado);
        let luz = 0;
        let peso = 0;
        let vazios = 0;
        for (let i = 0; i < data.length; i += 4) {
          const alfa = data[i + 3] / 255;
          if (alfa < 0.1) {
            vazios += 1;
            continue;
          }
          luz += ((0.2126 * data[i] + 0.7152 * data[i + 1] + 0.0722 * data[i + 2]) / 255) * alfa;
          peso += alfa;
        }
        /* Só conta como "claro" o logo com fundo transparente: imagem com o
           próprio fundo já se resolve sozinha. */
        const claro = peso > 0 && vazios > lado * lado * 0.15 && luz / peso > 0.72;
        leituraDosLogos.set(url, claro);
        if (vivo) setLido({ url, claro });
      } catch {
        leituraDosLogos.set(url, false);
      }
    };
    imagem.src = url;
    return () => {
      vivo = false;
    };
  }, [url]);
  if (!url) return false;
  return leituraDosLogos.get(url) ?? (lido?.url === url ? lido.claro : false);
}

function Escudo({ loja, tamanho }: { loja: LojaDaGalera; tamanho: number }) {
  const raio = Math.round(tamanho * 0.26);
  const claro = useLogoClaro(loja.logo);
  if (loja.logo) {
    const corDaLoja = normalizeHexColor(loja.cor, VIOLETA);
    const fundo = claro ? (getRelativeLuminance(corDaLoja) < 0.3 ? corDaLoja : TINTA) : "#FFFFFF";
    return (
      <span
        className="flex shrink-0 items-center justify-center overflow-hidden border transition-colors"
        style={{
          width: tamanho,
          height: tamanho,
          borderRadius: raio,
          backgroundColor: fundo,
          borderColor: claro ? fundo : LINHA,
          padding: Math.round(tamanho * 0.1),
        }}
      >
        <Image src={loja.logo} alt="" width={tamanho * 2} height={tamanho * 2} className="h-full w-full object-contain" unoptimized />
      </span>
    );
  }
  const cor = normalizeHexColor(loja.cor, VIOLETA);
  return (
    <span
      className="flex shrink-0 items-center justify-center font-extrabold tracking-tight"
      style={{
        width: tamanho,
        height: tamanho,
        borderRadius: raio,
        backgroundColor: cor,
        color: getReadableTextColor(cor),
        fontSize: Math.round(tamanho * 0.34),
      }}
      aria-hidden="true"
    >
      {iniciais(loja.nome) || "K"}
    </span>
  );
}

function SeloAoVivo({ atualizadoEm, escuro = false }: { atualizadoEm: number | null; escuro?: boolean }) {
  return (
    <span className={`inline-flex items-center gap-2 text-[11px] font-bold uppercase tracking-[0.16em] ${MONO}`} style={{ color: escuro ? "#D9D3F2" : TEXTO }}>
      <span className="relative flex h-2 w-2">
        <span className="absolute inline-flex h-full w-full animate-ping rounded-full opacity-70" style={{ backgroundColor: SUBIU }} />
        <span className="relative inline-flex h-2 w-2 rounded-full" style={{ backgroundColor: SUBIU }} />
      </span>
      Ao vivo
      {atualizadoEm ? (
        <span className="font-medium" style={{ color: escuro ? "#9C93C2" : "#8E89A6" }}>
          {new Date(atualizadoEm).toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit", second: "2-digit" })}
        </span>
      ) : null}
    </span>
  );
}

/* ---------------------------------------------------------- página */

const POR_PAGINA = 25;

export default function GaleraDaKtalogu({ lojas: lojasIniciais, totais: totaisIniciais }: { lojas: LojaDaGalera[]; totais: Totais }) {
  const [aba, setAba] = useState<AbaId>("score");
  const [busca, setBusca] = useState("");
  const [uf, setUf] = useState("todos");
  const [limite, setLimite] = useState(POR_PAGINA);
  const calmo = useReducedMotion();

  const { lojas, totais, atualizadoEm, posicoesAnteriores } = useGaleraAoVivo({ lojas: lojasIniciais, totais: totaisIniciais });

  const estados = useMemo(() => Array.from(new Set(lojas.map((l) => l.uf).filter(Boolean) as string[])).sort(), [lojas]);
  const ordenadas = useMemo(() => ordenar(lojas, aba), [lojas, aba]);
  const filtrando = Boolean(busca.trim()) || uf !== "todos";

  const filtradas = useMemo(() => {
    const termo = busca.trim().toLowerCase();
    return ordenadas.filter((loja) => {
      if (uf !== "todos" && loja.uf !== uf) return false;
      if (!termo) return true;
      return `${loja.nome} ${loja.cidade || ""} ${loja.uf || ""}`.toLowerCase().includes(termo);
    });
  }, [ordenadas, busca, uf]);

  /* A posição na aba vale para a tabela inteira, mesmo filtrando: quem busca
     a própria loja vê "14º", não "1º de 1". */
  const posicaoNaAba = useMemo(() => new Map(ordenadas.map((l, i) => [l.slug, i + 1])), [ordenadas]);
  const maiorDaAba = useMemo(() => Math.max(1, ...ordenadas.map((l) => numeroDaAba(l, aba).valor)), [ordenadas, aba]);
  const linhas = filtrando ? filtradas : filtradas.slice(0, limite);
  const podio = ordenadas.slice(0, 3);
  const criterio = CRITERIOS_DA_GALERA[aba];

  /* A faixa que corre embaixo do placar: só fatos de verdade da tabela. */
  const fita = useMemo(() => {
    const porVendas = ordenar(lojas, "vendas").filter((l) => l.pedidos30d > 0).slice(0, 3);
    const porSemana = ordenar(lojas, "alta").filter((l) => l.visitantes7d > 0).slice(0, 3);
    const porAcervo = ordenar(lojas, "acervo").slice(0, 2);
    return [
      ...porVendas.map((l) => `${l.nome} · ${nf.format(l.pedidos30d)} pedidos no mês`),
      ...porSemana.map((l) => `${l.nome} · ${nf.format(l.visitantes7d)} visitantes na semana`),
      ...porAcervo.map((l) => `${l.nome} · ${nf.format(l.produtos)} produtos no ar`),
    ];
  }, [lojas]);

  const trocarAba = (id: AbaId) => {
    setAba(id);
    setLimite(POR_PAGINA);
  };

  return (
    <div className="min-h-screen bg-white [font-family:var(--font-plus-jakarta),system-ui,sans-serif]" style={{ color: TINTA }}>
      <style>{`
        @keyframes galera-fita { from { transform: translateX(0); } to { transform: translateX(-50%); } }
        @media (prefers-reduced-motion: reduce) { .galera-fita { animation: none !important; } }
      `}</style>

      {/* ------------------------------------------------ topo */}
      <header className="sticky top-0 z-40 border-b border-white/10 px-4 sm:px-6" style={{ backgroundColor: TINTA }}>
        <div className="mx-auto flex max-w-[1200px] items-center justify-between gap-3 py-3">
          <a href="https://ktalogu.com.br" className="flex items-center" aria-label="Ktalogu">
            <Image src="/brand-logo.svg" alt="Ktalogu" width={116} height={30} className="h-7 w-auto brightness-0 invert" />
          </a>
          <nav className="flex items-center gap-1 sm:gap-2">
            <a href="#tabela" className="hidden rounded-full px-3 py-2 text-[13px] font-semibold text-white/75 transition hover:text-white sm:inline-flex">
              Tabela
            </a>
            <a href="#como-contamos" className="hidden rounded-full px-3 py-2 text-[13px] font-semibold text-white/75 transition hover:text-white sm:inline-flex">
              Como contamos
            </a>
            <a
              href="https://ktalogu.com.br"
              className="inline-flex items-center gap-1.5 rounded-full bg-white px-4 py-2 text-[13px] font-bold outline-none transition hover:bg-[#EDE9FE] focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-[#140B2B]"
              style={{ color: TINTA }}
            >
              Criar minha loja
              <Seta className="h-3.5 w-3.5" />
            </a>
          </nav>
        </div>
      </header>

      {/* ------------------------------------------------ placar */}
      <section
        className="relative overflow-hidden px-4 text-white sm:px-6"
        style={{
          backgroundColor: TINTA,
          backgroundImage: "radial-gradient(rgba(255,255,255,0.07) 1px, transparent 1px)",
          backgroundSize: "20px 20px",
        }}
      >
        <div className="relative mx-auto grid max-w-[1200px] gap-10 pb-12 pt-12 lg:grid-cols-12 lg:gap-8 lg:pb-16 lg:pt-16">
          <motion.div
            initial={calmo ? false : { opacity: 0, y: 16 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
            className="lg:col-span-7"
          >
            <SeloAoVivo atualizadoEm={atualizadoEm} escuro />
            <h1 className="mt-6 text-[3.1rem] font-extrabold leading-[0.98] tracking-[-0.045em] sm:text-[4.6rem] lg:text-[5.6rem]">
              A galera
              <br />
              da <span style={{ color: LILAS }}>Ktalogu</span>.
            </h1>
            <p className="mt-6 max-w-[34rem] text-[16px] leading-relaxed text-white/70 sm:text-[17px]">
              As lojas que vendem todo dia com a Ktalogu, numa tabela que se mexe sozinha. Veja quem está na frente, de
              onde vem cada uma e o que faz a diferença.
            </p>
            <div className="mt-8 flex flex-wrap items-center gap-3">
              <a
                href="#tabela"
                className="inline-flex items-center gap-2 rounded-full px-5 py-3 text-[14px] font-bold text-white outline-none transition hover:brightness-110 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-[#140B2B]"
                style={{ backgroundColor: VIOLETA }}
              >
                Ver a tabela
                <svg viewBox="0 0 16 16" className="h-3.5 w-3.5" fill="none" aria-hidden="true">
                  <path d="M8 3v10M3.5 8.5 8 13l4.5-4.5" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </a>
              <a href="#como-contamos" className="rounded-full px-4 py-3 text-[14px] font-semibold text-white/75 underline-offset-4 transition hover:text-white hover:underline">
                Como os números são contados
              </a>
            </div>
          </motion.div>

          <motion.div
            initial={calmo ? false : { opacity: 0, y: 16 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.5, delay: 0.08, ease: [0.22, 1, 0.36, 1] }}
            className="self-end lg:col-span-5"
          >
            <div className="rounded-[22px] border border-white/12 bg-white/[0.04] p-6 backdrop-blur-sm sm:p-7">
              <div className={`text-[11px] font-bold uppercase tracking-[0.18em] text-white/55 ${MONO}`}>Já negociado pela galera</div>
              <div className={`mt-3 text-[2.6rem] font-bold leading-none tracking-[-0.03em] sm:text-[3.4rem] ${NUM}`}>
                <NumeroVivo valor={totais.negociado} formato="moeda" />
              </div>
              <div className="mt-3 flex flex-wrap items-baseline gap-x-2 text-[14px]">
                <span className={`font-bold ${NUM}`} style={{ color: LILAS }}>
                  <NumeroVivo valor={totais.negociado30d} formato="moeda" />
                </span>
                <span className="text-white/60">nos últimos 30 dias</span>
              </div>
              <dl className="mt-6 grid grid-cols-3 border-t border-white/10 pt-5">
                {[
                  { valor: totais.lojas, rotulo: "lojas na tabela" },
                  { valor: totais.estados, rotulo: "estados" },
                  { valor: totais.visitas, rotulo: "visitas" },
                ].map((item, i) => (
                  <div key={item.rotulo} className={i ? "border-l border-white/10 pl-4" : "pr-4"}>
                    <dd className={`text-[1.65rem] font-bold leading-none ${NUM}`}>
                      <NumeroVivo valor={item.valor} formato="curto" />
                    </dd>
                    <dt className="mt-1.5 text-[12px] text-white/55">{item.rotulo}</dt>
                  </div>
                ))}
              </dl>
              <p className="mt-5 text-[12px] leading-relaxed text-white/45">
                Pagamentos recebidos nos pedidos dessas lojas, sem estornos e sem pedidos cancelados.
              </p>
            </div>
          </motion.div>
        </div>

        {fita.length ? (
          <div className="relative -mx-4 border-t border-white/10 py-3.5 sm:-mx-6" aria-label="Destaques da tabela">
            <div className="flex overflow-hidden [mask-image:linear-gradient(90deg,transparent,#000_6%,#000_94%,transparent)]">
              <div className={`galera-fita flex shrink-0 animate-[galera-fita_60s_linear_infinite] items-center gap-8 pr-8 text-[12px] font-medium uppercase tracking-[0.08em] text-white/70 ${MONO}`}>
                {[...fita, ...fita].map((fato, i) => (
                  <span key={i} className="flex shrink-0 items-center gap-8" aria-hidden={i >= fita.length}>
                    <span className="whitespace-nowrap">{fato}</span>
                    <span className="h-1.5 w-1.5 rotate-45" style={{ backgroundColor: LILAS }} />
                  </span>
                ))}
              </div>
            </div>
          </div>
        ) : null}
      </section>

      {/* ------------------------------------------------ tabela */}
      <section id="tabela" className="scroll-mt-16 px-4 pb-16 pt-12 sm:px-6 lg:pt-16">
        <div className="mx-auto max-w-[1200px]">
          <div className="flex flex-wrap items-end justify-between gap-4">
            <div>
              <h2 className="text-[1.9rem] font-extrabold leading-tight tracking-[-0.03em] sm:text-[2.4rem]">Tabela da galera</h2>
              <p className="mt-1.5 text-[14.5px]" style={{ color: TEXTO }}>
                Atualiza sozinha a cada 15 segundos. Quem sobe ganha seta verde.
              </p>
            </div>
            <SeloAoVivo atualizadoEm={atualizadoEm} />
          </div>

          {/* Abas com sublinhado */}
          <div className="mt-8 border-b" style={{ borderColor: LINHA }}>
            <div className="-mb-px flex gap-6 overflow-x-auto [scrollbar-width:none] sm:gap-8 [&::-webkit-scrollbar]:hidden" role="tablist" aria-label="Ordenar a tabela">
              {ABAS.map((item) => {
                const ativa = aba === item.id;
                return (
                  <button
                    key={item.id}
                    type="button"
                    role="tab"
                    aria-selected={ativa}
                    onClick={() => trocarAba(item.id)}
                    className="relative shrink-0 cursor-pointer whitespace-nowrap pb-3.5 pt-1 text-[14.5px] font-semibold outline-none transition focus-visible:text-[#6D28D9]"
                    style={{ color: ativa ? TINTA : "#8E89A6" }}
                  >
                    {item.rotulo}
                    {ativa ? (
                      <motion.span layoutId="galera-aba" className="absolute inset-x-0 bottom-0 h-[3px] rounded-full" style={{ backgroundColor: VIOLETA }} />
                    ) : null}
                  </button>
                );
              })}
            </div>
          </div>
          <p className="mt-4 max-w-3xl text-[13.5px] leading-relaxed" style={{ color: TEXTO }}>
            <span className="font-bold" style={{ color: TINTA }}>
              Como contamos:{" "}
            </span>
            {criterio}{" "}
            <a href="#como-contamos" className="font-semibold underline underline-offset-4" style={{ color: VIOLETA }}>
              Ver todos os critérios
            </a>
          </p>

          {/* Pódio da aba */}
          {podio.length === 3 ? <Podio lojas={podio} aba={aba} /> : null}

          {/* Barra: busca, estado e contagem */}
          <div className="mt-12 flex flex-col gap-3 sm:flex-row sm:items-center">
            <label className="relative flex-1">
              <span className="sr-only">Procurar loja ou cidade</span>
              <Lupa className="pointer-events-none absolute left-4 top-1/2 h-4 w-4 -translate-y-1/2 text-[#8E89A6]" />
              <input
                value={busca}
                onChange={(e) => setBusca(e.target.value)}
                placeholder="Procurar loja ou cidade"
                className="h-11 w-full rounded-full border bg-white pl-11 pr-4 text-[14px] outline-none transition placeholder:text-[#A29DB8] focus:border-[#6D28D9] focus:ring-4 focus:ring-[#6D28D9]/10"
                style={{ borderColor: "#E3E1EC", color: TINTA }}
              />
            </label>
            <div className="flex items-center gap-3">
              <label className="relative">
                <span className="sr-only">Filtrar por estado</span>
                <select
                  value={uf}
                  onChange={(e) => setUf(e.target.value)}
                  className="h-11 cursor-pointer appearance-none rounded-full border bg-white pl-4 pr-10 text-[14px] font-semibold outline-none transition focus:border-[#6D28D9] focus:ring-4 focus:ring-[#6D28D9]/10"
                  style={{ borderColor: "#E3E1EC", color: TINTA }}
                >
                  <option value="todos">Todos os estados</option>
                  {estados.map((sigla) => (
                    <option key={sigla} value={sigla}>
                      {sigla}
                    </option>
                  ))}
                </select>
                <svg viewBox="0 0 12 12" className="pointer-events-none absolute right-4 top-1/2 h-3 w-3 -translate-y-1/2 text-[#8E89A6]" fill="none" aria-hidden="true">
                  <path d="m2.5 4.5 3.5 3.5 3.5-3.5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </label>
              <span className={`whitespace-nowrap text-[12px] font-bold uppercase tracking-[0.12em] ${MONO}`} style={{ color: TEXTO }}>
                {filtrando ? `${nf.format(filtradas.length)} de ${nf.format(lojas.length)}` : `${nf.format(lojas.length)} lojas`}
              </span>
            </div>
          </div>

          {/* A tabela */}
          <div className="mt-5" role="table" aria-label="Tabela da galera">
            <div
              role="row"
              className={`hidden grid-cols-[64px_minmax(0,1fr)_repeat(5,92px)_32px] items-end gap-x-2 border-b pb-3 text-[10.5px] font-bold uppercase tracking-[0.14em] lg:grid ${MONO}`}
              style={{ borderColor: LINHA, color: "#8E89A6" }}
            >
              <span role="columnheader" className="pl-4">
                Pos
              </span>
              <span role="columnheader">Loja</span>
              {COLUNAS.map((col) => (
                <button
                  key={col.aba}
                  type="button"
                  role="columnheader"
                  onClick={() => trocarAba(col.aba)}
                  className="cursor-pointer text-right uppercase transition hover:text-[#140B2B]"
                  style={{ color: col.aba === aba ? VIOLETA : undefined }}
                  title={`Ordenar por ${col.titulo.toLowerCase()}`}
                >
                  {col.titulo}
                  <span className="block text-[9.5px] font-medium tracking-[0.1em] opacity-70">{col.detalhe}</span>
                </button>
              ))}
              <span />
            </div>

            {linhas.length === 0 ? (
              <div className="py-16 text-center">
                <p className="text-[16px] font-bold">{lojas.length ? "Nenhuma loja com esse filtro" : "A tabela está chegando"}</p>
                <p className="mt-1.5 text-[14px]" style={{ color: TEXTO }}>
                  {lojas.length ? "Tente outro nome, outra cidade ou todos os estados." : "Os números aparecem em alguns segundos."}
                </p>
              </div>
            ) : (
              <motion.div layout={!calmo}>
                {linhas.map((loja) => (
                  <LinhaDaTabela
                    key={loja.slug}
                    loja={loja}
                    aba={aba}
                    posicao={posicaoNaAba.get(loja.slug) || 0}
                    maior={maiorDaAba}
                    delta={
                      aba === "score" && posicoesAnteriores[loja.slug] ? posicoesAnteriores[loja.slug] - loja.posicao : 0
                    }
                    calmo={Boolean(calmo)}
                  />
                ))}
              </motion.div>
            )}

            {!filtrando && filtradas.length > limite ? (
              <div className="mt-6 flex justify-center">
                <button
                  type="button"
                  onClick={() => setLimite((n) => n + POR_PAGINA)}
                  className="cursor-pointer rounded-full border px-6 py-3 text-[14px] font-bold outline-none transition hover:border-[#140B2B] focus-visible:ring-4 focus-visible:ring-[#6D28D9]/15"
                  style={{ borderColor: "#D9D6E4", color: TINTA }}
                >
                  Ver mais {nf.format(Math.min(POR_PAGINA, filtradas.length - limite))} lojas
                  <span className="ml-2 font-medium" style={{ color: TEXTO }}>
                    de {nf.format(filtradas.length - limite)}
                  </span>
                </button>
              </div>
            ) : null}
          </div>
        </div>
      </section>

      {/* ------------------------------------------------ como contamos */}
      <section id="como-contamos" className="scroll-mt-16 border-t px-4 py-16 sm:px-6" style={{ borderColor: LINHA, backgroundColor: "#FAF9FC" }}>
        <div className="mx-auto grid max-w-[1200px] gap-10 lg:grid-cols-12">
          <div className="lg:col-span-4">
            <div className={`text-[11px] font-bold uppercase tracking-[0.18em] ${MONO}`} style={{ color: VIOLETA }}>
              Transparência
            </div>
            <h2 className="mt-3 text-[1.9rem] font-extrabold leading-tight tracking-[-0.03em]">Como contamos</h2>
            <p className="mt-3 text-[14.5px] leading-relaxed" style={{ color: TEXTO }}>
              Os números saem direto do sistema que as lojas usam no dia a dia. Ninguém digita nada para aparecer aqui, e
              nenhum dado de cliente sai desta página: só somas por loja.
            </p>
          </div>
          <dl className="lg:col-span-8">
            {[
              { termo: "Quem entra", texto: CRITERIOS_DA_GALERA.quem },
              { termo: "Ranking geral", texto: CRITERIOS_DA_GALERA.score },
              { termo: "Mais vendem", texto: CRITERIOS_DA_GALERA.vendas },
              { termo: "Mais acessadas", texto: CRITERIOS_DA_GALERA.acessos },
              { termo: "Em alta", texto: CRITERIOS_DA_GALERA.alta },
              { termo: "Maiores catálogos", texto: CRITERIOS_DA_GALERA.acervo },
              { termo: "Já negociado", texto: "Pagamentos recebidos nos pedidos dessas lojas, sem estornos e sem pedidos cancelados." },
            ].map((item) => (
              <div key={item.termo} className="grid gap-1 border-t py-4 sm:grid-cols-[180px_minmax(0,1fr)] sm:gap-6" style={{ borderColor: "#E9E7F0" }}>
                <dt className="text-[14px] font-bold">{item.termo}</dt>
                <dd className="text-[14px] leading-relaxed" style={{ color: TEXTO }}>
                  {item.texto}
                </dd>
              </div>
            ))}
          </dl>
        </div>
      </section>

      {/* ------------------------------------------------ chamada */}
      <section className="px-4 py-16 text-white sm:px-6" style={{ backgroundColor: TINTA }}>
        <div className="mx-auto flex max-w-[1200px] flex-col items-start justify-between gap-8 lg:flex-row lg:items-end">
          <div>
            <h2 className="text-[2.4rem] font-extrabold leading-[0.95] tracking-[-0.04em] sm:text-[3.4rem]">
              Sua loja
              <br />
              <span style={{ color: LILAS }}>na tabela.</span>
            </h2>
            <p className="mt-4 max-w-md text-[15px] leading-relaxed text-white/65">
              Monte o catálogo, compartilhe o link e venda. Os seus números entram aqui sozinhos, do mesmo jeito que os da
              galera.
            </p>
          </div>
          <a
            href="https://ktalogu.com.br"
            className="inline-flex items-center gap-2 rounded-full bg-white px-7 py-4 text-[15px] font-extrabold outline-none transition hover:bg-[#EDE9FE] focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-offset-2 focus-visible:ring-offset-[#140B2B]"
            style={{ color: TINTA }}
          >
            Criar minha loja
            <Seta className="h-4 w-4" />
          </a>
        </div>
      </section>

      <footer className="px-4 py-6 sm:px-6" style={{ backgroundColor: TINTA }}>
        <div className={`mx-auto flex max-w-[1200px] flex-wrap items-center justify-between gap-2 border-t border-white/10 pt-6 text-[11px] uppercase tracking-[0.14em] text-white/45 ${MONO}`}>
          <span>Ktalogu · a galera que vende todo dia</span>
          <span>Os números se atualizam sozinhos</span>
        </div>
      </footer>
    </div>
  );
}

/* ---------------------------------------------------------- pódio */

const MEDALHAS = [OURO, PRATA, BRONZE];

function Podio({ lojas, aba }: { lojas: LojaDaGalera[]; aba: AbaId }) {
  /* O 1º no meio e mais alto, como num pódio de verdade. */
  const ordem = [1, 0, 2];
  const alturas = ["h-[132px] sm:h-[150px]", "h-[96px] sm:h-[110px]", "h-[72px] sm:h-[82px]"];
  return (
    <div className="mx-auto mt-10 grid max-w-[880px] grid-cols-3 items-end gap-2 sm:gap-5">
      {ordem.map((i) => {
        const loja = lojas[i];
        const numero = numeroDaAba(loja, aba);
        const primeiro = i === 0;
        return (
          <a
            key={`${aba}-${loja.slug}`}
            href={loja.url}
            target="_blank"
            rel="noopener"
            className="group flex min-w-0 flex-col items-center text-center outline-none"
          >
            <div className="transition-transform duration-300 group-hover:-translate-y-1">
              <Escudo loja={loja} tamanho={primeiro ? 76 : 60} />
            </div>
            <div className="mt-3 line-clamp-2 min-h-[2.5em] px-1 text-[13px] font-bold leading-tight sm:text-[15px]">{loja.nome}</div>
            <div className={`mt-1 max-w-full truncate text-[10.5px] uppercase tracking-[0.1em] ${MONO}`} style={{ color: "#8E89A6" }}>
              {[loja.cidade, loja.uf].filter(Boolean).join(" · ") || "Brasil"}
            </div>
            <div className={`mt-3 text-[1.5rem] font-bold leading-none sm:text-[2.2rem] ${NUM}`} style={{ color: primeiro ? VIOLETA : TINTA }}>
              <NumeroVivo valor={numero.valor} />
            </div>
            <div className="mt-1 text-[11px] sm:text-[12px]" style={{ color: TEXTO }}>
              {numero.rotulo}
            </div>
            <div
              className={`relative mt-4 flex w-full items-start justify-center overflow-hidden rounded-t-[14px] pt-3 ${alturas[i]}`}
              style={{ backgroundColor: TINTA }}
            >
              <span className="absolute inset-x-0 top-0 h-1" style={{ backgroundColor: MEDALHAS[i] }} />
              <span className={`text-[2.2rem] font-bold leading-none sm:text-[3rem] ${NUM}`} style={{ color: MEDALHAS[i] }}>
                {i + 1}º
              </span>
            </div>
          </a>
        );
      })}
    </div>
  );
}

/* ---------------------------------------------------------- linha */

function LinhaDaTabela({
  loja,
  aba,
  posicao,
  maior,
  delta,
  calmo,
}: {
  loja: LojaDaGalera;
  aba: AbaId;
  posicao: number;
  maior: number;
  delta: number;
  calmo: boolean;
}) {
  const marcas = selos(loja);
  const numero = numeroDaAba(loja, aba);
  const zona = posicao <= 3 ? MEDALHAS[posicao - 1] : posicao <= 10 ? VIOLETA : null;
  const lugar = [loja.cidade, loja.uf].filter(Boolean).join(" · ") || "Brasil";

  return (
    <motion.a
      layout={!calmo}
      transition={{ layout: { duration: 0.45, ease: [0.22, 1, 0.36, 1] } }}
      href={loja.url}
      target="_blank"
      rel="noopener"
      role="row"
      className="group relative grid grid-cols-[44px_minmax(0,1fr)_auto] items-center gap-x-3 border-b py-3.5 outline-none transition-colors hover:bg-[#FAF9FC] focus-visible:bg-[#F5F3FF] lg:grid-cols-[64px_minmax(0,1fr)_repeat(5,92px)_32px] lg:gap-x-2"
      style={{ borderColor: "#F2F1F6" }}
    >
      {zona ? <span className="absolute inset-y-2 left-0 w-[3px] rounded-full" style={{ backgroundColor: zona }} aria-hidden="true" /> : null}

      {/* Posição e movimento */}
      <span role="cell" className="flex flex-col items-center gap-1 lg:flex-row lg:justify-start lg:gap-2.5 lg:pl-4">
        <span className={`text-[17px] font-bold leading-none ${NUM}`}>{posicao}</span>
        <Movimento delta={delta} />
      </span>

      {/* Loja */}
      <span role="cell" className="flex min-w-0 items-center gap-3">
        <Escudo loja={loja} tamanho={42} />
        <span className="min-w-0">
          <span className="block truncate text-[15px] font-bold leading-tight group-hover:underline group-hover:underline-offset-4">{loja.nome}</span>
          <span className="mt-1 flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1">
            <span className={`truncate text-[11px] uppercase tracking-[0.08em] ${MONO}`} style={{ color: "#8E89A6" }}>
              {lugar}
            </span>
            {marcas.map((m) => (
              <span key={m.texto} className="inline-flex items-center gap-1.5 text-[11.5px] font-semibold" style={{ color: m.cor }}>
                <span className="h-1.5 w-1.5 rounded-full" style={{ backgroundColor: m.cor }} />
                {m.texto}
              </span>
            ))}
          </span>
        </span>
      </span>

      {/* Celular: só o número da aba */}
      <span role="cell" className="text-right lg:hidden">
        <span className={`block text-[18px] font-bold leading-none ${NUM}`} style={{ color: VIOLETA }}>
          {nf.format(numero.valor)}
        </span>
        <span className="mt-1 block text-[10.5px]" style={{ color: TEXTO }}>
          {numero.rotulo}
        </span>
      </span>

      {/* Tela larga: todas as colunas, a da aba acesa com a barra */}
      {COLUNAS.map((col) => {
        const valor = numeroDaAba(loja, col.aba).valor;
        const acesa = col.aba === aba;
        return (
          <span key={col.aba} role="cell" className="hidden text-right lg:block">
            <span
              className={`block leading-none ${NUM} ${acesa ? "text-[17px] font-bold" : "text-[14.5px] font-medium"}`}
              style={{ color: acesa ? TINTA : valor ? "#6B6684" : "#C9C6D6" }}
            >
              {nf.format(valor)}
            </span>
            {acesa ? (
              <span className="ml-auto mt-2 block h-[3px] w-[64px] overflow-hidden rounded-full bg-[#EFEDF5]">
                <span className="block h-full rounded-full" style={{ width: `${Math.max(4, (valor / maior) * 100)}%`, backgroundColor: VIOLETA }} />
              </span>
            ) : null}
          </span>
        );
      })}

      <span role="cell" className="hidden justify-end pr-1 lg:flex">
        <Seta className="h-4 w-4 text-[#B9B4CC] transition group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-[#140B2B]" />
      </span>
    </motion.a>
  );
}
