"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import {
  ChevronDown,
  ChevronRight,
  CreditCard,
  Info,
  Mail,
  MapPin,
  Menu,
  MessageCircle,
  Phone,
  Search,
  ShieldCheck,
  ShoppingCart,
  User,
  X,
} from "lucide-react";
import { useCart } from "@/context/CartContext";
import { useVisaoDaLoja } from "@/components/VisaoDaLojaContext";
import { VendorAviso, type VendorCupomDoAviso } from "./VendorAviso";
import { marcaDeRegiao, useNavegacaoDaLoja } from "@/components/navegacao/ContextoDaNavegacao";
import { itensProntos } from "@/lib/navegacao-da-loja";
import { VendorFaixaDoMenuProprio, VendorGavetaDoMenuProprio } from "./VendorMenuProprio";
import { VendorRodapeProprio } from "./VendorRodapeProprio";

/*
  O shell do template Vendor: cabeçalho, rodapé e os flutuantes.

  Escrito do zero para este template. Não importa nada de desenho do Padrão
  nem do Vitrine, e nada daqui é exportado para eles — cada template tem o seu
  shell, e é isso que permite mexer num sem medo do outro.

  O cabeçalho tem TRÊS faixas empilhadas e somando 152px no desktop:
    1. aviso da loja        32px
    2. logo + busca + ações 81px
    3. menu de categorias   39px

  Essa altura vira `--vd-header-h` e a galeria da página de produto usa o
  mesmo número para se fixar na tela. Mudou a altura, muda a variável.
*/

export type VendorCategoria = {
  id: string;
  name: string;
  slug?: string | null;
  parent_id?: string | null;
};

export type VendorContato = {
  whatsapp?: string | null;
  telefone?: string | null;
  email?: string | null;
  endereco?: string | null;
  cnpj?: string | null;
  instagram?: string | null;
  facebook?: string | null;
};

/* Tudo que a tela "personalização avançada" do catálogo oferece. Chega num
   objeto só para as páginas não precisarem repetir vinte props — e para
   nenhuma escolha do lojista ficar de fora por esquecimento. */
export type VendorAparencia = {
  corDoCabecalho?: string | null;
  corDoTextoDoCabecalho?: string | null;
  corDoMenu?: string | null;
  corDoTextoDoMenu?: string | null;
  corDoFundo?: string | null;
  corDoBotaoDoCard?: string | null;
  fonteDosTitulos?: string | null;
  fonteDoTexto?: string | null;
  corDoRodape?: string | null;
  corDoTextoDoRodape?: string | null;
  corDosIconesDoCabecalho?: string | null;
  /* Nome e slogan ao lado da logo, com as cores escolhidas. */
  mostrarNome?: boolean | null;
  mostrarSlogan?: boolean | null;
  corDoNome?: string | null;
  corDoSlogan?: string | null;
  /* A faixa de aviso do topo, com tudo que a tela do catálogo configura:
     texto com destaque, relógio, cupom para copiar e botão. */
  avisoLigado?: boolean | null;
  avisoTexto?: string | null;
  avisoCorDeFundo?: string | null;
  avisoCorDoTexto?: string | null;
  avisoBotaoRotulo?: string | null;
  avisoBotaoUrl?: string | null;
  avisoMostrarSelo?: boolean | null;
  avisoCorDoSelo?: string | null;
  avisoContagemLigada?: boolean | null;
  avisoContagemAte?: string | null;
  avisoFixo?: boolean | null;
  /* O efeito da logo. */
  logoEfeitoLigado?: boolean | null;
  logoEfeitoTipo?: string | null;
  logoEfeitoVelocidade?: number | null;
  logoEfeitoIntensidade?: number | null;
  /* A tarja de benefícios ("Entrega rápida", "Compra segura"). */
  tarjaLigada?: boolean | null;
  tarjaItens?: Array<{ icon?: string | null; title?: string | null; subtitle?: string | null }> | null;
};

export type VendorShellProps = {
  slug: string;
  nomeDaLoja: string;
  slogan?: string | null;
  logoUrl?: string | null;
  corDaMarca: string;
  aparencia?: VendorAparencia | null;
  /* O cupom do aviso vem lido do banco pela página: o navegador não tem como
     descobrir sozinho o código a partir do id guardado no perfil. */
  cupomDoAviso?: VendorCupomDoAviso | null;
  categorias: VendorCategoria[];
  contato: VendorContato;
  clienteLogado?: boolean;
  /* O lojista decide se o botão do WhatsApp aparece na loja. */
  whatsappFlutuante?: boolean | null;
  /* A categoria da página atual. Numa página de produto a rota não diz a
     categoria, e sem isto o menu ficaria apagado durante a compra inteira. */
  categoriaAtual?: string | null;
  children: React.ReactNode;
};

/* Texto legível sobre a cor escolhida pelo lojista. */
function textoSobre(cor: string) {
  const hex = String(cor || "").replace("#", "");
  if (hex.length !== 6) return "#ffffff";
  const r = parseInt(hex.slice(0, 2), 16);
  const g = parseInt(hex.slice(2, 4), 16);
  const b = parseInt(hex.slice(4, 6), 16);
  const luz = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
  return luz > 0.62 ? "#111827" : "#ffffff";
}

export function VendorShell({
  slug,
  nomeDaLoja,
  slogan,
  logoUrl,
  corDaMarca,
  aparencia,
  cupomDoAviso,
  categorias,
  contato,
  clienteLogado,
  whatsappFlutuante,
  categoriaAtual,
  children,
}: VendorShellProps) {
  const router = useRouter();
  const caminho = usePathname();
  const { toggleCart, cartCount } = useCart();
  /* Loja em pausa ou cadastro em análise: o visitante precisa saber antes de
     montar o pedido, e a faixa fina no topo diz isso em uma linha. */
  const visao = useVisaoDaLoja();
  const avisoDaSituacao =
    visao.lojaPausada || visao.aguardandoAprovacao || visao.cadastroRecusado
      ? `${visao.motivoDoBloqueio || ""}${visao.lojaPausada && visao.regras.voltaEm ? ` Previsão de volta: ${dataCurta(visao.regras.voltaEm)}.` : ""}`
      : null;
  const [busca, setBusca] = useState("");
  /* As sugestões da busca. Vêm do servidor, poucas por vez: com mil produtos
     no catálogo, carregar tudo no navegador para filtrar é caro e lento. */
  const [sugestoes, setSugestoes] = useState<Array<{ id: string; name: string; image_url: string | null }>>([]);
  const [sugestoesAbertas, setSugestoesAbertas] = useState(false);
  const caixaDaBusca = useRef<HTMLDivElement | null>(null);
  const [menuAberto, setMenuAberto] = useState(false);
  const [categoriaAberta, setCategoriaAberta] = useState<string | null>(null);
  const barraDeNav = useRef<HTMLDivElement | null>(null);
  const cabecalho = useRef<HTMLElement | null>(null);
  /* A aba do WhatsApp aberta no celular. Recolhe sozinha: aberta para sempre,
     ela volta a atrapalhar a foto do produto. */
  const [whatsAberto, setWhatsAberto] = useState(false);
  const raiz = useRef<HTMLDivElement | null>(null);

  const corDoTexto = useMemo(() => textoSobre(corDaMarca), [corDaMarca]);
  /* O cabeçalho, o menu e o rodapé publicados no editor (migration 197).
     Sem nada publicado, o shell desenha exatamente como sempre. */
  const { navegacao, noEditor } = useNavegacaoDaLoja();
  const cabecalhoFixo = navegacao?.cabecalho?.fixo !== false;
  const mostrarBusca = navegacao?.cabecalho?.mostrar_busca !== false;
  const tamanhoDaLogo = navegacao?.cabecalho?.tamanho_da_logo ?? "normal";
  const menuProprio = navegacao?.menu ?? null;
  const rodapeProprio = navegacao?.rodape ?? null;
  const itensDoMenu = useMemo(
    () => (menuProprio && menuProprio.itens.length ? itensProntos(menuProprio.itens, { slug, categorias, paginas: navegacao?.paginas }) : null),
    [menuProprio, slug, categorias, navegacao?.paginas]
  );
  const ap = aparencia || {};
  const fundoDoCabecalho = ap.corDoCabecalho?.trim() || null;
  const textoDoCabecalho = ap.corDoTextoDoCabecalho?.trim() || (fundoDoCabecalho ? textoSobre(fundoDoCabecalho) : null);
  const fundoDoMenu = ap.corDoMenu?.trim() || fundoDoCabecalho;
  const textoDoMenu = ap.corDoTextoDoMenu?.trim() || (fundoDoMenu ? textoSobre(fundoDoMenu) : null);
  /* Fixa, a faixa entra dentro do cabeçalho grudado; solta, fica acima dele
     e sobe com a página. */
  const avisoFixo = ap.avisoFixo !== false;

  /* O efeito da logo: mesma conta do resto do sistema, classes próprias. */
  const velocidade = Math.min(200, Math.max(50, Math.round(Number(ap.logoEfeitoVelocidade) || 100)));
  const forca = Math.min(180, Math.max(40, Math.round(Number(ap.logoEfeitoIntensidade) || 100))) / 100;
  const tempo = 100 / velocidade;
  const classeDoEfeito = ap.logoEfeitoLigado
    ? ap.logoEfeitoTipo === "rotate_3d"
      ? "vd-logo-rotate3d"
      : ap.logoEfeitoTipo === "blink"
        ? "vd-logo-blink"
        : ap.logoEfeitoTipo === "pulse_glow"
          ? "vd-logo-pulse"
          : ""
    : "";

  const mostrarNome = Boolean(ap.mostrarNome && nomeDaLoja.trim());
  const mostrarSlogan = Boolean(ap.mostrarSlogan && String(slogan || "").trim());
  const corDosIcones = ap.corDosIconesDoCabecalho?.trim() || "var(--vd-primary)";

  /* As categorias de primeiro nível, com os filhos pendurados. É o que o
     menu precisa: uma linha de botões, alguns com lista que desce. */
  const arvore = useMemo(() => {
    const raizes = categorias.filter((c) => !c.parent_id);
    return raizes.map((raiz) => ({
      ...raiz,
      filhas: categorias
        .filter((c) => c.parent_id === raiz.id)
        .map((filha) => ({
          ...filha,
          netas: categorias.filter((n) => n.parent_id === filha.id),
        })),
    }));
  }, [categorias]);

  /* Espera o dedo parar antes de perguntar ao servidor. */
  useEffect(() => {
    const termo = busca.trim();
    /* Termo curto demais não vira consulta: a lista some sozinha porque o
       render já ignora sugestão com menos de dois caracteres. */
    if (termo.length < 2) return;
    let ativo = true;
    const relogio = window.setTimeout(() => {
      fetch(`/api/catalog/busca?slug=${encodeURIComponent(slug)}&q=${encodeURIComponent(termo)}`)
        .then((r) => (r.ok ? r.json() : { produtos: [] }))
        .then((j) => {
          if (ativo) setSugestoes(Array.isArray(j?.produtos) ? j.produtos : []);
        })
        .catch(() => {
          if (ativo) setSugestoes([]);
        });
    }, 220);
    return () => {
      ativo = false;
      window.clearTimeout(relogio);
    };
  }, [busca, slug]);

  useEffect(() => {
    if (!sugestoesAbertas) return;
    const foraDaBusca = (evento: MouseEvent) => {
      if (!caixaDaBusca.current?.contains(evento.target as Node)) setSugestoesAbertas(false);
    };
    document.addEventListener("mousedown", foraDaBusca);
    return () => document.removeEventListener("mousedown", foraDaBusca);
  }, [sugestoesAbertas]);

  useEffect(() => {
    if (!categoriaAberta) return;
    const foraDoMenu = (evento: MouseEvent) => {
      if (!barraDeNav.current?.contains(evento.target as Node)) setCategoriaAberta(null);
    };
    const comEsc = (evento: KeyboardEvent) => {
      if (evento.key === "Escape") setCategoriaAberta(null);
    };
    document.addEventListener("mousedown", foraDoMenu);
    document.addEventListener("keydown", comEsc);
    return () => {
      document.removeEventListener("mousedown", foraDoMenu);
      document.removeEventListener("keydown", comEsc);
    };
  }, [categoriaAberta]);

  /* Deixa registrado que esta loja é Vendor: o esqueleto de carregamento do
     sistema consulta isso para não piscar numa navegação deste template. */
  useEffect(() => {
    try {
      window.localStorage.setItem("ks_tema_da_loja", "vendor");
    } catch {
      /* Sem armazenamento, o esqueleto aparece — feio, não quebrado. */
    }
  }, []);

  /* O drawer não pode deixar a página rolar por baixo dele. */
  useEffect(() => {
    if (!menuAberto) return;
    const antes = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = antes;
    };
  }, [menuAberto]);

  function buscar(evento: React.FormEvent) {
    evento.preventDefault();
    const termo = busca.trim();
    if (!termo) return;
    router.push(`/${slug}/buscar?search=${encodeURIComponent(termo)}`);
    setMenuAberto(false);
  }

  const linkDaCategoria = (categoria: VendorCategoria) =>
    `/${slug}/c/${categoria.slug || categoria.id}`;

  const whatsappLimpo = String(contato.whatsapp || "").replace(/\D/g, "");
  const linkDoWhats = whatsappLimpo
    ? `https://wa.me/${whatsappLimpo.length <= 11 ? `55${whatsappLimpo}` : whatsappLimpo}`
    : null;

  const acoes = [
    linkDoWhats
      ? { chave: "atendimento", icone: MessageCircle, rotulo: "Atendimento", href: linkDoWhats, externo: true }
      : null,
    { chave: "conta", icone: User, rotulo: clienteLogado ? "Minha conta" : "Entrar", href: `/${slug}/cliente`, externo: false },
  ].filter(Boolean) as Array<{
    chave: string;
    icone: typeof User;
    rotulo: string;
    href: string;
    externo: boolean;
  }>;


  useEffect(() => {
    if (!whatsAberto) return;
    const recolher = window.setTimeout(() => setWhatsAberto(false), 4000);
    return () => window.clearTimeout(recolher);
  }, [whatsAberto]);

  /* A galeria da página de produto se fixa logo abaixo do cabeçalho, e a
     altura dele muda: o aviso pode estar desligado, e no celular ele ocupa
     duas linhas. Medir é mais barato que manter um número cravado que erra
     em metade das lojas. */
  useEffect(() => {
    const alvo = cabecalho.current;
    const casa = raiz.current;
    if (!alvo || !casa) return;
    const publicar = () => {
      const altura = Math.round(alvo.getBoundingClientRect().height);
      if (altura > 0) casa.style.setProperty("--vd-header-h", cabecalhoFixo ? `${altura}px` : "0px");
    };
    publicar();
    const observador = new ResizeObserver(publicar);
    observador.observe(alvo);
    window.addEventListener("resize", publicar);
    return () => {
      observador.disconnect();
      window.removeEventListener("resize", publicar);
    };
  }, [cabecalhoFixo]);

  /* A faixa é montada uma vez e usada num dos dois lugares: dentro do
     cabeçalho grudado, ou acima dele. */
  const faixaDeAviso = (
    <VendorAviso
      slug={slug}
      ligado={ap.avisoLigado}
      texto={ap.avisoTexto}
      corDeFundo={ap.avisoCorDeFundo}
      corDoTexto={ap.avisoCorDoTexto}
      botaoRotulo={ap.avisoBotaoRotulo}
      botaoUrl={ap.avisoBotaoUrl}
      cupom={cupomDoAviso}
      mostrarSelo={ap.avisoMostrarSelo}
      corDoSelo={ap.avisoCorDoSelo}
      contagemLigada={ap.avisoContagemLigada}
      contagemAte={ap.avisoContagemAte}
    />
  );

  return (
    <div
      ref={raiz}
      /* A barra fixa de compra é montada aqui dentro por portal: é neste
         elemento que moram as variáveis `--vd-*` da loja. No `body` ela
         chegava sem cor nenhuma. */
      data-vd-raiz="1"
      className={`flex min-h-screen flex-col overflow-x-clip${ap.fonteDosTitulos ? " vd-tipografia" : ""}`}
      style={
        {
          "--vd-primary": corDaMarca,
          "--vd-primary-fg": corDoTexto,
          ...(ap.corDoFundo?.trim() ? { "--vd-bg": ap.corDoFundo.trim() } : {}),
          ...(fundoDoCabecalho ? { "--vd-header-bg": fundoDoCabecalho } : {}),
          ...(textoDoCabecalho ? { "--vd-header-fg": textoDoCabecalho } : {}),
          ...(fundoDoMenu ? { "--vd-menu-bg": fundoDoMenu } : {}),
          ...(textoDoMenu ? { "--vd-menu-fg": textoDoMenu } : {}),
          ...(ap.corDoBotaoDoCard?.trim() ? { "--vd-card-button": ap.corDoBotaoDoCard.trim() } : {}),
          ...(ap.corDoRodape?.trim() ? { "--vd-footer-bg": ap.corDoRodape.trim() } : {}),
          ...(ap.corDoTextoDoRodape?.trim() ? { "--vd-footer-fg": ap.corDoTextoDoRodape.trim() } : {}),
          ...(ap.fonteDosTitulos ? { "--vd-fonte-titulo": ap.fonteDosTitulos } : {}),
          "--vd-logo-forca": String(forca),
          "--vd-logo-tempo-rotate": `${(5.2 * tempo).toFixed(2)}s`,
          "--vd-logo-tempo-pulse": `${(3.2 * tempo).toFixed(2)}s`,
          "--vd-logo-tempo-blink": `${(2.4 * tempo).toFixed(2)}s`,
          backgroundColor: "var(--vd-bg)",
          color: "var(--vd-foreground)",
          ...(ap.fonteDoTexto ? { fontFamily: ap.fonteDoTexto } : {}),
        } as React.CSSProperties
      }
    >
      {!avisoFixo ? faixaDeAviso : null}

      <header ref={cabecalho} {...marcaDeRegiao(noEditor, "cabecalho")} className={`${cabecalhoFixo ? "sticky top-0" : "relative"} z-40`}>
        {/* FAIXA 0 — a situação da loja (pausa, cadastro em análise). Fica
            grudada junto com o cabeçalho: é a informação que muda o que o
            visitante pode fazer na página inteira. */}
        {avisoDaSituacao ? (
          <div
            className="border-b px-4 py-1.5 text-center text-[12.5px] font-medium leading-snug"
            style={{ backgroundColor: "#fffbeb", color: "#92400e", borderColor: "#fde68a" }}
            role="status"
          >
            <span className="inline-flex max-w-full items-center gap-1.5">
              <Info className="h-3.5 w-3.5 shrink-0" />
              <span>{avisoDaSituacao}</span>
            </span>
          </div>
        ) : null}

        {/* FAIXA 1 — o aviso da loja, com o cupom e o relógio da promoção */}
        {avisoFixo ? faixaDeAviso : null}

        {/* FAIXA 2 — logo, busca e ações */}
        <div
          className="border-b shadow-sm"
          style={{
            borderColor: "var(--vd-border)",
            backgroundColor: "var(--vd-header-bg, var(--vd-surface))",
            color: "var(--vd-header-fg, var(--vd-foreground))",
          }}
        >
          <div className="mx-auto w-full max-w-6xl px-4 py-2.5 sm:py-3">
            {/* desktop — a faixa tem 81px cravados: com as três faixas o
                cabeçalho fecha em 152px, que é o número publicado em
                `--vd-header-h` e usado pela galeria da página de produto. */}
            <div className="hidden h-[56px] items-center gap-4 lg:grid lg:grid-cols-[minmax(150px,1fr)_minmax(288px,320px)_260px]">
              <div className="flex min-w-0 items-center justify-start gap-3">
                <Link href={`/${slug}`} className={`flex ${tamanhoDaLogo === "pequeno" ? "h-9" : tamanhoDaLogo === "grande" ? "h-14" : "h-12"} flex-shrink-0 items-center justify-start`}>
                  {logoUrl ? (
                    /* eslint-disable-next-line @next/next/no-img-element */
                    <img src={logoUrl} alt={nomeDaLoja} className={`h-full w-auto object-contain ${classeDoEfeito}`} />
                  ) : (
                    <span className="text-lg font-bold tracking-tight">{nomeDaLoja}</span>
                  )}
                </Link>
                {logoUrl && (mostrarNome || mostrarSlogan) ? (
                  <span className="min-w-0">
                    {mostrarNome ? (
                      <span
                        className="block truncate text-[15px] font-bold leading-tight"
                        style={ap.corDoNome ? { color: ap.corDoNome } : undefined}
                      >
                        {nomeDaLoja}
                      </span>
                    ) : null}
                    {mostrarSlogan ? (
                      <span
                        className="block max-w-[150px] truncate text-[11.5px] leading-tight opacity-80"
                        style={ap.corDoSlogan ? { color: ap.corDoSlogan } : undefined}
                      >
                        {slogan}
                      </span>
                    ) : null}
                  </span>
                ) : null}
              </div>

              {mostrarBusca ? (
              <div ref={caixaDaBusca} className="relative mx-auto w-full max-w-[288px]">
                <form onSubmit={buscar} className="relative">
                  <button
                    type="submit"
                    aria-label="Buscar"
                    className="absolute right-4 top-1/2 -translate-y-1/2 text-[var(--vd-muted-fg)] transition-colors hover:text-[var(--vd-foreground)]"
                  >
                    <Search className="h-5 w-5" />
                  </button>
                  <input
                    value={busca}
                    onChange={(e) => {
                      setBusca(e.target.value);
                      setSugestoesAbertas(e.target.value.trim().length >= 2);
                    }}
                    onFocus={() => setSugestoesAbertas(busca.trim().length >= 2)}
                    placeholder="O que você está procurando?"
                    className="h-10 w-full rounded-full border bg-[var(--vd-bg)] pl-5 pr-12 text-sm text-[var(--vd-foreground)] shadow-sm outline-none transition-colors placeholder:text-[var(--vd-muted-fg)]"
                    style={{ borderColor: "color-mix(in srgb, var(--vd-primary) 50%, transparent)" }}
                  />
                </form>

                {/* As sugestões aparecem enquanto se digita e levam direto ao
                    produto. A última linha leva à página de resultados, que é
                    o caminho de sempre. */}
                {sugestoesAbertas && busca.trim().length >= 2 && sugestoes.length ? (
                  <div
                    className="absolute left-0 right-0 top-[calc(100%+8px)] z-50 overflow-hidden border bg-[var(--vd-surface)] py-1 text-[var(--vd-foreground)] shadow-xl"
                    style={{ borderRadius: "var(--vd-radius-lg)", borderColor: "var(--vd-border)" }}
                  >
                    {sugestoes.map((produto) => (
                      <Link
                        key={produto.id}
                        href={`/${slug}/p/${produto.id}`}
                        onClick={() => {
                          setSugestoesAbertas(false);
                          setBusca("");
                        }}
                        className="flex items-center gap-3 px-3 py-2 transition-colors hover:bg-[var(--vd-muted-bg)]"
                      >
                        <span
                          className="h-9 w-9 shrink-0 overflow-hidden bg-white"
                          style={{ borderRadius: "var(--vd-radius-md)", border: "1px solid var(--vd-border)" }}
                        >
                          {produto.image_url ? (
                            /* eslint-disable-next-line @next/next/no-img-element */
                            <img src={produto.image_url} alt="" className="h-full w-full object-cover" />
                          ) : null}
                        </span>
                        <span className="min-w-0 flex-1 truncate text-[13.5px]">{produto.name}</span>
                      </Link>
                    ))}
                    <button
                      type="button"
                      onClick={(evento) => {
                        buscar(evento);
                        setSugestoesAbertas(false);
                      }}
                      className="w-full border-t px-3 py-2 text-left text-[12.5px] font-semibold"
                      style={{ borderColor: "var(--vd-border)", color: "var(--vd-primary)" }}
                    >
                      Ver todos os resultados
                    </button>
                  </div>
                ) : null}
              </div>
              ) : (
                <div />
              )}

              <div className="flex items-center justify-end gap-1">
                {acoes.map((acao) => {
                  const Icone = acao.icone;
                  const conteudo = (
                    <>
                      <Icone className="h-4 w-4 shrink-0" />
                      <span className="text-[11px]">{acao.rotulo}</span>
                    </>
                  );
                  const classe =
                    "inline-flex h-auto min-h-[52px] w-[76px] flex-col items-center justify-center gap-1 rounded-lg px-2 py-2 text-sm font-medium transition-all duration-200 hover:bg-[color-mix(in_srgb,var(--vd-primary)_10%,transparent)]";
                  return acao.externo ? (
                    <a
                      key={acao.chave}
                      href={acao.href}
                      target="_blank"
                      rel="noopener noreferrer"
                      className={classe}
                      style={{ color: corDosIcones }}
                    >
                      {conteudo}
                    </a>
                  ) : (
                    <Link key={acao.chave} href={acao.href} className={classe} style={{ color: corDosIcones }}>
                      {conteudo}
                    </Link>
                  );
                })}
                <button
                  type="button"
                  onClick={toggleCart}
                  className="relative inline-flex h-[52px] w-[76px] flex-col items-center justify-center gap-1 rounded-lg px-2 py-1.5 text-sm font-medium transition-all duration-200 hover:bg-[color-mix(in_srgb,var(--vd-primary)_10%,transparent)]"
                  style={{ color: corDosIcones }}
                >
                  <ShoppingCart className="h-4 w-4 shrink-0" />
                  <span className="text-[11px]">Meu carrinho</span>
                  {cartCount > 0 ? (
                    <span
                      className="absolute right-3 top-1 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-bold"
                      style={{ backgroundColor: "var(--vd-primary)", color: "var(--vd-primary-fg)" }}
                    >
                      {cartCount}
                    </span>
                  ) : null}
                </button>
              </div>
            </div>

            {/* mobile: uma linha com menu, logo e carrinho; a busca desce */}
            <div className="lg:hidden">
              <div className="flex items-center justify-between gap-3">
                <button
                  type="button"
                  aria-label="Abrir menu"
                  onClick={() => setMenuAberto(true)}
                  className="rounded-lg p-2 text-[var(--vd-foreground)]"
                >
                  <Menu className="h-5 w-5" />
                </button>
                <Link href={`/${slug}`} className="flex h-10 min-w-0 flex-1 items-center justify-center">
                  {logoUrl ? (
                    /* eslint-disable-next-line @next/next/no-img-element */
                    <img src={logoUrl} alt={nomeDaLoja} className={`h-full w-auto object-contain ${classeDoEfeito}`} />
                  ) : (
                    <span className="truncate text-base font-bold">{nomeDaLoja}</span>
                  )}
                </Link>
                <button
                  type="button"
                  onClick={toggleCart}
                  aria-label="Abrir carrinho"
                  className="relative rounded-lg p-2"
                  style={{ color: corDosIcones }}
                >
                  <ShoppingCart className="h-5 w-5" />
                  {cartCount > 0 ? (
                    <span
                      className="absolute right-0 top-0 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-bold"
                      style={{ backgroundColor: "var(--vd-primary)", color: "var(--vd-primary-fg)" }}
                    >
                      {cartCount}
                    </span>
                  ) : null}
                </button>
              </div>
              {mostrarBusca ? (
              <form onSubmit={buscar} className="relative mt-2">
                <button
                  type="submit"
                  aria-label="Buscar"
                  className="absolute right-4 top-1/2 -translate-y-1/2 text-[var(--vd-muted-fg)]"
                >
                  <Search className="h-4 w-4" />
                </button>
                <input
                  value={busca}
                  onChange={(e) => setBusca(e.target.value)}
                  placeholder="O que você está procurando?"
                  className="h-10 w-full rounded-full border bg-[var(--vd-bg)] pl-4 pr-11 text-sm outline-none placeholder:text-[var(--vd-muted-fg)]"
                  style={{ borderColor: "color-mix(in srgb, var(--vd-primary) 50%, transparent)" }}
                />
              </form>
              ) : null}
            </div>
          </div>
        </div>

        {/* FAIXA 3 — as categorias */}
        <div
          ref={barraDeNav}
          className="relative hidden border-b lg:block"
          style={{
            borderColor: "var(--vd-border)",
            backgroundColor: "var(--vd-menu-bg, var(--vd-surface))",
            color: "var(--vd-menu-fg, var(--vd-foreground))",
          }}
        >
          {itensDoMenu ? (
            <VendorFaixaDoMenuProprio
              slug={slug}
              itens={itensDoMenu}
              mostrarCategorias={menuProprio?.mostrar_categorias !== false}
              arvore={arvore}
              linkDaCategoria={linkDaCategoria}
            />
          ) : (
          <>
          <div className="mx-auto w-full max-w-6xl px-4">
            {/* O item da rota atual vira pílula cheia; o que está com o painel
                aberto ganha um fundo suave. É assim que o menu diz onde a
                pessoa está sem precisar de uma segunda linha de texto. */}
            <nav className="flex flex-nowrap items-center justify-center gap-1 py-1">
              <Link
                href={`/${slug}`}
                className="flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-md px-2.5 py-1.5 text-xs font-semibold transition-opacity hover:opacity-80"
              >
                <Menu className="h-4 w-4 shrink-0" />
                Todos os Produtos
              </Link>

              {arvore.slice(0, 8).map((categoria) => {
                const aberta = categoriaAberta === categoria.id;
                const rota = linkDaCategoria(categoria);
                /* Ativo quando se está na categoria, numa filha dela, ou num
                   produto que pertence a qualquer uma das duas. */
                const idsDaFamilia = [categoria.id, categoria.slug || "", ...categoria.filhas.flatMap((f) => [f.id, f.slug || "", ...f.netas.flatMap((n) => [n.id, n.slug || ""])])].filter(Boolean);
                const naRota =
                  caminho === rota ||
                  categoria.filhas.some((f) => caminho === linkDaCategoria(f)) ||
                  (Boolean(categoriaAtual) && idsDaFamilia.includes(String(categoriaAtual)));
                const estilo = naRota
                  ? { backgroundColor: "var(--vd-primary)", color: "var(--vd-primary-fg)", opacity: 1 }
                  : aberta
                    ? { backgroundColor: "color-mix(in srgb, currentColor 12%, transparent)", opacity: 1 }
                    : { opacity: 0.85 };

                if (!categoria.filhas.length) {
                  return (
                    <Link
                      key={categoria.id}
                      href={rota}
                      className="flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md px-2.5 py-1.5 text-xs font-medium transition-all"
                      style={estilo}
                    >
                      {categoria.name}
                    </Link>
                  );
                }

                return (
                  <div
                    key={categoria.id}
                    className="shrink-0"
                    onMouseEnter={() => setCategoriaAberta(categoria.id)}
                  >
                    <button
                      type="button"
                      onClick={() => setCategoriaAberta(aberta ? null : categoria.id)}
                      className="flex shrink-0 items-center gap-1 whitespace-nowrap rounded-md px-2.5 py-1.5 text-xs font-medium transition-all"
                      style={estilo}
                    >
                      {categoria.name}
                      <ChevronDown
                        className={`h-3.5 w-3.5 shrink-0 transition-transform ${aberta ? "rotate-180" : ""}`}
                      />
                    </button>
                  </div>
                );
              })}
            </nav>
          </div>

          {categoriaAberta ? (
            <div
              className="absolute inset-x-0 top-full border-b bg-[var(--vd-surface)] text-[var(--vd-foreground)] shadow-xl"
              style={{ borderColor: "var(--vd-border)" }}
              onMouseLeave={() => setCategoriaAberta(null)}
            >
              <div className="mx-auto w-full max-w-6xl px-4 py-6">
                {/* Três colunas de listas. Subcategoria com filhas vira título
                    de coluna; sem filhas, entra na lista solta da primeira. */}
                <div className="grid grid-cols-3 gap-x-10 gap-y-6">
                  {(() => {
                    const grupo = arvore.find((c) => c.id === categoriaAberta);
                    if (!grupo) return null;
                    const comFilhas = grupo.filhas.filter((f) => f.netas.length > 0);
                    const soltas = grupo.filhas.filter((f) => f.netas.length === 0);
                    const colunas: React.ReactNode[] = [];

                    if (soltas.length) {
                      colunas.push(
                        <div key="soltas" className="min-w-0">
                          <p
                            className="mb-2 border-b pb-2 text-[13px] font-bold"
                            style={{ borderColor: "var(--vd-border)" }}
                          >
                            {grupo.name}
                          </p>
                          <div className="space-y-1.5">
                            {soltas.map((filha) => (
                              <Link
                                key={filha.id}
                                href={linkDaCategoria(filha)}
                                onClick={() => setCategoriaAberta(null)}
                                className="block truncate text-[13px] text-[var(--vd-muted-fg)] transition-colors hover:text-[var(--vd-primary)]"
                              >
                                {filha.name}
                              </Link>
                            ))}
                          </div>
                        </div>
                      );
                    }

                    for (const filha of comFilhas) {
                      colunas.push(
                        <div key={filha.id} className="min-w-0">
                          <Link
                            href={linkDaCategoria(filha)}
                            onClick={() => setCategoriaAberta(null)}
                            className="mb-2 block border-b pb-2 text-[13px] font-bold"
                            style={{ borderColor: "var(--vd-border)" }}
                          >
                            {filha.name}
                          </Link>
                          <div className="space-y-1.5">
                            {filha.netas.map((neta) => (
                              <Link
                                key={neta.id}
                                href={linkDaCategoria(neta)}
                                onClick={() => setCategoriaAberta(null)}
                                className="block truncate text-[13px] text-[var(--vd-muted-fg)] transition-colors hover:text-[var(--vd-primary)]"
                              >
                                {neta.name}
                              </Link>
                            ))}
                          </div>
                        </div>
                      );
                    }

                    return colunas;
                  })()}
                </div>
              </div>
            </div>
          ) : null}
          </>
          )}
        </div>
      </header>

      {/* drawer de categorias no mobile */}
      {menuAberto ? (
        <div className="fixed inset-0 z-50 lg:hidden">
          <div className="absolute inset-0 bg-black/40" onClick={() => setMenuAberto(false)} />
          <div className="absolute inset-y-0 left-0 flex w-[86%] max-w-sm flex-col bg-[var(--vd-surface)] shadow-xl">
            <div className="flex items-center justify-between border-b px-4 py-3" style={{ borderColor: "var(--vd-border)" }}>
              <span className="text-sm font-bold">{itensDoMenu ? "Menu" : "Categorias"}</span>
              <button type="button" onClick={() => setMenuAberto(false)} aria-label="Fechar menu" className="p-1">
                <X className="h-5 w-5" />
              </button>
            </div>
            <div className="flex-1 overflow-y-auto px-2 py-2">
              {itensDoMenu ? <VendorGavetaDoMenuProprio itens={itensDoMenu} aoEscolher={() => setMenuAberto(false)} /> : null}
              {menuProprio?.mostrar_categorias !== false ? (
              <>
              <Link
                href={`/${slug}`}
                onClick={() => setMenuAberto(false)}
                className="flex items-center justify-between rounded-lg px-3 py-2.5 text-sm font-semibold"
              >
                Todos os Produtos
                <ChevronRight className="h-4 w-4 opacity-40" />
              </Link>
              {arvore.map((categoria) => (
                <div key={categoria.id}>
                  <Link
                    href={linkDaCategoria(categoria)}
                    onClick={() => setMenuAberto(false)}
                    className="flex items-center justify-between rounded-lg px-3 py-2.5 text-sm"
                  >
                    {categoria.name}
                    <ChevronRight className="h-4 w-4 opacity-40" />
                  </Link>
                  {categoria.filhas.length ? (
                    <div className="mb-1 ml-3 border-l pl-3" style={{ borderColor: "var(--vd-border)" }}>
                      {categoria.filhas.map((filha) => (
                        <Link
                          key={filha.id}
                          href={linkDaCategoria(filha)}
                          onClick={() => setMenuAberto(false)}
                          className="block rounded-lg px-3 py-2 text-[13px] text-[var(--vd-muted-fg)]"
                        >
                          {filha.name}
                        </Link>
                      ))}
                    </div>
                  ) : null}
                </div>
              ))}
              </>
              ) : null}
            </div>
          </div>
        </div>
      ) : null}

      <main className="flex-1">{children}</main>

      {rodapeProprio ? (
        <VendorRodapeProprio
          regiao={marcaDeRegiao(noEditor, "rodape")}
          slug={slug}
          nomeDaLoja={nomeDaLoja}
          contato={contato}
          linkDoWhats={linkDoWhats}
          categorias={arvore}
          linkDaCategoria={linkDaCategoria}
          sobre={rodapeProprio.sobre}
          colunas={rodapeProprio.colunas.map((coluna) => ({
            id: coluna.id,
            titulo: coluna.titulo,
            links: itensProntos(coluna.links, { slug, categorias, paginas: navegacao?.paginas })
              .filter((link) => link.destino)
              .map((link) => ({ id: link.id, rotulo: link.rotulo, destino: link.destino! })),
          }))}
          mostrarContato={rodapeProprio.mostrar_contato}
          mostrarRedes={rodapeProprio.mostrar_redes}
          mostrarPagamento={rodapeProprio.mostrar_pagamento}
          mostrarCategorias={rodapeProprio.mostrar_categorias}
        />
      ) : (
      <footer
        {...marcaDeRegiao(noEditor, "rodape")}
        className="mt-10 border-t"
        style={{
          backgroundColor: "var(--vd-footer-bg)",
          color: "var(--vd-footer-fg)",
          borderColor: "var(--vd-footer-border)",
        }}
      >
        <div className="mx-auto w-full max-w-6xl px-4 py-8">
          <div className="grid gap-8 lg:grid-cols-[1.1fr_1fr_1fr]">
            <section className="space-y-4">
              <h3 className="text-sm font-extrabold uppercase tracking-wide">Entre em contato</h3>
              <div className="space-y-3 text-sm opacity-80">
                {linkDoWhats ? (
                  <a href={linkDoWhats} target="_blank" rel="noopener noreferrer" className="flex gap-3 transition-opacity hover:opacity-100">
                    <Phone className="h-4 w-4 shrink-0" />
                    <span>{contato.whatsapp}</span>
                  </a>
                ) : null}
                {contato.telefone ? (
                  <p className="flex gap-3">
                    <Phone className="h-4 w-4 shrink-0" />
                    <span>{contato.telefone}</span>
                  </p>
                ) : null}
                {contato.email ? (
                  <a href={`mailto:${contato.email}`} className="flex gap-3 transition-opacity hover:opacity-100">
                    <Mail className="h-4 w-4 shrink-0" />
                    <span>{contato.email}</span>
                  </a>
                ) : null}
                {contato.endereco ? (
                  <p className="flex gap-3">
                    <MapPin className="h-4 w-4 shrink-0" />
                    <span>{contato.endereco}</span>
                  </p>
                ) : null}
              </div>
            </section>

            <section className="space-y-4">
              <h3 className="text-sm font-extrabold uppercase tracking-wide">Formas de pagamento</h3>
              <div className="flex flex-wrap gap-2">
                {["Pix", "Cartão de crédito", "Boleto"].map((forma) => (
                  <span
                    key={forma}
                    className="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium"
                    style={{ borderRadius: "var(--vd-radius-md)", backgroundColor: "rgba(255,255,255,0.08)" }}
                  >
                    <CreditCard className="h-3.5 w-3.5" />
                    {forma}
                  </span>
                ))}
              </div>
              <h3 className="pt-2 text-sm font-extrabold uppercase tracking-wide">Categorias</h3>
              <div className="space-y-2 text-sm opacity-80">
                {arvore.slice(0, 5).map((categoria) => (
                  <Link key={categoria.id} href={linkDaCategoria(categoria)} className="block transition-opacity hover:opacity-100">
                    {categoria.name}
                  </Link>
                ))}
              </div>
            </section>

            <section className="space-y-4">
              <h3 className="text-sm font-extrabold uppercase tracking-wide">Compra 100% segura</h3>
              <div
                className="flex items-start gap-3 p-4"
                style={{
                  borderRadius: "var(--vd-radius-lg)",
                  backgroundColor: "rgba(255,255,255,0.06)",
                }}
              >
                <ShieldCheck className="mt-0.5 h-5 w-5 shrink-0 opacity-90" />
                <div className="min-w-0">
                  <p className="text-sm font-semibold">Seus dados estão protegidos</p>
                  <p className="mt-1 text-xs leading-relaxed opacity-70">
                    Loja com conexão segura e pagamento processado por instituição autorizada.
                  </p>
                </div>
              </div>
              <div className="space-y-2 text-sm opacity-80">
                <Link href={`/${slug}/cliente`} className="block transition-opacity hover:opacity-100">
                  Meus pedidos
                </Link>
                {contato.instagram ? (
                  <a href={contato.instagram} target="_blank" rel="noopener noreferrer" className="block transition-opacity hover:opacity-100">
                    Instagram
                  </a>
                ) : null}
                {contato.facebook ? (
                  <a href={contato.facebook} target="_blank" rel="noopener noreferrer" className="block transition-opacity hover:opacity-100">
                    Facebook
                  </a>
                ) : null}
              </div>
            </section>
          </div>

          {contato.cnpj ? (
            <p className="mt-8 border-t pt-6 text-justify text-xs leading-relaxed opacity-70" style={{ borderColor: "var(--vd-footer-border)" }}>
              {nomeDaLoja} · CNPJ {contato.cnpj}. O prazo de produção começa a contar depois da aprovação da arte e da
              confirmação do pagamento, e não inclui o tempo de entrega.
            </p>
          ) : null}

          <p className="pt-8 text-center text-[11px] font-light opacity-70">
            © {new Date().getFullYear()}, {nomeDaLoja}. Todos os direitos reservados.
          </p>
        </div>
      </footer>
      )}

      {/* O WhatsApp é a aba vertical na lateral. O canto inferior direito fica
          livre para o balão de atendimento da loja — os dois no mesmo canto se
          empilhavam e um cobria o outro. */}
      {whatsappFlutuante !== false && linkDoWhats ? (
        <div data-flutuante-da-loja="" className="pointer-events-none fixed left-0 top-1/3 z-40 w-[min(400px,100vw)] overflow-x-clip">
          <a
            href={linkDoWhats}
            target="_blank"
            rel="noopener noreferrer"
            aria-label="Falar no WhatsApp"
            /* No celular a tag inteira cobria a foto do produto. Lá ela nasce
               só com o símbolo; o primeiro toque abre o nome, o segundo leva
               para a conversa. No computador continua sempre aberta. */
            onClick={(evento) => {
              if (whatsAberto) return;
              if (typeof window === "undefined") return;
              if (!window.matchMedia("(max-width: 639px)").matches) return;
              evento.preventDefault();
              setWhatsAberto(true);
            }}
            /* Em `vertical-rl` o eixo principal do flex é o vertical: `row`
               empilha de cima para baixo. Assim a leitura é símbolo e depois
               nome, e a tag fica alta e estreita. */
            className="pointer-events-auto inline-flex flex-row items-center gap-2 rounded-r-lg bg-[#25D366] px-2 py-2.5 text-[11px] font-semibold tracking-wide text-white shadow-lg transition-transform hover:translate-x-0.5 sm:py-4 [writing-mode:vertical-rl]"
          >
            {/* Girado junto com o texto: em `vertical-rl` a letra vira, o SVG não,
                 e o ícone ficava de pé ao lado de um nome deitado. */}
            <svg viewBox="0 0 24 24" className="h-4 w-4 shrink-0 rotate-90" fill="currentColor" aria-hidden="true">
              <path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z" />
            </svg>
            <span className={whatsAberto ? "inline" : "hidden sm:inline"}>WhatsApp</span>
          </a>
        </div>
      ) : null}
    </div>
  );
}

/** 2026-10-13 vira 13/10/2026, como a faixa dos outros temas. */
function dataCurta(valor: string) {
  const partes = String(valor).slice(0, 10).split("-");
  if (partes.length !== 3) return valor;
  return `${partes[2]}/${partes[1]}/${partes[0]}`;
}
