"use client";

import { useMemo, useState, type CSSProperties, type ReactNode } from "react";
import Link from "next/link";
import { ChevronLeft, ChevronRight, ImagePlus } from "lucide-react";
import {
  FORMATOS_DE_BANNER,
  PROPORCOES_DA_IMAGEM,
  configDaSecao,
  destinoDaSecao,
  fotosDasCategorias,
  lerBanner,
  lerCarrossel,
  lerGrade,
  modoDaSecao,
  quantidadeDeProdutos,
  type EspacoVertical,
  type ImagemDaSecao,
  type LinkDaSecao,
} from "@/lib/pagina-inicial";
import { useCarrossel } from "@/lib/use-carrossel";
import { miniatura } from "@/lib/foto";
import { useNoEditor } from "@/components/editor-da-loja/contexto";
import { BoutiqueCardDoProduto, type BoutiqueProduto } from "./BoutiqueCardDoProduto";
import {
  BoutiqueCardsDeCategoria,
  BoutiqueCirculosDeItens,
  BoutiqueSecaoDeProdutos,
  BoutiqueTituloDeVitrine,
  BoutiqueTituloEditorial,
  BoutiqueTopSellers,
  BoutiqueVazio,
  abasDoTopSellers,
  eyebrowDaVitrine,
  type BoutiqueCardDeCategoria,
} from "./BoutiqueBlocosDaHome";
import type { BoutiqueCategoria } from "./BoutiqueShell";
import { ehWidget } from "@/lib/widgets-da-home";
import { BoutiqueWidgetDaHome } from "./BoutiqueWidgetsDaHome";
import { CaixaDaSecao } from "@/components/home/CaixaDaSecao";

/*
  As seções da página inicial da Boutique: a home montada pelo editor, a home
  automática (escrita como seções por arranjoAutomaticoDaBoutique, em
  lib/pagina-inicial.ts) e as páginas extras usam todas este desenho.

  A linguagem é a da referência: seções de borda a borda, sem raio; vitrines
  com o eyebrow pequeno e o título enorme em caixa alta à esquerda, com a
  linha embaixo, em carrossel de quatro (setas redondas, pontos, anda sozinho
  a cada 3 s); "Primeiros produtos" é o TOP SELLERS centralizado com abas;
  "Atalhos de categorias" são os cards grandes com degradê e o título em
  Georgia; banners e imagens lado a lado vão de borda a borda, sem raio.
  Os blocos novos (oferta, cupom, vídeo, perguntas...) moram em
  BoutiqueWidgetsDaHome. As cores e o tamanho de título das seções (que o
  Padrão e o Vitrine usam) não entram: o painel os esconde na família Vendor.

  Agendamento, aparelho, fundo e contagem de cliques ficam com a CaixaDaSecao
  (a mesma dos outros temas); a moldura do editor vem de `envolver`.
*/

export type BoutiqueSecaoDaHome = {
  id: string;
  title?: string | null;
  layout_width?: string | null;
  section_type?: string | null;
  config?: unknown;
  /* Produtos escolhidos à mão, já montados pela página. */
  products?: BoutiqueProduto[];
  /* Só no editor: a agendada fora da janela aparece como se estivesse no ar. */
  previa_no_ar?: boolean;
};

type Contexto = {
  slug: string;
  produtos: BoutiqueProduto[];
  categorias: BoutiqueCategoria[];
  clienteId?: string | null;
  favoritos?: string[] | null;
  corDaMarca?: string;
  /* Entra nos eyebrows ("NOVIDADES FEMME"). */
  nomeDaLoja?: string | null;
};

const MARGEM: Record<EspacoVertical, string> = { nenhum: "py-0", pequeno: "pt-3", normal: "py-6" };
const LOTE = 40;

function LinkDaSecaoBoutique({
  link,
  ctx,
  className,
  style,
  children,
  rotulo,
}: {
  link: LinkDaSecao;
  ctx: Contexto;
  className?: string;
  style?: CSSProperties;
  children: ReactNode;
  rotulo?: string;
}) {
  const destino = destinoDaSecao(link, ctx.slug, ctx.categorias);
  if (!destino) {
    return (
      <div className={className} style={style}>
        {children}
      </div>
    );
  }
  const alvo = destino.novaAba ? { target: "_blank", rel: "noopener noreferrer" } : {};
  if (destino.externo) {
    return (
      <a href={destino.href} className={className} style={style} aria-label={rotulo} {...alvo}>
        {children}
      </a>
    );
  }
  return (
    <Link href={destino.href} className={className} style={style} aria-label={rotulo} {...alvo}>
      {children}
    </Link>
  );
}

function Foto({ item, alt, className = "" }: { item: { imagem: string; imagem_celular?: string }; alt: string; className?: string }) {
  const classe = `absolute inset-0 h-full w-full object-cover ${className}`;
  if (item.imagem_celular) {
    return (
      <picture>
        <source media="(max-width: 639px)" srcSet={miniatura(item.imagem_celular, 900)} />
        <img src={miniatura(item.imagem, 1600)} alt={alt} loading="lazy" className={classe} draggable={false} />
      </picture>
    );
  }
  // eslint-disable-next-line @next/next/no-img-element
  return <img src={miniatura(item.imagem, 1600)} alt={alt} loading="lazy" className={classe} draggable={false} />;
}

/* ------------------------------------------------ imagens lado a lado */

const COLUNAS: Record<string, string> = {
  "2": "sm:grid-cols-2",
  "3": "sm:grid-cols-3",
  "4": "sm:grid-cols-2 lg:grid-cols-4",
  "1+2": "sm:grid-cols-2 sm:grid-rows-2",
  "2+1": "sm:grid-cols-2 sm:grid-rows-2",
};
const LUGAR: Record<string, string[]> = {
  "1+2": ["sm:col-start-1 sm:row-start-1 sm:row-span-2", "sm:col-start-2 sm:row-start-1", "sm:col-start-2 sm:row-start-2"],
  "2+1": ["sm:col-start-1 sm:row-start-1", "sm:col-start-1 sm:row-start-2", "sm:col-start-2 sm:row-start-1 sm:row-span-2"],
};
/* Na Boutique as imagens quase se encostam, como os cards de categoria da
   referência (2 px). Os cantos seguem a escala do tema: reto, 3 px e 8 px. */
const ESPACO: Record<string, string> = { nenhum: "gap-0", pequeno: "gap-[2px]", medio: "gap-[6px]" };
const RAIO: Record<string, string> = { retos: "0px", suaves: "3px", redondos: "8px" };

function BoutiqueImagensLadoALado({ secao, ctx }: { secao: BoutiqueSecaoDaHome; ctx: Contexto }) {
  const editor = useNoEditor();
  const grade = lerGrade(configDaSecao(secao.config));
  const quantas = grade.layout === "1+2" || grade.layout === "2+1" ? 3 : Number(grade.layout);
  const itens: Array<ImagemDaSecao | null> = Array.from({ length: quantas }, (_, i) => grade.itens[i] ?? null);
  const visiveis = editor ? itens : itens.filter((item) => item?.imagem);
  if (!visiveis.length) return null;

  const mosaico = grade.layout === "1+2" || grade.layout === "2+1";
  const proporcao = PROPORCOES_DA_IMAGEM[grade.proporcao].proporcao;
  const noCelular =
    grade.celular === "deslizar"
      ? "bq-sem-barra flex snap-x snap-mandatory overflow-x-auto sm:grid sm:overflow-visible"
      : grade.celular === "lado_a_lado"
        ? "grid grid-cols-2"
        : "grid grid-cols-1";
  const larguraDoItem =
    grade.celular === "deslizar" ? `${quantas === 2 ? "w-full" : "w-[84%]"} shrink-0 snap-start sm:w-auto` : "";

  return (
    <div className={`w-full ${MARGEM[grade.margem]}`}>
      {grade.mostrarTitulo && secao.title ? (
        <BoutiqueTituloEditorial titulo={secao.title} centro className="px-4 pb-8 pt-10 md:pb-10 md:pt-14" />
      ) : null}
      <div className={`${noCelular} ${COLUNAS[grade.layout]} ${ESPACO[grade.espaco]}`}>
        {visiveis.map((item, indice) => {
          const lugar = mosaico ? LUGAR[grade.layout][indice] || "" : "";
          const grande = lugar.includes("row-span-2");
          const medida = grande ? "aspect-[var(--proporcao)] sm:aspect-auto sm:h-full" : "aspect-[var(--proporcao)]";
          const estilo = { ["--proporcao" as string]: String(proporcao), borderRadius: RAIO[grade.cantos] } as CSSProperties;
          if (!item?.imagem) {
            return (
              <div key={`vazio-${indice}`} className={`${larguraDoItem} ${lugar} ${medida}`} style={estilo}>
                <BoutiqueVazio texto={`Imagem ${indice + 1}`} icone={<ImagePlus className="h-5 w-5" />} style={{ height: "100%", borderRadius: RAIO[grade.cantos] }} />
              </div>
            );
          }
          return (
            <LinkDaSecaoBoutique
              key={`${item.imagem}-${indice}`}
              link={item.link}
              ctx={ctx}
              rotulo={item.legenda || undefined}
              className={`group relative block overflow-hidden bg-[var(--bq-foto-fundo)] ${larguraDoItem} ${lugar} ${medida}`}
              style={estilo}
            >
              <Foto item={item} alt={item.legenda || ""} className="bq-zoom-lento" />
              {item.legenda ? (
                <>
                  <span className="pointer-events-none absolute inset-0" style={{ background: "linear-gradient(180deg, transparent 50%, rgba(0,0,0,0.5) 100%)" }} />
                  <span className="pointer-events-none absolute inset-x-5 bottom-5 text-white md:inset-x-8 md:bottom-7">
                    <span className="bq-revista block text-[24px] leading-[1.05] tracking-[-0.03em] md:text-[clamp(24px,2.4vw,38px)]">{item.legenda}</span>
                    <span className="mt-3 inline-flex items-center gap-2 border-b border-white pb-1 text-[9px] font-bold uppercase tracking-[0.14em]">
                      Ver mais <span className="bq-seta-texto" aria-hidden="true">→</span>
                    </span>
                  </span>
                </>
              ) : null}
            </LinkDaSecaoBoutique>
          );
        })}
      </div>
    </div>
  );
}

/* ---------------------------------------------- carrossel de banners */

function BoutiqueCarrosselDeBanners({ secao, ctx }: { secao: BoutiqueSecaoDaHome; ctx: Contexto }) {
  const editor = useNoEditor();
  const carrossel = lerCarrossel(configDaSecao(secao.config));
  const itens = carrossel.itens.filter((item) => item.imagem);
  const { atual, ir, anterior, seguinte, eventos } = useCarrossel(itens.length, carrossel.automatico, carrossel.intervalo);
  const proporcao = String(FORMATOS_DE_BANNER[carrossel.formato].proporcao);

  if (!itens.length) {
    if (!editor) return null;
    return (
      <div className={`w-full ${MARGEM[carrossel.margem]}`}>
        <BoutiqueVazio texto="Carrossel de banners: adicione as imagens no painel" icone={<ImagePlus className="h-5 w-5" />} style={{ aspectRatio: proporcao }} />
      </div>
    );
  }

  return (
    <div className={`w-full ${MARGEM[carrossel.margem]}`}>
      <div className="relative w-full overflow-hidden bg-[var(--bq-foto-fundo)]" style={{ aspectRatio: proporcao }} aria-roledescription="carrossel" {...eventos}>
        <div className="flex h-full will-change-transform" style={{ transform: `translateX(-${atual * 100}%)`, transition: "transform 0.6s var(--bq-curva)" }}>
          {itens.map((item, indice) => (
            <LinkDaSecaoBoutique key={`${item.imagem}-${indice}`} link={item.link} ctx={ctx} rotulo={item.legenda || `Banner ${indice + 1}`} className="relative h-full min-w-full shrink-0">
              <Foto item={item} alt={item.legenda || ""} />
            </LinkDaSecaoBoutique>
          ))}
        </div>
        {itens.length > 1 ? (
          <>
            {/* As setas do banner da referência: quadradas, brancas, coladas na borda. */}
            <button type="button" aria-label="Banner anterior" onClick={anterior} className="bq-seta-quadrada absolute left-0 top-1/2 z-10 hidden -translate-y-1/2 sm:flex">
              <ChevronLeft className="h-5 w-5" strokeWidth={1.4} />
            </button>
            <button type="button" aria-label="Próximo banner" onClick={seguinte} className="bq-seta-quadrada absolute right-0 top-1/2 z-10 hidden -translate-y-1/2 sm:flex">
              <ChevronRight className="h-5 w-5" strokeWidth={1.4} />
            </button>
            <div className="absolute bottom-3 left-1/2 flex -translate-x-1/2">
              {itens.map((_, i) => (
                <button key={i} type="button" aria-label={`Banner ${i + 1}`} onClick={() => ir(i)} className="flex h-[25px] w-[22px] items-center justify-center">
                  <span className="bq-ponto bq-ponto-claro" {...(i === atual ? { "data-ativo": "" } : {})} />
                </button>
              ))}
            </div>
          </>
        ) : null}
      </div>
    </div>
  );
}

/* --------------------------------------------------------- banner */

function BoutiqueBannerDaSecao({ secao, ctx }: { secao: BoutiqueSecaoDaHome; ctx: Contexto }) {
  const editor = useNoEditor();
  const banner = lerBanner(configDaSecao(secao.config));
  const proporcao = String(FORMATOS_DE_BANNER[banner.formato || "faixa"].proporcao);
  if (!banner.imagem) {
    if (!editor) return null;
    return (
      <div className={`w-full ${MARGEM[banner.margem]}`}>
        <BoutiqueVazio texto="Banner: escolha a imagem no painel" icone={<ImagePlus className="h-5 w-5" />} style={{ aspectRatio: proporcao }} />
      </div>
    );
  }
  const temTexto = Boolean(banner.titulo || banner.subtitulo || banner.botao) && banner.formato !== "faixa" && Boolean(banner.formato);
  const claro = banner.tom === "claro";
  const centro = banner.alinhamento === "centro";
  return (
    <div className={`w-full ${MARGEM[banner.margem]}`}>
      <LinkDaSecaoBoutique
        link={banner.link}
        ctx={ctx}
        rotulo={banner.titulo || secao.title || "Banner"}
        className="group relative block w-full overflow-hidden bg-[var(--bq-foto-fundo)]"
        style={{ aspectRatio: proporcao }}
      >
        <Foto item={{ imagem: banner.imagem, imagem_celular: banner.imagemCelular }} alt={banner.titulo || secao.title || ""} className="bq-zoom-lento" />
        {temTexto ? (
          <>
            <span
              className="pointer-events-none absolute inset-0"
              style={{
                background: claro
                  ? centro
                    ? "rgba(0,0,0,0.32)"
                    : "linear-gradient(90deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.2) 45%, transparent 75%)"
                  : centro
                    ? "rgba(255,255,255,0.4)"
                    : "linear-gradient(90deg, rgba(255,255,255,0.85) 0%, rgba(255,255,255,0.4) 45%, transparent 75%)",
              }}
            />
            <span
              className={`absolute inset-0 flex flex-col justify-center gap-2 px-6 md:gap-3 md:px-[60px] ${centro ? "items-center text-center" : "items-start text-left"}`}
              style={{ color: claro ? "#ffffff" : "var(--bq-tinta)" }}
            >
              {secao.title && banner.titulo && secao.title !== banner.titulo ? (
                <span className="text-[9px] font-bold uppercase tracking-[0.18em] opacity-90">{secao.title}</span>
              ) : null}
              {banner.titulo ? (
                <span className="bq-revista max-w-2xl text-[28px] leading-[1.02] tracking-[-0.035em] md:text-[clamp(34px,4.4vw,64px)]">{banner.titulo}</span>
              ) : null}
              {banner.subtitulo ? <span className="hidden max-w-lg text-[13px] leading-relaxed opacity-90 sm:block">{banner.subtitulo}</span> : null}
              {banner.botao ? (
                <span className="bq-link-sublinhado mt-2">
                  {banner.botao} <span className="bq-seta-texto" aria-hidden="true">→</span>
                </span>
              ) : null}
            </span>
          </>
        ) : null}
      </LinkDaSecaoBoutique>
    </div>
  );
}

/* ------------------------------------------------ todos os produtos */

function BoutiqueTodosOsProdutos({ secao, ctx }: { secao: BoutiqueSecaoDaHome; ctx: Contexto }) {
  const [quantos, setQuantos] = useState(LOTE);
  if (!ctx.produtos.length) return null;
  return (
    <section id="produtos" className="w-full scroll-mt-28 pb-12 md:pb-16">
      <BoutiqueTituloDeVitrine eyebrow={eyebrowDaVitrine("colecao", ctx.nomeDaLoja)} titulo={secao.title || "Todos os produtos"} />
      <div className="mt-[30px] grid grid-cols-2 gap-x-[2px] gap-y-8 md:grid-cols-4 md:gap-x-[6px] md:gap-y-10">
        {ctx.produtos.slice(0, quantos).map((produto) => (
          <div key={produto.id} className="md:px-[5px]">
            <BoutiqueCardDoProduto produto={produto} slug={ctx.slug} clienteId={ctx.clienteId} favoritos={ctx.favoritos} corDaMarca={ctx.corDaMarca} />
          </div>
        ))}
      </div>
      {ctx.produtos.length > quantos ? (
        <div className="mt-10 flex justify-center">
          <button type="button" onClick={() => setQuantos((n) => n + LOTE)} className="bq-botao-contorno">
            Ver mais produtos ({ctx.produtos.length - quantos})
          </button>
        </div>
      ) : null}
    </section>
  );
}

/* ------------------------------------------------------- a seção */

function descendentes(id: string, categorias: BoutiqueCategoria[]) {
  const achadas = new Set<string>([id]);
  const pilha = [id];
  while (pilha.length) {
    const atual = pilha.pop() as string;
    for (const c of categorias) {
      if (c.parent_id === atual && !achadas.has(c.id)) {
        achadas.add(c.id);
        pilha.push(c.id);
      }
    }
  }
  return achadas;
}

/* A foto do card grande da categoria: a 2ª foto (a da modelo) de um produto
   dela, como na home automática; senão, a foto de sempre. */
function fotoParaOCard(categoriaId: string, ctx: Contexto, fotos: Map<string, string>) {
  const ids = descendentes(categoriaId, ctx.categorias);
  const daCategoria = ctx.produtos.filter((p) => ids.has(String((p as BoutiqueProduto & { category_id?: string }).category_id || "")));
  for (const produto of daCategoria) {
    const imagens = [...(produto.product_images || [])].filter((img) => img?.image_url).sort((a, b) => Number(a.sort_order ?? 0) - Number(b.sort_order ?? 0));
    const principal = imagens.find((img) => img.is_primary) || imagens[0];
    const segunda = imagens.find((img) => img.image_url !== (principal?.image_url || produto.image_url));
    if (segunda?.image_url) return segunda.image_url;
  }
  return fotos.get(categoriaId) || null;
}

function BoutiqueSecao({ secao, ctx, fotos }: { secao: BoutiqueSecaoDaHome; ctx: Contexto; fotos: Map<string, string> }) {
  const editor = useNoEditor();
  const modo = modoDaSecao(secao);
  const config = configDaSecao(secao.config);
  const titulo = String(secao.title || "").trim();

  /* Os blocos novos (oferta, cupom, vídeo, perguntas...): BoutiqueWidgetsDaHome. */
  if (ehWidget(modo)) return <BoutiqueWidgetDaHome secao={secao} ctx={ctx} />;
  if (modo === "image_grid") return <BoutiqueImagensLadoALado secao={secao} ctx={ctx} />;
  if (modo === "banner_carousel") return <BoutiqueCarrosselDeBanners secao={secao} ctx={ctx} />;
  if (modo === "image_banner") return <BoutiqueBannerDaSecao secao={secao} ctx={ctx} />;
  if (modo === "all_products") return <BoutiqueTodosOsProdutos secao={secao} ctx={ctx} />;

  if (modo === "category_circles") {
    const raizes = ctx.categorias.filter((c) => !c.parent_id);
    const limite = Number(config.limite) > 0 ? Math.min(12, Math.trunc(Number(config.limite))) : null;
    if (!raizes.length) {
      return editor ? (
        <div className="px-4 py-6">
          <BoutiqueVazio texto="Categorias em círculos: a loja ainda não tem categorias" />
        </div>
      ) : null;
    }
    return (
      <section className="w-full pb-8 pt-10 md:pb-10 md:pt-14">
        {titulo ? <BoutiqueTituloEditorial eyebrow="Navegue por categoria" titulo={titulo} centro className="px-4" /> : null}
        <BoutiqueCirculosDeItens
          itens={raizes.map((categoria) => ({
            chave: categoria.id,
            href: `/${ctx.slug}/c/${categoria.slug || categoria.id}`,
            nome: categoria.name,
            foto: fotos.get(categoria.id) || null,
          }))}
          noComputador={limite ?? 6}
          noCelular={limite ?? 10}
        />
      </section>
    );
  }

  /* Atalhos de categorias: os cards grandes da referência (foto, degradê,
     kicker, nome em Georgia e o link sublinhado). */
  if (modo === "category_navigator") {
    const itens = (Array.isArray(config.items) ? config.items : [])
      .map((bruto) => {
        const item = (bruto || {}) as Record<string, unknown>;
        const id = String(item.target_category_id || "");
        const categoria = ctx.categorias.find((c) => c.id === id || (item.target_category_slug && c.slug === item.target_category_slug));
        const caminho = String(item.target_category_slug || categoria?.slug || "");
        if (!caminho) return null;
        return {
          id: categoria?.id || id,
          caminho,
          nome: String(item.label || "").trim() || categoria?.name || "Categoria",
          foto: String(item.image_url || "") || null,
        };
      })
      .filter((item): item is NonNullable<typeof item> => Boolean(item))
      .slice(0, 12);
    if (!itens.length) {
      return editor ? (
        <div className="px-4 py-6">
          <BoutiqueVazio texto="Atalhos de categorias: escolha as categorias no painel" style={{ minHeight: 160 }} />
        </div>
      ) : null;
    }
    const cards: BoutiqueCardDeCategoria[] = itens.map((item, indice) => ({
      chave: `${item.id || item.caminho}-${indice}`,
      nome: item.nome,
      href: `/${ctx.slug}/c/${item.caminho}`,
      foto: item.foto || (item.id ? fotoParaOCard(item.id, ctx, fotos) : null),
      kicker: indice === 0 ? eyebrowDaVitrine("selecao", ctx.nomeDaLoja) : "Descubra também",
      chamada: indice === 0 ? "Ver coleção" : "Descobrir",
    }));
    return (
      <section className="w-full">
        {cards.length > 2 && titulo ? <BoutiqueTituloDeVitrine eyebrow={eyebrowDaVitrine("colecao", ctx.nomeDaLoja)} titulo={titulo} /> : null}
        <div className={cards.length > 2 && titulo ? "pt-[30px]" : ""}>
          <BoutiqueCardsDeCategoria cards={cards} />
        </div>
      </section>
    );
  }

  /* "Primeiros produtos" na Boutique é o TOP SELLERS: título centralizado,
     abas (os primeiros da loja e as categorias principais) e a grade. */
  if (modo === "featured_products") {
    const quantidade = quantidadeDeProdutos(config, 4);
    const abas = abasDoTopSellers(ctx.produtos, ctx.categorias, ctx.slug, quantidade);
    if (!abas.some((aba) => aba.produtos.length)) {
      return editor ? (
        <div className="px-4 py-6">
          <BoutiqueVazio texto={`${titulo || "Top sellers"}: a loja ainda não tem produtos à mostra`} />
        </div>
      ) : null;
    }
    return (
      <BoutiqueTopSellers
        titulo={titulo || "Top sellers"}
        abas={abas}
        slug={ctx.slug}
        clienteId={ctx.clienteId}
        favoritos={ctx.favoritos}
        corDaMarca={ctx.corDaMarca}
      />
    );
  }

  /* As seções de produtos: vitrine em carrossel. */
  let produtos: BoutiqueProduto[] = [];
  let verTudo: string | null = null;
  let limite = 4;
  let eyebrow = eyebrowDaVitrine("selecao", ctx.nomeDaLoja);
  if (modo === "manual_products") {
    produtos = secao.products || [];
    limite = 48;
  } else if (modo === "category_products" || modo === "subcategory_products") {
    const alvo = String(config.target_category_id || "");
    const categoria = ctx.categorias.find((c) => c.id === alvo);
    if (categoria) {
      const ids = modo === "subcategory_products" || config.so_da_categoria === true ? new Set([alvo]) : descendentes(alvo, ctx.categorias);
      produtos = ctx.produtos.filter((p) => ids.has(String((p as BoutiqueProduto & { category_id?: string }).category_id || "")));
      if (config.show_view_more !== false) verTudo = `/${ctx.slug}/c/${categoria.slug || categoria.id}`;
    }
    limite = quantidadeDeProdutos(config, 4);
    eyebrow = eyebrowDaVitrine("destaques", ctx.nomeDaLoja);
  }

  if (!produtos.length) {
    return editor ? (
      <div className="px-4 py-6">
        <BoutiqueVazio texto={`${titulo || "Seção"}: nenhum produto para mostrar ainda`} style={{ minHeight: 160 }} />
      </div>
    ) : null;
  }

  return (
    <BoutiqueSecaoDeProdutos
      eyebrow={eyebrow}
      titulo={titulo || "Produtos"}
      produtos={produtos}
      slug={ctx.slug}
      verTudoHref={verTudo}
      clienteId={ctx.clienteId}
      favoritos={ctx.favoritos}
      corDaMarca={ctx.corDaMarca}
      limite={limite}
    />
  );
}

export function BoutiqueSecoesDaHome({
  secoes,
  envolver,
  contarCliques = false,
  ...ctx
}: Contexto & {
  secoes: BoutiqueSecaoDaHome[];
  /* Só o editor passa: a moldura de cada seção. */
  envolver?: (secao: BoutiqueSecaoDaHome, indice: number, conteudo: ReactNode) => ReactNode;
  /* A loja montada pelo editor conta os cliques de cada seção (migration 199). */
  contarCliques?: boolean;
}) {
  const fotos = useMemo(() => fotosDasCategorias(ctx.produtos as never), [ctx.produtos]);
  return (
    <>
      {secoes.map((secao, indice) => {
        /* A caixa comum de toda seção (aparelho, fundo, espaço): sem ajuste, a seção sai sozinha. */
        const conteudo = (
          <CaixaDaSecao key={secao.id} secao={secao} familia="boutique" contarCliques={contarCliques}>
            <BoutiqueSecao secao={secao} ctx={ctx} fotos={fotos} />
          </CaixaDaSecao>
        );
        return envolver ? envolver(secao, indice, conteudo) : conteudo;
      })}
    </>
  );
}
