"use client";

import Link from "next/link";
import { useMemo, useState, type ReactNode } from "react";
import { ArrowRight, Check, ChevronLeft, ChevronRight, Clock, Copy, MapPin, Phone, Play, Radio, Ticket, Timer, Zap } from "lucide-react";
import { configDaSecao, destinoDaSecao, lerLink, modoDaSecao } from "@/lib/pagina-inicial";
import {
  PROPORCOES_DO_WIDGET,
  PROPORCOES_DOS_PONTOS,
  SEGUNDOS_DA_FAIXA,
  capaDoVideo,
  condicoesDoCupom,
  cupomAutomatico,
  contaDoCorte,
  cupomValeAgora,
  descontoDoCupom,
  emReais,
  enderecoDaRota,
  enderecoDigitado,
  enderecoDoMapa,
  enderecoDoPlayer,
  fotoDoProdutoDoWidget,
  lancamentos,
  lerAntesEDepois,
  lerAvisoDoCorte,
  lerCupomEmDestaque,
  lerFaixa,
  lerImagemComPontos,
  lerKits,
  lerListaAutomatica,
  lerOferta,
  lerOndeEstamos,
  lerPerguntas,
  lerProximaLive,
  lerTextoComImagem,
  lerTextoSimples,
  lerVideo,
  lerVistos,
  liveDaVez,
  ofertaNoAr,
  partesDaContagem,
  precoComDesconto,
  precoDoCartao,
  precoFixo,
  produtosNaOrdem,
  quandoDaLive,
  relogioDaContagem,
  seloDoCombo,
  type BlocoDoTexto,
  type EspacoDoWidget,
  type PedacoDoTexto,
} from "@/lib/widgets-da-home";
import { useNoEditor } from "@/components/editor-da-loja/contexto";
import { useVisaoDaLoja } from "@/components/VisaoDaLojaContext";
import { useAgora, useDadosDosWidgets } from "@/components/home/contexto-dos-widgets";
import { useBarraDeComparacao, useCopiar, useMovimentoReduzido, useVistos } from "@/components/home/ganchos-dos-widgets";
import { fotoDoProduto, segundaFotoDoProduto, type BoutiqueProduto } from "./BoutiqueCardDoProduto";
import { BoutiqueSecaoDeProdutos, BoutiqueTituloEditorial, BoutiqueVazio, eyebrowDaVitrine } from "./BoutiqueBlocosDaHome";
import { BoutiqueLooks, type BoutiqueLook } from "./BoutiqueLooks";
import type { BoutiqueCategoria } from "./BoutiqueShell";

/*
  Os blocos novos da página inicial na Boutique (os temas Padrão e Vitrine
  têm os deles em components/home/WidgetsDaHome.tsx; o Vendor, os dele).
  Só os dados e as regras (lib/widgets-da-home, ganchos-dos-widgets) são
  divididos; o desenho é o da referência:

  - as listas (lançamentos, mais vendidos, vistos, a oferta) são vitrines:
    eyebrow, título enorme à esquerda com a linha embaixo e o carrossel;
  - os blocos de conteúdo (vídeo, texto com imagem, live, onde estamos) são
    "de revista": foto de borda a borda ao lado de um painel papel (#F4F0EB)
    com o eyebrow espaçado, o título em Georgia e o botão preto;
  - o cupom é a caixa de cupom da página do produto da referência;
  - as perguntas são o acordeão da descrição do produto;
  - os kits viram o "Elas vestem" (BoutiqueLooks.tsx explica por quê).

  Raio zero, preto nas ações (a cor da loja entra por --bq-primary quando a
  personalização avançada está ligada) e o caramelo (--bq-accent) só nos
  detalhes do cupom.
*/

type Ctx = {
  slug: string;
  produtos: BoutiqueProduto[];
  categorias: BoutiqueCategoria[];
  clienteId?: string | null;
  favoritos?: string[] | null;
  corDaMarca?: string;
  nomeDaLoja?: string | null;
};

type Secao = { id: string; title?: string | null; config?: unknown };
type Props = { secao: Secao; ctx: Ctx };

const MARGEM: Record<EspacoDoWidget, string> = { nenhum: "py-0", pequeno: "py-3", normal: "py-6" };
const CONTEUDO = "mx-auto w-full max-w-[1240px] px-4 md:px-6";

function Bloco({ margem, children, className = "" }: { margem: EspacoDoWidget; children: ReactNode; className?: string }) {
  return <section className={`w-full ${MARGEM[margem]} ${className}`}>{children}</section>;
}

/* O botão preto da Boutique (VER PRODUTO, TRAÇAR ROTA...). */
function classeDoBotao(extra = "") {
  return `bq-botao-preto inline-flex h-[50px] items-center justify-center gap-3 px-8 ${extra}`;
}

/* ------------------------------------------------- oferta relâmpago */

function Quadradinho({ valor, rotulo }: { valor: number; rotulo: string }) {
  return (
    <span className="flex flex-col items-center gap-1.5">
      <span
        className="flex h-[52px] min-w-[52px] items-center justify-center border px-1.5 text-[24px] font-medium tabular-nums leading-none text-[var(--bq-tinta)] md:h-[58px] md:min-w-[58px] md:text-[28px]"
        style={{ borderColor: "rgba(17,17,17,0.2)" }}
        suppressHydrationWarning
      >
        {String(valor).padStart(2, "0")}
      </span>
      <span className="text-[8px] font-bold uppercase tracking-[0.16em]" style={{ color: "var(--bq-eyebrow)" }}>
        {rotulo}
      </span>
    </span>
  );
}

function BoutiqueOferta({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const agora = useAgora(1000);
  const oferta = lerOferta(configDaSecao(secao.config));
  const lista = produtosNaOrdem(oferta.produtos, ctx.produtos);
  const noAr = ofertaNoAr(oferta, agora);
  if (!editor && (!noAr || !lista.length)) return null;
  if (!lista.length) {
    return (
      <Bloco margem={oferta.margem} className="px-4">
        <BoutiqueVazio texto="Oferta relâmpago: escolha os produtos e a hora do fim no painel" icone={<Zap className="h-5 w-5" />} />
      </Bloco>
    );
  }
  const falta = oferta.terminaEm ? oferta.terminaEm - agora : 0;
  const partes = partesDaContagem(falta);
  const relogio = noAr ? (
    <div className="flex max-w-[440px] flex-col gap-2 md:ml-auto md:items-end md:text-right" role="timer" aria-label={`Termina em ${relogioDaContagem(falta)}`}>
      <p className="text-[9px] font-bold uppercase tracking-[0.2em]" style={{ color: "var(--bq-accent)" }}>
        {oferta.subtitulo || "Termina em"}
      </p>
      <span className="flex items-start gap-1.5 md:gap-2" aria-hidden>
        {partes.dias > 0 ? <Quadradinho valor={partes.dias} rotulo="dias" /> : null}
        <Quadradinho valor={partes.horas} rotulo="horas" />
        <Quadradinho valor={partes.minutos} rotulo="min" />
        <Quadradinho valor={partes.segundos} rotulo="seg" />
      </span>
    </div>
  ) : (
    <p className="max-w-[320px] text-[11px] leading-relaxed" style={{ color: "var(--bq-benef)" }}>
      {oferta.terminaEm ? "Esta oferta já terminou: na loja ela não aparece mais." : "Escolha no painel quando a oferta termina."}
    </p>
  );
  return (
    <Bloco margem={oferta.margem}>
      <BoutiqueSecaoDeProdutos
        eyebrow={oferta.selo || "Oferta relâmpago"}
        titulo={String(secao.title || "").trim() || "Oferta relâmpago"}
        produtos={lista}
        slug={ctx.slug}
        clienteId={ctx.clienteId}
        favoritos={ctx.favoritos}
        corDaMarca={ctx.corDaMarca}
        limite={48}
        lado={relogio}
      />
    </Bloco>
  );
}

/* ---------------------------------------------------- cupom em destaque */

function BoutiqueCupom({ secao }: Props) {
  const editor = useNoEditor();
  const dados = useDadosDosWidgets();
  const agora = useAgora(30000);
  const { estado, copiar } = useCopiar();
  const ajuste = lerCupomEmDestaque(configDaSecao(secao.config));
  const cupom = dados?.cupons.find((c) => c.id === ajuste.cupomId) ?? null;
  if (!cupom || !cupomValeAgora(cupom, agora)) {
    if (!editor) return null;
    return (
      <Bloco margem={ajuste.margem} className="px-4">
        <BoutiqueVazio
          icone={<Ticket className="h-5 w-5" />}
          texto={cupom ? "Este cupom não vale agora (desligado, vencido ou ainda não começou)" : "Cupom em destaque: escolha um cupom ativo no painel"}
        />
      </Bloco>
    );
  }
  const condicoes = condicoesDoCupom(cupom, ajuste.mostrarValidade);
  const automatico = cupomAutomatico(cupom);
  return (
    <Bloco margem={ajuste.margem} className="px-4 py-10 md:py-14">
      <div className="bq-cupom mx-auto max-w-[880px]">
        <div className="grid gap-5 md:grid-cols-[minmax(0,1fr)_1px_minmax(0,1fr)] md:gap-8">
          <div className="flex flex-col justify-center">
            <p className="text-[9px] font-semibold uppercase tracking-[0.16em]" style={{ color: "var(--bq-accent)" }}>
              {secao.title || "Oferta especial"}
            </p>
            <p className="mt-2 text-[23px] font-normal leading-tight text-[#171717] md:text-[30px]">
              {descontoDoCupom(cupom)}{" "}
              {ajuste.chamada ? (
                <em className="bq-revista italic" style={{ color: "var(--bq-accent)" }}>
                  {ajuste.chamada}
                </em>
              ) : null}
            </p>
          </div>
          <span aria-hidden className="hidden bg-[#e4ded8] md:block" />
          <div className="flex flex-col justify-center border-t pt-5 md:border-t-0 md:pt-0" style={{ borderColor: "#e4ded8" }}>
            {automatico ? (
              <>
                <p className="text-[9px] font-semibold uppercase tracking-[0.16em] text-[#6e6a66]">Aproveite seu desconto</p>
                <p className="mt-2 flex items-center gap-2 text-[15px] text-[#1c1c1c]">
                  <Check className="h-4 w-4 shrink-0" style={{ color: "var(--bq-accent)" }} strokeWidth={2.5} /> Desconto automático no carrinho
                </p>
              </>
            ) : (
              <>
                <p className="text-[9px] font-semibold uppercase tracking-[0.16em] text-[#6e6a66]">Aproveite seu desconto</p>
                <p className="mt-2 text-[15px] text-[#1c1c1c]">
                  Use o cupom <strong className="font-bold">{cupom.code}</strong>
                </p>
                <div className="mt-3 flex flex-wrap items-center gap-3">
                  <button
                    type="button"
                    onClick={() => copiar(cupom.code)}
                    className="bq-cupom-codigo inline-flex h-10 items-center gap-2 px-4 text-[13px] font-bold tracking-[0.12em]"
                    aria-label={`Copiar o cupom ${cupom.code}`}
                  >
                    {estado === "copiado" ? <Check className="h-4 w-4" strokeWidth={2.5} /> : <Copy className="h-4 w-4" />}
                    {estado === "copiado" ? "Copiado!" : cupom.code}
                  </button>
                </div>
                <p className="mt-2 text-[11px] text-[#6e6a66]">
                  {estado === "falhou" ? "Não deu para copiar: selecione o código e copie." : "Clique no cupom para copiar o código."}
                </p>
                <span className="sr-only" aria-live="polite">
                  {estado === "copiado" ? "Cupom copiado." : ""}
                </span>
              </>
            )}
          </div>
        </div>
        {condicoes.length ? (
          <div className="mt-5 flex items-start gap-3 border-t pt-4" style={{ borderColor: "#e4ded8" }}>
            <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[#faf6f2]" style={{ color: "var(--bq-accent)" }}>
              <Ticket className="h-4 w-4" strokeWidth={1.5} />
            </span>
            <ul className="flex flex-col gap-1 text-[12px] leading-relaxed text-[#252525]">
              {condicoes.map((c) => (
                <li key={c} suppressHydrationWarning>
                  {c}
                </li>
              ))}
            </ul>
          </div>
        ) : null}
      </div>
    </Bloco>
  );
}

/* --------------------------------------------- peça até as 16h */

function BoutiqueCorte({ secao }: Props) {
  const editor = useNoEditor();
  const dados = useDadosDosWidgets();
  const agora = useAgora(1000);
  const ajuste = lerAvisoDoCorte(configDaSecao(secao.config));
  const corte = dados?.corte;
  const conta = corte?.ligado && corte.hora ? contaDoCorte(corte.hora, agora) : null;
  if (!conta) {
    if (!editor) return null;
    return (
      <Bloco margem={ajuste.margem} className="px-4">
        <BoutiqueVazio icone={<Timer className="h-5 w-5" />} texto="Ligue o corte de produção para este aviso aparecer" detalhe="Catálogo > Personalização > Corte de produção." />
      </Bloco>
    );
  }
  return (
    <Bloco margem={ajuste.margem}>
      <div className="w-full border-y bg-[var(--bq-surface)]" style={{ borderColor: "var(--bq-linha)" }}>
        <div className="mx-auto flex max-w-[1240px] flex-wrap items-center justify-center gap-x-6 gap-y-3 px-4 py-[18px] text-center md:py-[22px]">
          <Clock className="h-6 w-6 shrink-0 text-[var(--bq-tinta)]" strokeWidth={1.35} />
          <div className="min-w-0 text-left">
            <p className="text-[9px] font-bold uppercase tracking-[0.18em]" style={{ color: "var(--bq-eyebrow)" }}>
              {conta.hoje ? "Seu pedido entra em" : "Produção do dia encerrada"}
            </p>
            <p className="mt-1 text-[12px] font-extrabold uppercase leading-tight tracking-[0.11em] text-[var(--bq-tinta)] md:text-[14px]">
              {conta.hoje ? ajuste.frase || "Produção hoje, se finalizado até" : `Pedidos de agora: lote ${conta.amanha ? "de amanhã" : `de ${conta.proximoDia}`}`}
            </p>
            <p className="mt-1 text-[11px] md:text-[13px]" style={{ color: "var(--bq-benef)" }}>
              {conta.hoje ? ajuste.destaque || "Dias úteis, horário de Brasília" : `O corte é às ${conta.hora}, de segunda a sexta`}
            </p>
          </div>
          <div className="flex items-center gap-3" role={conta.hoje ? "timer" : undefined}>
            <span className="bg-[var(--bq-primary)] px-3 py-2 text-[15px] font-semibold tabular-nums leading-none text-[var(--bq-primary-fg)]">{conta.hora}</span>
            {conta.hoje ? (
              <span className="text-[11px] font-medium tabular-nums" style={{ color: "var(--bq-benef)" }} suppressHydrationWarning>
                faltam {relogioDaContagem(conta.faltaMs)}
              </span>
            ) : null}
          </div>
        </div>
      </div>
    </Bloco>
  );
}

/* --------------------------------------------------------- próxima live */

function BoutiqueLive({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const dados = useDadosDosWidgets();
  const agora = useAgora(1000);
  const ajuste = lerProximaLive(configDaSecao(secao.config));
  const vez = liveDaVez(dados?.lives ?? [], agora);
  if (!vez) {
    if (!ajuste.mostrarSemLive) {
      return editor ? (
        <Bloco margem={ajuste.margem} className="px-4">
          <BoutiqueVazio icone={<Radio className="h-5 w-5" />} texto="Nenhuma live de venda marcada na vitrine" detalhe="Na loja o bloco fica escondido até haver uma." />
        </Bloco>
      ) : null;
    }
    return (
      <Bloco margem={ajuste.margem}>
        <div className="w-full bg-[var(--bq-papel)] px-4 py-12 text-center md:py-16">
          <BoutiqueTituloEditorial eyebrow="Ao vivo" titulo={secao.title || "Próxima live"} centro />
          <p className="mx-auto mt-4 max-w-[520px] text-[13px] leading-[1.75] text-[#6d6a66]">{ajuste.semLive}</p>
        </div>
      </Bloco>
    );
  }
  const { live, momento } = vez;
  const noAr = momento === "ao_vivo";
  const aberta = momento === "espera";
  const comeca = new Date(live.comeca_em).getTime();
  return (
    <Bloco margem={ajuste.margem}>
      <Link href={`/${ctx.slug}/live/${encodeURIComponent(live.id)}`} className="group grid w-full md:grid-cols-[1.05fr_0.95fr]">
        <div className="relative aspect-[4/3] w-full overflow-hidden bg-[#e8e3dd] md:aspect-auto md:min-h-[480px]">
          {live.capa ? (
            /* eslint-disable-next-line @next/next/no-img-element */
            <img src={live.capa} alt="" loading="lazy" className="bq-zoom-lento absolute inset-0 h-full w-full object-cover" />
          ) : (
            <span className="absolute inset-0 flex items-center justify-center bg-[#111111]">
              <Radio className="h-14 w-14 text-white/40" strokeWidth={1.2} />
            </span>
          )}
          <span className="absolute left-[18px] top-[18px] inline-flex items-center gap-2 bg-white/85 px-3 py-2 text-[9px] font-bold uppercase tracking-[0.16em] text-[#111111] backdrop-blur">
            {noAr ? <span className="h-1.5 w-1.5 animate-pulse rounded-full bg-[#ff0000] motion-reduce:animate-none" /> : <Clock className="h-3 w-3" />}
            {noAr ? "Ao vivo agora" : aberta ? "Sala aberta" : "Agendada"}
          </span>
        </div>
        <div className="flex flex-col justify-center bg-[var(--bq-papel)] px-6 py-12 md:px-[72px] md:py-[72px]">
          <p className="text-[9px] font-bold uppercase tracking-[0.2em] text-[#111111] md:text-[10px]">{secao.title || "Próxima live"}</p>
          <h3 className="bq-revista bq-titulo-editorial mt-3 text-[#111111]">{live.titulo}</h3>
          <p className="mt-5 text-[13px] leading-[1.75] text-[#6d6a66]" suppressHydrationWarning>
            {noAr ? "Acontecendo agora: entre e compre ao vivo." : quandoDaLive(comeca)}
          </p>
          {!noAr && comeca > agora ? (
            <p className="mt-2 text-[11px] font-bold uppercase tracking-[0.14em] text-[#111111]" suppressHydrationWarning>
              Começa em <span className="tabular-nums">{relogioDaContagem(comeca - agora)}</span>
            </p>
          ) : null}
          <span className={classeDoBotao("mt-8 self-start")}>
            {noAr ? "Entrar agora" : aberta ? "Entrar na sala" : "Ver a live"} <span className="bq-seta-texto" aria-hidden="true">→</span>
          </span>
        </div>
      </Link>
    </Bloco>
  );
}

/* ---------------------------------------------------- listas automáticas */

function BoutiqueLista({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const dados = useDadosDosWidgets();
  const lista = lerListaAutomatica(configDaSecao(secao.config));
  const maisVendidos = lista.lista === "mais_vendidos";
  const produtos = maisVendidos
    ? produtosNaOrdem(dados?.maisVendidos?.[String(lista.dias) as "7" | "30" | "90"] ?? [], ctx.produtos).slice(0, lista.quantidade)
    : lancamentos(ctx.produtos as Array<BoutiqueProduto & { created_at?: unknown }>, lista.quantidade);
  if (!produtos.length) {
    return editor ? (
      <Bloco margem={lista.margem} className="px-4">
        <BoutiqueVazio
          texto={maisVendidos ? `Ainda sem vendas nos últimos ${lista.dias} dias` : "A loja ainda não tem produtos à mostra"}
          detalhe="Sem produto, o bloco fica escondido na loja."
        />
      </Bloco>
    ) : null;
  }
  return (
    <Bloco margem={lista.margem}>
      <BoutiqueSecaoDeProdutos
        eyebrow={eyebrowDaVitrine(maisVendidos ? "destaques" : "novidades", ctx.nomeDaLoja)}
        titulo={String(secao.title || "").trim() || (maisVendidos ? "Mais vendidos" : "Lançamentos")}
        produtos={produtos}
        slug={ctx.slug}
        clienteId={ctx.clienteId}
        favoritos={ctx.favoritos}
        corDaMarca={ctx.corDaMarca}
        limite={lista.quantidade}
      />
    </Bloco>
  );
}

/* ------------------------------------- kits e combos = "Elas vestem" */

function semAcentoNemPontuacao(texto: string) {
  return String(texto || "")
    .normalize("NFD")
    .replace(/[̀-ͯ]/g, "")
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, " ")
    .trim();
}

/* O nome que o "Compre junto" dá sozinho (e as variações dele que as lojas
   repetem em todos os kits): não diferencia um look do outro. */
const NOMES_GENERICOS_DO_KIT = new Set([
  "compre junto",
  "compre junto e economize",
  "compre junto e ganhe desconto",
  "leve junto",
  "aproveite",
  "kit",
  "combo",
]);

/* O nome que a Boutique dá a cada kit, sem repetir: o nome do kit quando ele
   é próprio (não é o genérico e só este kit usa); senão "Peça A + Peça B"
   quando cabe no card, ou o nome da peça principal. Se a peça principal se
   repete em dois kits, vai o par, que é o que diferencia. */
const CABE_NO_CARD = 46;

export function nomesDosLooks(kits: Array<{ titulo?: string | null; principal: string; junto: string }>): string[] {
  const usos = new Map<string, number>();
  for (const kit of kits) {
    const chave = semAcentoNemPontuacao(String(kit.titulo || ""));
    if (chave) usos.set(chave, (usos.get(chave) || 0) + 1);
  }
  const principais = new Map<string, number>();
  for (const kit of kits) {
    const chave = semAcentoNemPontuacao(kit.principal);
    principais.set(chave, (principais.get(chave) || 0) + 1);
  }
  return kits.map((kit) => {
    const titulo = String(kit.titulo || "").trim();
    const chave = semAcentoNemPontuacao(titulo);
    if (chave && !NOMES_GENERICOS_DO_KIT.has(chave) && (usos.get(chave) || 0) === 1) return titulo;
    const principal = String(kit.principal || "").trim();
    const junto = String(kit.junto || "").trim();
    const par = junto ? `${principal} + ${junto}` : principal;
    const principalRepete = (principais.get(semAcentoNemPontuacao(principal)) || 0) > 1;
    return par.length <= CABE_NO_CARD || principalRepete ? par : principal;
  });
}

/* O título da seção é o que a loja escreveu no editor. Vazio, ou o nome que
   o bloco ganha ao nascer no painel ("Kits e combos"), vira o padrão da
   Boutique: "Elas vestem <loja>". */
export function tituloDosLooks(tituloDaSecao: string | null | undefined, nomeDaLoja: string) {
  const titulo = String(tituloDaSecao || "").trim();
  if (titulo && semAcentoNemPontuacao(titulo) !== "kits e combos") return titulo;
  const nome = String(nomeDaLoja || "").trim();
  return nome ? `Elas vestem ${nome}` : "Elas vestem";
}

function BoutiqueKits({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const dados = useDadosDosWidgets();
  const visao = useVisaoDaLoja();
  const ajuste = lerKits(configDaSecao(secao.config));
  const porId = useMemo(() => new Map(ctx.produtos.map((p) => [String(p.id), p])), [ctx.produtos]);
  const kits = (dados?.combos ?? [])
    .filter((c) => !ajuste.combos.length || ajuste.combos.includes(c.id))
    .sort((a, b) => (ajuste.combos.length ? ajuste.combos.indexOf(a.id) - ajuste.combos.indexOf(b.id) : 0))
    .map((combo) => ({ combo, principal: porId.get(combo.main_product_id), junto: porId.get(combo.combo_product_id) }))
    .filter((k): k is { combo: typeof k.combo; principal: BoutiqueProduto; junto: BoutiqueProduto } => Boolean(k.principal && k.junto))
    .slice(0, ajuste.quantidade);
  const nome = String(ctx.nomeDaLoja || "").trim();
  const titulo = tituloDosLooks(secao.title, nome);
  if (!kits.length) {
    return editor ? (
      <Bloco margem={ajuste.margem}>
        <div className="bg-[var(--bq-papel)] px-4 py-12">
          <BoutiqueVazio texto={`${titulo}: nenhum look para mostrar`} detalhe="Os looks saem dos kits do “Compre junto” dos produtos (as duas peças precisam estar à mostra na loja)." />
        </div>
      </Bloco>
    ) : null;
  }
  const comPreco = !dados?.semPreco && visao.mostrarPreco;
  const textoSemPreco = visao.textoNoLugarDoPreco || "";
  const nomes = nomesDosLooks(kits.map(({ combo, principal, junto }) => ({ titulo: combo.title, principal: principal.name, junto: junto.name })));
  const looks: BoutiqueLook[] = kits.map(({ combo, principal, junto }, indice) => {
    const p1 = precoFixo(principal);
    const p2 = precoFixo(junto);
    const total = p1 !== null && p2 !== null ? p1 + precoComDesconto(p2, combo) : null;
    return {
      chave: combo.id,
      nome: nomes[indice] || principal.name,
      foto: segundaFotoDoProduto(principal) || fotoDoProduto(principal) || fotoDoProduto(junto),
      pecas: [principal, junto],
      preco: comPreco && total !== null ? emReais(total) : null,
      selo: comPreco ? seloDoCombo(combo) : null,
      precoDaPeca: Object.fromEntries(
        [principal, junto].map((p) => [String(p.id), comPreco ? precoDoCartao(p, textoSemPreco).texto : textoSemPreco])
      ),
    };
  });
  return (
    <Bloco margem={ajuste.margem}>
      <BoutiqueLooks
        eyebrow={nome ? `Inspiração ${nome}` : "Inspiração"}
        titulo={titulo}
        subtitulo="Looks montados pela loja com peças que conversam entre si. Descubra as peças e encontre a sua próxima inspiração."
        looks={looks}
        slug={ctx.slug}
      />
    </Bloco>
  );
}

/* --------------------------------------------- vistos recentemente */

function BoutiqueVistos({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const ajuste = lerVistos(configDaSecao(secao.config));
  const ids = useVistos(ctx.slug);
  const lista = produtosNaOrdem(ids, ctx.produtos).slice(0, ajuste.quantidade);
  if (!lista.length) {
    return editor ? (
      <Bloco margem={ajuste.margem} className="px-4">
        <BoutiqueVazio
          icone={<Clock className="h-5 w-5" />}
          texto="Os produtos que o visitante abriu aparecem aqui"
          detalhe="Guardado só no navegador de cada pessoa. Na primeira visita, o bloco não aparece."
        />
      </Bloco>
    ) : null;
  }
  return (
    <Bloco margem={ajuste.margem}>
      <BoutiqueSecaoDeProdutos
        eyebrow={eyebrowDaVitrine("historico")}
        titulo={String(secao.title || "").trim() || "Vistos recentemente"}
        produtos={lista}
        slug={ctx.slug}
        clienteId={ctx.clienteId}
        favoritos={ctx.favoritos}
        corDaMarca={ctx.corDaMarca}
        limite={ajuste.quantidade}
      />
    </Bloco>
  );
}

/* ---------------------------------------------------- texto com marcação */

function Pedacos({ pedacos }: { pedacos: PedacoDoTexto[] }) {
  return (
    <>
      {pedacos.map((p, i) => {
        if (p.tipo === "negrito") return <strong key={i} className="font-semibold text-[#111111]">{p.valor}</strong>;
        if (p.tipo === "link") {
          return p.externo ? (
            <a key={i} href={p.href} target="_blank" rel="noopener noreferrer" className="font-semibold text-[#111111] underline underline-offset-4">
              {p.valor}
            </a>
          ) : (
            <Link key={i} href={p.href} className="font-semibold text-[#111111] underline underline-offset-4">
              {p.valor}
            </Link>
          );
        }
        return <span key={i}>{p.valor}</span>;
      })}
    </>
  );
}

function Texto({ blocos, className = "" }: { blocos: BlocoDoTexto[]; className?: string }) {
  return (
    <div className={`space-y-3 text-[13px] leading-[1.75] text-[#6d6a66] md:text-[14px] ${className}`}>
      {blocos.map((bloco, i) =>
        bloco.tipo === "lista" ? (
          <ul key={i} className="space-y-1.5">
            {bloco.itens.map((item, j) => (
              <li key={j} className="flex gap-2.5">
                <Check className="mt-1 h-3.5 w-3.5 shrink-0 text-[#111111]" strokeWidth={2.2} />
                <span>
                  <Pedacos pedacos={item} />
                </span>
              </li>
            ))}
          </ul>
        ) : (
          <p key={i}>
            {bloco.linhas.map((l, j) => (
              <span key={j}>
                {j > 0 ? <br /> : null}
                <Pedacos pedacos={l} />
              </span>
            ))}
          </p>
        )
      )}
    </div>
  );
}

/* ------------------------------------------------------------- vídeo */

function PlayerBoutique({ secao, className = "" }: { secao: Secao; className?: string }) {
  const editor = useNoEditor();
  const video = lerVideo(configDaSecao(secao.config));
  const [tocando, setTocando] = useState(false);
  if (!video.link) return null;
  const capa = video.capa || capaDoVideo(video.link);
  const titulo = String(secao.title || "Vídeo");
  return (
    <div className={`relative aspect-video w-full overflow-hidden bg-black ${className}`}>
      {tocando && !editor ? (
        <iframe
          src={enderecoDoPlayer(video.link)}
          title={titulo}
          className="absolute inset-0 h-full w-full"
          allow="autoplay; encrypted-media; picture-in-picture; fullscreen"
          allowFullScreen
          loading="lazy"
          referrerPolicy="strict-origin-when-cross-origin"
        />
      ) : (
        <button type="button" onClick={() => setTocando(true)} aria-label={`Assistir: ${titulo}`} className="group absolute inset-0 h-full w-full">
          {capa ? (
            /* eslint-disable-next-line @next/next/no-img-element */
            <img src={capa} alt="" loading="lazy" className="bq-zoom-lento absolute inset-0 h-full w-full object-cover" />
          ) : (
            <span className="absolute inset-0 bg-[#111111]" />
          )}
          <span className="absolute inset-0 bg-black/15" />
          <span className="bq-video-play absolute left-1/2 top-1/2 flex h-[76px] w-[76px] -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full">
            <Play className="ml-1 h-7 w-7 text-white" fill="currentColor" strokeWidth={0} />
          </span>
        </button>
      )}
    </div>
  );
}

function BoutiqueVideo({ secao }: Props) {
  const editor = useNoEditor();
  const video = lerVideo(configDaSecao(secao.config));
  if (!video.link) {
    return editor ? (
      <Bloco margem={video.margem} className="px-4">
        <BoutiqueVazio
          icone={<Play className="h-5 w-5" />}
          texto={video.url ? "Esse link não é de um vídeo do YouTube ou do Vimeo" : "Vídeo: cole o link do YouTube ou do Vimeo no painel"}
        />
      </Bloco>
    ) : null;
  }
  const blocos = lerTextoSimples(video.texto);
  if (video.lado === "inteiro" || (!blocos.length && !secao.title)) {
    return (
      <Bloco margem={video.margem} className="py-10 md:py-14">
        <div className={CONTEUDO}>
          <BoutiqueTituloEditorial eyebrow="Assista" titulo={secao.title} centro className="mb-8 md:mb-10" />
          <PlayerBoutique secao={secao} />
          {blocos.length ? <Texto blocos={blocos} className="mx-auto mt-6 max-w-2xl text-center" /> : null}
        </div>
      </Bloco>
    );
  }
  return (
    <Bloco margem={video.margem}>
      <div className="grid w-full md:grid-cols-2">
        <div className={`flex items-center bg-black ${video.lado === "direita" ? "md:order-2" : ""}`}>
          <PlayerBoutique secao={secao} />
        </div>
        <div className="flex flex-col justify-center bg-[var(--bq-papel)] px-6 py-12 md:px-[72px] md:py-[64px]">
          <BoutiqueTituloEditorial eyebrow="Assista" titulo={secao.title} />
          {blocos.length ? <Texto blocos={blocos} className="mt-5 max-w-[520px]" /> : null}
        </div>
      </div>
    </Bloco>
  );
}

/* ------------------------------------------------- texto com imagem */

function BoutiqueTextoComImagem({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const bloco = lerTextoComImagem(configDaSecao(secao.config));
  const blocos = lerTextoSimples(bloco.texto);
  if (!bloco.imagem && !blocos.length && !editor) return null;
  const destino = bloco.botao.texto && bloco.botao.link ? destinoDaSecao(lerLink(bloco.botao.link), ctx.slug, ctx.categorias) : null;
  const alvo = destino?.novaAba ? { target: "_blank", rel: "noopener noreferrer" } : {};
  const conteudoDoBotao = (
    <>
      {bloco.botao.texto} <span className="bq-seta-texto" aria-hidden="true">→</span>
    </>
  );
  return (
    <Bloco margem={bloco.margem}>
      <div className="grid w-full md:grid-cols-2">
        <div
          className={`group relative w-full overflow-hidden bg-[#e8e3dd] ${bloco.lado === "direita" ? "md:order-2" : ""}`}
          style={{ aspectRatio: String(PROPORCOES_DO_WIDGET[bloco.proporcao]) }}
        >
          {bloco.imagem ? (
            /* eslint-disable-next-line @next/next/no-img-element */
            <img src={bloco.imagem} alt={secao.title || ""} loading="lazy" className="bq-zoom-lento absolute inset-0 h-full w-full object-cover" />
          ) : (
            <span className="absolute inset-0 flex items-center justify-center p-6">
              <BoutiqueVazio texto="Escolha a imagem no painel" className="w-full" />
            </span>
          )}
        </div>
        <div className="flex flex-col justify-center bg-[var(--bq-papel)] px-6 py-12 md:px-[72px] md:py-[64px]">
          <BoutiqueTituloEditorial eyebrow={bloco.chamada || null} titulo={secao.title} />
          {blocos.length ? (
            <Texto blocos={blocos} className="mt-5 max-w-[520px]" />
          ) : editor ? (
            <p className="mt-5 text-[11px] font-semibold uppercase tracking-[0.14em] text-[#6d6a66]">Escreva o texto no painel.</p>
          ) : null}
          {destino ? (
            destino.externo ? (
              <a href={destino.href} className={classeDoBotao("mt-8 self-start")} {...alvo}>
                {conteudoDoBotao}
              </a>
            ) : (
              <Link href={destino.href} className={classeDoBotao("mt-8 self-start")} {...alvo}>
                {conteudoDoBotao}
              </Link>
            )
          ) : null}
        </div>
      </div>
    </Bloco>
  );
}

/* --------------------------------------------------- perguntas frequentes */

/* O título dos blocos do produto da referência ("Descrição do produto"):
   18/700 centralizado com o risco preto de 30 × 2 embaixo. */
function TituloComRisco({ texto }: { texto?: string | null }) {
  const titulo = String(texto || "").trim();
  if (!titulo) return null;
  return (
    <div className="mb-8 flex flex-col items-center gap-3">
      <h2 className="text-center text-[18px] font-bold text-black" style={{ fontFamily: "var(--bq-fonte-texto)" }}>
        {titulo}
      </h2>
      <span aria-hidden className="h-[2px] w-[30px] bg-black" />
    </div>
  );
}

function BoutiquePerguntas({ secao }: Props) {
  const editor = useNoEditor();
  const ajuste = lerPerguntas(configDaSecao(secao.config));
  const [aberta, setAberta] = useState<number | null>(ajuste.abrirPrimeira ? 0 : null);
  if (!ajuste.itens.length) {
    return editor ? (
      <Bloco margem={ajuste.margem} className="px-4">
        <BoutiqueVazio texto="Perguntas frequentes: escreva as perguntas e respostas no painel" />
      </Bloco>
    ) : null;
  }
  return (
    <Bloco margem={ajuste.margem} className="py-10 md:py-14">
      <div className="mx-auto w-full max-w-[900px] px-4">
        <TituloComRisco texto={secao.title} />
        <div className="border-t" style={{ borderColor: "#dedede" }}>
          {ajuste.itens.map((item, indice) => {
            const aberto = aberta === indice;
            const id = `bq-faq-${secao.id}-${indice}`;
            return (
              <div key={indice} className="border-b" style={{ borderColor: "#dedede" }}>
                {/* A pergunta vai na fonte do texto, como o acordeão da descrição do
                    produto da referência (a fonte de títulos da loja pesaria aqui). */}
                <h3 style={{ fontFamily: "var(--bq-fonte-texto)" }}>
                  <button
                    type="button"
                    id={`${id}-botao`}
                    aria-expanded={aberto}
                    aria-controls={`${id}-resposta`}
                    onClick={() => setAberta(aberto ? null : indice)}
                    className="bq-acordeao flex w-full items-center justify-between gap-4 px-2 py-[18px] text-left text-[14px] font-semibold leading-[1.3] text-[#202020]"
                  >
                    <span>{item.pergunta}</span>
                    <span aria-hidden className="bq-acordeao-seta" {...(aberto ? { "data-aberto": "" } : {})} />
                  </button>
                </h3>
                <div id={`${id}-resposta`} role="region" aria-labelledby={`${id}-botao`} hidden={!aberto} className="px-2 pb-5">
                  <Texto blocos={lerTextoSimples(item.resposta)} className="!text-[13px] !text-[#555555]" />
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </Bloco>
  );
}

/* --------------------------------------------------------- onde estamos */

function BoutiqueOndeEstamos({ secao }: Props) {
  const editor = useNoEditor();
  const dados = useDadosDosWidgets();
  const ajuste = lerOndeEstamos(configDaSecao(secao.config));
  const endereco = ajuste.usarDaLoja ? dados?.local.endereco ?? null : enderecoDigitado(ajuste.endereco);
  if (!endereco) {
    return editor ? (
      <Bloco margem={ajuste.margem} className="px-4">
        <BoutiqueVazio icone={<MapPin className="h-5 w-5" />} texto={ajuste.usarDaLoja ? "A empresa ainda não tem endereço cadastrado" : "Escreva o endereço no painel"} />
      </Bloco>
    ) : null;
  }
  const horarios = ajuste.horarios.split("\n").map((l) => l.trim()).filter(Boolean);
  const retiradas = ajuste.mostrarRetiradas ? dados?.local.retiradas ?? [] : [];
  const telefone = dados?.local.telefone ?? null;
  return (
    <Bloco margem={ajuste.margem}>
      <div className={`grid w-full ${ajuste.mostrarMapa ? "md:grid-cols-[0.95fr_1.05fr]" : ""}`}>
        <div className="flex flex-col justify-center bg-[var(--bq-papel)] px-6 py-12 md:px-[72px] md:py-[64px]">
          <BoutiqueTituloEditorial eyebrow="Visite a loja" titulo={secao.title || "Onde estamos"} />
          <div className="mt-7 space-y-5 text-[13px] leading-[1.75] text-[#252525] md:text-[14px]">
            <div className="flex gap-3">
              <MapPin className="mt-1 h-4 w-4 shrink-0 text-[#111111]" strokeWidth={1.5} />
              <address className="not-italic">
                {endereco.linhas.map((l) => (
                  <span key={l} className="block">
                    {l}
                  </span>
                ))}
              </address>
            </div>
            {horarios.length ? (
              <div className="flex gap-3">
                <Clock className="mt-1 h-4 w-4 shrink-0 text-[#111111]" strokeWidth={1.5} />
                <ul>
                  {horarios.map((h) => (
                    <li key={h}>{h}</li>
                  ))}
                </ul>
              </div>
            ) : null}
            {telefone ? (
              <div className="flex items-center gap-3">
                <Phone className="h-4 w-4 shrink-0 text-[#111111]" strokeWidth={1.5} /> {telefone}
              </div>
            ) : null}
          </div>
          <a href={enderecoDaRota(endereco.busca)} target="_blank" rel="noopener noreferrer" className={classeDoBotao("mt-8 self-start")}>
            Traçar rota <span className="bq-seta-texto" aria-hidden="true">→</span>
          </a>
          {retiradas.length ? (
            <div className="mt-8 border-t pt-5" style={{ borderColor: "rgba(17,17,17,0.12)" }}>
              <p className="text-[9px] font-bold uppercase tracking-[0.18em] text-[#111111]">Pontos de retirada</p>
              <ul className="mt-3 space-y-3">
                {retiradas.map((r) => (
                  <li key={r.nome + r.endereco.busca} className="text-[12px] leading-relaxed">
                    <span className="font-semibold uppercase tracking-[0.06em] text-[#111111]">{r.nome}</span>
                    <span className="block text-[#6d6a66]">{r.endereco.linhas.slice(0, 2).join(" · ")}</span>
                  </li>
                ))}
              </ul>
            </div>
          ) : null}
        </div>
        {ajuste.mostrarMapa ? (
          <div className="relative min-h-[300px] bg-[#e8e3dd] md:min-h-[440px]">
            {editor ? (
              <span className="absolute inset-0 flex flex-col items-center justify-center gap-2 text-[10px] font-bold uppercase tracking-[0.14em] text-[#6d6a66]">
                <MapPin className="h-7 w-7 text-[#111111]" strokeWidth={1.3} /> O mapa do Google aparece aqui na loja publicada
              </span>
            ) : (
              <iframe
                src={enderecoDoMapa(endereco.busca)}
                title={`Mapa: ${endereco.linhas[0] || "endereço da loja"}`}
                className="bq-mapa absolute inset-0 h-full w-full border-0"
                loading="lazy"
                referrerPolicy="no-referrer-when-downgrade"
              />
            )}
          </div>
        ) : null}
      </div>
    </Bloco>
  );
}

/* --------------------------------------------- faixa de texto que desliza */

function BoutiqueFaixa({ secao }: Props) {
  const editor = useNoEditor();
  const reduzido = useMovimentoReduzido();
  /* Sem cor escolhida, a faixa é a da referência: quase preta (#121212). */
  const faixa = lerFaixa(configDaSecao(secao.config), "#121212");
  if (!faixa.itens.length) {
    return editor ? (
      <div className="px-4 py-3">
        <BoutiqueVazio texto="Faixa que desliza: escreva as frases no painel" />
      </div>
    ) : null;
  }
  const grande = faixa.tamanho === "g";
  const tamanho = grande
    ? "bq-revista text-[24px] md:text-[34px] py-4 md:py-5 tracking-[-0.02em]"
    : faixa.tamanho === "p"
      ? "text-[10px] py-2 font-medium uppercase tracking-[0.2em]"
      : "text-[11px] md:text-[13px] py-3 md:py-[14px] font-medium uppercase tracking-[0.2em]";
  const grupo = (copia: boolean) => (
    <span className="flex shrink-0 items-center" aria-hidden={copia || undefined}>
      {faixa.itens.map((item, i) => (
        <span key={`${copia ? "c" : "o"}-${i}`} className="flex items-center whitespace-nowrap">
          <span className="px-6 md:px-9">{item}</span>
          <span aria-hidden className={grande ? "text-[0.5em] opacity-60" : "text-[0.8em] opacity-60"}>
            ✦
          </span>
        </span>
      ))}
    </span>
  );
  return (
    <div className="w-full" style={{ backgroundColor: faixa.fundo, color: faixa.cor }}>
      {reduzido ? (
        <div className={`flex flex-wrap items-center justify-center px-4 text-center ${tamanho}`}>{grupo(false)}</div>
      ) : (
        <div className={`bq-faixa-desliza flex overflow-hidden ${tamanho}`} role="marquee" aria-label={faixa.itens.join(" • ")}>
          <div className="bq-faixa-desliza-trilho flex" style={{ animationDuration: `${SEGUNDOS_DA_FAIXA[faixa.velocidade]}s` }}>
            {grupo(false)}
            {grupo(true)}
          </div>
        </div>
      )}
    </div>
  );
}

/* -------------------------------------------- imagem com pontos clicáveis */

function BoutiquePontos({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const visao = useVisaoDaLoja();
  const ajuste = lerImagemComPontos(configDaSecao(secao.config));
  const [aberto, setAberto] = useState<number | null>(null);
  const porId = useMemo(() => new Map(ctx.produtos.map((p) => [String(p.id), p])), [ctx.produtos]);
  const pontos = ajuste.pontos.map((p) => ({ ...p, produto: porId.get(p.produtoId) })).filter((p) => p.produto);
  if (!ajuste.imagem) {
    return editor ? (
      <Bloco margem={ajuste.margem} className="px-4">
        <BoutiqueVazio texto="Imagem com pontos: escolha a imagem e toque nela no painel para marcar os produtos" />
      </Bloco>
    ) : null;
  }
  return (
    <Bloco margem={ajuste.margem} className="py-10 md:py-14">
      <div className={CONTEUDO}>
        <BoutiqueTituloEditorial eyebrow="Toque nas peças" titulo={secao.title} centro className="mb-8 md:mb-10" />
        <div className="relative w-full" style={{ aspectRatio: String(PROPORCOES_DOS_PONTOS[ajuste.proporcao]) }} onMouseLeave={() => setAberto(null)}>
          <div className="absolute inset-0 overflow-hidden bg-[#e8e3dd]">
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img src={ajuste.imagem} alt={secao.title || ""} loading="lazy" className="h-full w-full object-cover" />
          </div>
          {pontos.map((ponto, indice) => {
            const produto = ponto.produto as BoutiqueProduto;
            const ativo = aberto === indice;
            const preco = visao.mostrarPreco ? precoDoCartao(produto as never, visao.textoNoLugarDoPreco).texto : visao.textoNoLugarDoPreco;
            const foto = fotoDoProdutoDoWidget(produto as never);
            return (
              <div key={indice} className="absolute" style={{ left: `${ponto.x}%`, top: `${ponto.y}%`, zIndex: ativo ? 30 : 10 }} onMouseEnter={() => setAberto(indice)}>
                <button
                  type="button"
                  aria-label={`Ver ${produto.name}`}
                  aria-expanded={ativo}
                  onClick={() => setAberto(ativo ? null : indice)}
                  onFocus={() => setAberto(indice)}
                  className="bq-ponto-da-foto -ml-[14px] -mt-[14px] flex h-7 w-7 items-center justify-center rounded-full"
                  {...(ativo ? { "data-ativo": "" } : {})}
                >
                  <span className="h-2.5 w-2.5 rounded-full bg-[#111111]" />
                </button>
                {ativo ? (
                  <Link
                    href={`/${ctx.slug}/p/${encodeURIComponent(produto.id)}`}
                    className={`bq-cartao-da-foto absolute flex w-60 items-center gap-3 p-2.5 ${ponto.x > 60 ? "right-5" : "left-5"} ${ponto.y > 55 ? "bottom-1" : "top-1"}`}
                  >
                    {foto ? (
                      /* eslint-disable-next-line @next/next/no-img-element */
                      <img src={foto} alt="" className="h-[70px] w-14 shrink-0 bg-[#fafafa] object-contain" />
                    ) : null}
                    <span className="min-w-0">
                      <span className="line-clamp-2 text-[10.5px] font-medium uppercase leading-snug tracking-[0.04em] text-[#202020]">{produto.name}</span>
                      {preco ? <span className="mt-1 block text-[15px] font-semibold text-[#111111]">{preco}</span> : null}
                      <span className="mt-1.5 inline-flex items-center gap-1.5 border-b border-[#111111] pb-0.5 text-[8.5px] font-bold uppercase tracking-[0.12em] text-[#111111]">
                        Ver produto <ArrowRight className="h-3 w-3" />
                      </span>
                    </span>
                  </Link>
                ) : null}
              </div>
            );
          })}
        </div>
      </div>
    </Bloco>
  );
}

/* ---------------------------------------------------------- antes e depois */

function BoutiqueAntesEDepois({ secao }: Props) {
  const editor = useNoEditor();
  const ajuste = lerAntesEDepois(configDaSecao(secao.config));
  const { posicao, caixa, eventosDaCaixa, eventosDaAlca } = useBarraDeComparacao(ajuste.inicio);
  if (!ajuste.antes || !ajuste.depois) {
    return editor ? (
      <Bloco margem={ajuste.margem} className="px-4">
        <BoutiqueVazio texto="Antes e depois: escolha as duas imagens no painel" />
      </Bloco>
    ) : null;
  }
  return (
    <Bloco margem={ajuste.margem} className="py-10 md:py-14">
      <div className={CONTEUDO}>
        <BoutiqueTituloEditorial eyebrow="Arraste para comparar" titulo={secao.title} centro className="mb-8 md:mb-10" />
        <div
          ref={caixa}
          {...eventosDaCaixa}
          className="relative w-full touch-pan-y select-none overflow-hidden bg-[#e8e3dd]"
          style={{ aspectRatio: String(PROPORCOES_DOS_PONTOS[ajuste.proporcao]), cursor: "ew-resize" }}
        >
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img src={ajuste.antes} alt={ajuste.rotuloAntes} draggable={false} className="pointer-events-none absolute inset-0 h-full w-full object-cover" />
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img
            src={ajuste.depois}
            alt={ajuste.rotuloDepois}
            draggable={false}
            className="pointer-events-none absolute inset-0 h-full w-full object-cover"
            style={{ clipPath: `inset(0 0 0 ${posicao}%)` }}
          />
          <span className="pointer-events-none absolute bottom-4 left-4 bg-white/90 px-3 py-1.5 text-[9px] font-bold uppercase tracking-[0.16em] text-[#111111]">{ajuste.rotuloAntes}</span>
          <span className="pointer-events-none absolute bottom-4 right-4 bg-[#111111] px-3 py-1.5 text-[9px] font-bold uppercase tracking-[0.16em] text-white">{ajuste.rotuloDepois}</span>
          <span className="pointer-events-none absolute inset-y-0 w-px -translate-x-1/2 bg-white" style={{ left: `${posicao}%` }} />
          <span
            role="slider"
            tabIndex={0}
            aria-label={`Comparar ${ajuste.rotuloAntes} e ${ajuste.rotuloDepois}`}
            aria-valuemin={0}
            aria-valuemax={100}
            aria-valuenow={Math.round(posicao)}
            aria-valuetext={`${Math.round(posicao)}% ${ajuste.rotuloAntes.toLowerCase()}`}
            {...eventosDaAlca}
            className="absolute top-1/2 flex h-11 w-11 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-white text-[#111111] shadow-[0_4px_15px_rgba(0,0,0,0.18)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#111111]"
            style={{ left: `${posicao}%` }}
          >
            <ChevronLeft aria-hidden className="-mr-1 h-4 w-4" strokeWidth={2} />
            <ChevronRight aria-hidden className="-ml-1 h-4 w-4" strokeWidth={2} />
          </span>
        </div>
      </div>
    </Bloco>
  );
}

/* ------------------------------------------------------------- o bloco */

export function BoutiqueWidgetDaHome(props: Props) {
  switch (modoDaSecao(props.secao)) {
    case "flash_offer":
      return <BoutiqueOferta {...props} />;
    case "coupon_highlight":
      return <BoutiqueCupom {...props} />;
    case "order_cutoff":
      return <BoutiqueCorte {...props} />;
    case "next_live":
      return <BoutiqueLive {...props} />;
    case "auto_list":
      return <BoutiqueLista {...props} />;
    case "combo_highlight":
      return <BoutiqueKits {...props} />;
    case "recently_viewed":
      return <BoutiqueVistos {...props} />;
    case "video_section":
      return <BoutiqueVideo {...props} />;
    case "text_image":
      return <BoutiqueTextoComImagem {...props} />;
    case "faq":
      return <BoutiquePerguntas {...props} />;
    case "store_location":
      return <BoutiqueOndeEstamos {...props} />;
    case "marquee":
      return <BoutiqueFaixa {...props} />;
    case "shoppable_image":
      return <BoutiquePontos {...props} />;
    case "before_after":
      return <BoutiqueAntesEDepois {...props} />;
    default:
      return null;
  }
}
