"use client";

import Link from "next/link";
import { useMemo, useState, type CSSProperties, type ReactNode } from "react";
import {
  ArrowRight,
  CalendarClock,
  Check,
  Clock,
  Copy,
  ImagePlus,
  MapPin,
  Minus,
  Navigation,
  Phone,
  Play,
  Plus,
  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,
  horaEmBrasilia,
  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 { VendorCardDoProduto, type VendorProduto } from "./VendorCardDoProduto";
import { VendorSecaoDeProdutos } from "./VendorBlocosDaHome";
import type { VendorCategoria } from "./VendorShell";

/*
  Os blocos novos da página inicial no Vendor (os temas Padrão e Vitrine têm
  os deles em components/home/WidgetsDaHome.tsx). A linguagem é a do Vendor:
  coluna de 6xl, título entre duas linhas, cantos e cores pelas variáveis
  --vd-*, a cor da loja (--vd-primary) nos pontos de ação. Só os dados e as
  regras (lib/widgets-da-home, ganchos-dos-widgets) são divididos.
*/

type Ctx = {
  slug: string;
  produtos: VendorProduto[];
  categorias: VendorCategoria[];
  clienteId?: string | null;
  favoritos?: string[] | null;
  corDaMarca?: string;
};

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 PRIMARIA = "var(--vd-primary)";
const SOBRE_A_PRIMARIA = "var(--vd-primary-fg, #ffffff)";
const R2XL = "var(--vd-radius-2xl)";
const RXL = "var(--vd-radius-xl)";
const RLG = "var(--vd-radius-lg)";

function forte(quanto: number) {
  return `color-mix(in srgb, var(--vd-primary) ${100 - quanto}%, #000000)`;
}

function Coluna({ margem, children, className = "" }: { margem: EspacoDoWidget; children: ReactNode; className?: string }) {
  return <section className={`mx-auto w-full max-w-6xl px-4 ${MARGEM[margem]} ${className}`}>{children}</section>;
}

function TituloVendor({ texto }: { texto?: string | null }) {
  const titulo = String(texto || "").trim();
  if (!titulo) return null;
  return (
    <div className="mb-6 flex items-center justify-center gap-4">
      <span className="h-px max-w-[120px] flex-1" style={{ backgroundColor: "var(--vd-border)" }} />
      <h2 className="text-center text-base font-bold sm:text-xl">{titulo}</h2>
      <span className="h-px max-w-[120px] flex-1" style={{ backgroundColor: "var(--vd-border)" }} />
    </div>
  );
}

function Vazio({ texto, detalhe, icone, style }: { texto: string; detalhe?: string; icone?: ReactNode; style?: CSSProperties }) {
  return (
    <div
      className="flex min-h-[140px] flex-col items-center justify-center gap-2 border-2 border-dashed px-6 py-7 text-center text-[var(--vd-muted-fg)]"
      style={{ borderRadius: R2XL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-muted-bg)", ...style }}
    >
      {icone ?? <ImagePlus className="h-6 w-6" />}
      <span className="text-xs font-bold">{texto}</span>
      {detalhe ? <span className="max-w-md text-[11px]">{detalhe}</span> : null}
    </div>
  );
}

function Trilho({ children }: { children: ReactNode }) {
  return (
    <div className="-mx-4 flex snap-x snap-mandatory scroll-px-4 gap-3 overflow-x-auto px-4 pb-2 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden sm:mx-0 sm:grid sm:grid-cols-2 sm:gap-x-4 sm:gap-y-6 sm:overflow-visible sm:px-0 sm:pb-0 lg:grid-cols-4">
      {children}
    </div>
  );
}

function Card({ produto, ctx }: { produto: VendorProduto; ctx: Ctx }) {
  return (
    <div className="w-[46%] shrink-0 snap-start sm:w-auto sm:shrink">
      <VendorCardDoProduto produto={produto} slug={ctx.slug} clienteId={ctx.clienteId} favoritos={ctx.favoritos} corDaMarca={ctx.corDaMarca} />
    </div>
  );
}

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

function Quadradinho({ valor, rotulo }: { valor: number; rotulo: string }) {
  return (
    <span className="flex flex-col items-center gap-0.5">
      <span
        className="flex h-10 min-w-[2.6rem] items-center justify-center px-1.5 text-lg font-bold tabular-nums sm:h-11 sm:text-xl"
        style={{ borderRadius: RLG, backgroundColor: "var(--vd-foreground, #111827)", color: "#ffffff" }}
        suppressHydrationWarning
      >
        {String(valor).padStart(2, "0")}
      </span>
      <span className="text-[9px] font-semibold uppercase tracking-wider text-[var(--vd-muted-fg)]">{rotulo}</span>
    </span>
  );
}

function VendorOferta({ 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 (
      <Coluna margem={oferta.margem}>
        <Vazio texto="Oferta relâmpago: escolha os produtos e a hora do fim no painel" icone={<Zap className="h-6 w-6" />} />
      </Coluna>
    );
  }
  const falta = oferta.terminaEm ? oferta.terminaEm - agora : 0;
  const partes = partesDaContagem(falta);
  return (
    <Coluna margem={oferta.margem}>
      <div className="overflow-hidden border" style={{ borderRadius: R2XL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}>
        <div className="flex flex-col gap-3 px-4 py-4 sm:flex-row sm:items-center sm:justify-between sm:px-6" style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>
          <div className="flex items-center gap-3">
            <span className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-white/20">
              <Zap className="h-5 w-5" strokeWidth={2.6} />
            </span>
            <div className="min-w-0">
              <p className="text-[11px] font-bold uppercase tracking-[0.16em] opacity-85">{oferta.selo}</p>
              <h2 className="text-lg font-bold leading-tight sm:text-xl">{secao.title || "Oferta relâmpago"}</h2>
              {oferta.subtitulo ? <p className="text-xs opacity-85">{oferta.subtitulo}</p> : null}
            </div>
          </div>
          {noAr ? (
            <div className="flex items-center gap-3 self-start rounded-xl bg-white px-3 py-2 text-[var(--vd-foreground,#111827)] sm:self-auto" role="timer" aria-label={`Termina em ${relogioDaContagem(falta)}`}>
              <span className="text-[11px] font-bold uppercase leading-tight tracking-wider text-[var(--vd-muted-fg)]">
                Termina
                <br />
                em
              </span>
              <span className="flex items-start gap-1.5" aria-hidden>
                {partes.dias > 0 ? <Quadradinho valor={partes.dias} rotulo="dias" /> : null}
                <Quadradinho valor={partes.horas} rotulo="h" />
                <Quadradinho valor={partes.minutos} rotulo="min" />
                <Quadradinho valor={partes.segundos} rotulo="s" />
              </span>
            </div>
          ) : (
            <p className="rounded-lg bg-black/25 px-3 py-2 text-xs font-semibold">
              {oferta.terminaEm ? "Esta oferta já terminou: na loja ela não aparece mais." : "Escolha no painel quando a oferta termina."}
            </p>
          )}
        </div>
        <div className="p-4 sm:p-6">
          <Trilho>
            {lista.map((produto) => (
              <Card key={produto.id} produto={produto} ctx={ctx} />
            ))}
          </Trilho>
        </div>
      </div>
    </Coluna>
  );
}

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

function VendorCupom({ 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 (
      <Coluna margem={ajuste.margem}>
        <Vazio icone={<Ticket className="h-6 w-6" />} 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"} />
      </Coluna>
    );
  }
  const condicoes = condicoesDoCupom(cupom, ajuste.mostrarValidade);
  return (
    <Coluna margem={ajuste.margem}>
      <div className="relative flex flex-col overflow-hidden border-2 border-dashed sm:flex-row sm:items-stretch" style={{ borderRadius: R2XL, borderColor: PRIMARIA, backgroundColor: "var(--vd-surface)" }}>
        <div className="flex items-center gap-3 px-5 py-4 sm:w-[34%] sm:flex-col sm:items-start sm:justify-center sm:px-7" style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>
          <Ticket className="h-7 w-7 shrink-0" />
          <div>
            <p className="text-[11px] font-semibold uppercase tracking-[0.16em] opacity-85">{secao.title || "Cupom"}</p>
            <p className="text-3xl font-bold leading-none tracking-tight">{descontoDoCupom(cupom)}</p>
          </div>
        </div>
        <div className="flex flex-1 flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between sm:px-7">
          <div className="min-w-0">
            {ajuste.chamada ? <p className="text-[15px] font-bold leading-snug">{ajuste.chamada}</p> : null}
            <ul className="mt-0.5 space-y-0.5 text-xs text-[var(--vd-muted-fg)]">
              {condicoes.map((c) => (
                <li key={c} className="flex items-center gap-1.5" suppressHydrationWarning>
                  <Check className="h-3 w-3 shrink-0" style={{ color: PRIMARIA }} strokeWidth={3} /> {c}
                </li>
              ))}
            </ul>
          </div>
          <div className="flex shrink-0 items-stretch gap-2">
            {cupomAutomatico(cupom) ? (
            <span className="inline-flex h-10 items-center gap-1.5 px-4 text-[13px] font-semibold" style={{ borderRadius: RLG, backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>
              <Check className="h-4 w-4" strokeWidth={3} /> Desconto automático no carrinho
            </span>
            ) : (
            <>
            <span className="flex h-10 flex-1 items-center justify-center border px-4 font-mono text-base font-bold tracking-[0.14em] select-all sm:flex-none" style={{ borderRadius: RLG, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-muted-bg)" }} aria-label={`Código do cupom: ${cupom.code}`}>
              {cupom.code}
            </span>
            <button
              type="button"
              onClick={() => copiar(cupom.code)}
              className="inline-flex h-10 items-center gap-1.5 px-4 text-[13px] font-semibold transition hover:brightness-110 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
              style={{ borderRadius: RLG, backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA, outlineColor: PRIMARIA }}
            >
              {estado === "copiado" ? <Check className="h-4 w-4" strokeWidth={3} /> : <Copy className="h-4 w-4" />}
              {estado === "copiado" ? "Copiado!" : estado === "falhou" ? "Selecione" : "Copiar cupom"}
            </button>
            <span className="sr-only" aria-live="polite">
              {estado === "copiado" ? "Cupom copiado." : estado === "falhou" ? "Não deu para copiar: selecione o código e copie." : ""}
            </span>
            </>
            )}
          </div>
        </div>
      </div>
    </Coluna>
  );
}

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

function VendorCorte({ 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 (
      <Coluna margem={ajuste.margem}>
        <Vazio icone={<Timer className="h-6 w-6" />} texto="Ligue o corte de produção para este aviso aparecer" detalhe="Catálogo > Personalização > Corte de produção." />
      </Coluna>
    );
  }
  return (
    <Coluna margem={ajuste.margem}>
      <div className="flex items-stretch overflow-hidden border" style={{ borderRadius: RXL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}>
        <div className="flex shrink-0 items-center px-4" style={{ color: PRIMARIA }}>
          <Timer className="h-6 w-6" />
        </div>
        <div className="min-w-0 flex-1 py-3 pr-3">
          <p className="text-[11px] text-[var(--vd-muted-fg)]">{conta.hoje ? "Seu pedido entra em" : "Produção do dia encerrada"}</p>
          <p className="text-sm font-bold uppercase leading-tight tracking-tight sm:text-base">
            {conta.hoje ? ajuste.frase || "Produção hoje, se finalizado até" : `Pedidos de agora: lote ${conta.amanha ? "de amanhã" : `de ${conta.proximoDia}`}`}
          </p>
          <p className="text-[11px] text-[var(--vd-muted-fg)]">{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 shrink-0 flex-col items-center justify-center px-4" style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }} role={conta.hoje ? "timer" : undefined}>
          <span className="text-lg font-bold leading-none tabular-nums">{conta.hora}</span>
          {conta.hoje ? (
            <span className="mt-1 text-[10px] font-semibold tabular-nums opacity-90" suppressHydrationWarning>
              faltam {relogioDaContagem(conta.faltaMs)}
            </span>
          ) : null}
        </div>
      </div>
    </Coluna>
  );
}

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

function VendorLive({ 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 ? (
        <Coluna margem={ajuste.margem}>
          <Vazio icone={<Radio className="h-6 w-6" />} texto="Nenhuma live de venda marcada na vitrine" detalhe="Na loja o bloco fica escondido até haver uma." />
        </Coluna>
      ) : null;
    }
    return (
      <Coluna margem={ajuste.margem}>
        <div className="flex items-center gap-3 border px-5 py-4" style={{ borderRadius: R2XL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}>
          <Radio className="h-6 w-6 shrink-0" style={{ color: PRIMARIA }} />
          <div>
            {secao.title ? <p className="text-sm font-bold">{secao.title}</p> : null}
            <p className="text-xs text-[var(--vd-muted-fg)]">{ajuste.semLive}</p>
          </div>
        </div>
      </Coluna>
    );
  }
  const { live, momento } = vez;
  const noAr = momento === "ao_vivo";
  const aberta = momento === "espera";
  const comeca = new Date(live.comeca_em).getTime();
  return (
    <Coluna margem={ajuste.margem}>
      <Link
        href={`/${ctx.slug}/live/${encodeURIComponent(live.id)}`}
        className="group flex flex-col overflow-hidden border sm:flex-row"
        style={{ borderRadius: R2XL, borderColor: noAr ? "#dc2626" : "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}
      >
        <div className="relative aspect-[16/9] w-full shrink-0 bg-[var(--vd-muted-bg)] sm:aspect-auto sm:w-[38%]">
          {live.capa ? (
            /* eslint-disable-next-line @next/next/no-img-element */
            <img src={live.capa} alt="" loading="lazy" className="absolute inset-0 h-full w-full object-cover" />
          ) : (
            <span className="absolute inset-0 flex items-center justify-center" style={{ background: `linear-gradient(135deg, var(--vd-primary), ${forte(45)})` }}>
              <Radio className="h-12 w-12 text-white/60" />
            </span>
          )}
          <span className={`absolute left-3 top-3 inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-[10px] font-bold uppercase tracking-wider ${noAr ? "bg-red-600 text-white" : "bg-white text-[var(--vd-foreground,#111827)]"}`}>
            {noAr ? <span className="h-1.5 w-1.5 animate-pulse rounded-full bg-white motion-reduce:animate-none" /> : <CalendarClock className="h-3 w-3" />}
            {noAr ? "Ao vivo" : aberta ? "Sala aberta" : "Agendada"}
          </span>
        </div>
        <div className="flex flex-1 flex-col justify-center gap-1.5 p-5 sm:p-6">
          {secao.title ? <p className="text-[11px] font-bold uppercase tracking-[0.16em]" style={{ color: PRIMARIA }}>{secao.title}</p> : null}
          <h3 className="text-lg font-bold leading-snug sm:text-xl">{live.titulo}</h3>
          <p className="text-xs text-[var(--vd-muted-fg)]" suppressHydrationWarning>
            {noAr ? "Acontecendo agora: entre e compre ao vivo." : quandoDaLive(comeca)}
          </p>
          {!noAr && comeca > agora ? (
            <p className="text-sm font-semibold" suppressHydrationWarning>
              Começa em <span className="tabular-nums" style={{ color: PRIMARIA }}>{relogioDaContagem(comeca - agora)}</span>
            </p>
          ) : null}
          <span
            className="mt-2 inline-flex h-10 items-center gap-1.5 self-start px-4 text-[13px] font-semibold transition group-hover:brightness-110"
            style={{ borderRadius: RLG, backgroundColor: noAr ? "#dc2626" : PRIMARIA, color: "#ffffff" }}
          >
            {noAr ? "Entrar agora" : aberta ? "Entrar na sala" : "Ver a live"} <ArrowRight className="h-4 w-4" />
          </span>
        </div>
      </Link>
    </Coluna>
  );
}

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

function VendorLista({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const dados = useDadosDosWidgets();
  const lista = lerListaAutomatica(configDaSecao(secao.config));
  const produtos =
    lista.lista === "mais_vendidos"
      ? produtosNaOrdem(dados?.maisVendidos?.[String(lista.dias) as "7" | "30" | "90"] ?? [], ctx.produtos).slice(0, lista.quantidade)
      : lancamentos(ctx.produtos as Array<VendorProduto & { created_at?: unknown }>, lista.quantidade);
  if (!produtos.length) {
    return editor ? (
      <Coluna margem={lista.margem}>
        <TituloVendor texto={secao.title} />
        <Vazio texto={lista.lista === "mais_vendidos" ? `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." />
      </Coluna>
    ) : null;
  }
  return (
    <VendorSecaoDeProdutos
      titulo={String(secao.title || "").trim() || (lista.lista === "mais_vendidos" ? "Mais vendidos" : "Lançamentos")}
      produtos={produtos}
      slug={ctx.slug}
      clienteId={ctx.clienteId}
      favoritos={ctx.favoritos}
      corDaMarca={ctx.corDaMarca}
      limite={lista.quantidade}
    />
  );
}

/* --------------------------------------------------------- kits e combos */

function VendorKits({ 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: VendorProduto; junto: VendorProduto } => Boolean(k.principal && k.junto))
    .slice(0, ajuste.quantidade);
  if (!kits.length) {
    return editor ? (
      <Coluna margem={ajuste.margem}>
        <TituloVendor texto={secao.title} />
        <Vazio icone={<Plus className="h-6 w-6" />} texto="Nenhum kit para mostrar" detalhe="Os kits saem do “Compre junto” dos produtos." />
      </Coluna>
    ) : null;
  }
  return (
    <Coluna margem={ajuste.margem}>
      <TituloVendor texto={secao.title} />
      <div className="-mx-4 flex snap-x snap-mandatory scroll-px-4 gap-3 overflow-x-auto px-4 pb-2 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden sm:mx-0 sm:grid sm:grid-cols-2 sm:gap-4 sm:overflow-visible sm:px-0 lg:grid-cols-3">
        {kits.map(({ combo, principal, junto }) => {
          const p1 = precoFixo(principal);
          const p2 = precoFixo(junto);
          const soma = p1 !== null && p2 !== null ? p1 + p2 : null;
          const total = p1 !== null && p2 !== null ? p1 + precoComDesconto(p2, combo) : null;
          const selo = dados?.semPreco ? null : seloDoCombo(combo);
          return (
            <Link
              key={combo.id}
              href={`/${ctx.slug}/p/${encodeURIComponent(principal.id)}`}
              className="group flex w-[86%] shrink-0 snap-start flex-col border p-3 transition hover:shadow-md sm:w-auto"
              style={{ borderRadius: R2XL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}
            >
              <div className="flex items-center gap-2">
                {[principal, junto].map((p, i) => {
                  const foto = fotoDoProdutoDoWidget(p);
                  return (
                    <div key={p.id} className="contents">
                      {i === 1 ? (
                        <span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full" style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>
                          <Plus className="h-4 w-4" strokeWidth={3} />
                        </span>
                      ) : null}
                      <div className="relative aspect-square flex-1 overflow-hidden bg-[var(--vd-muted-bg)]" style={{ borderRadius: RXL }}>
                        {foto ? (
                          /* eslint-disable-next-line @next/next/no-img-element */
                          <img src={foto} alt="" loading="lazy" className="absolute inset-0 h-full w-full object-cover" />
                        ) : null}
                      </div>
                    </div>
                  );
                })}
              </div>
              <div className="mt-3 flex flex-1 flex-col gap-1">
                <div className="flex items-center justify-between gap-2">
                  <p className="truncate text-[11px] font-bold uppercase tracking-wider" style={{ color: PRIMARIA }}>{combo.title || "Compre junto"}</p>
                  {selo ? <span className="shrink-0 rounded-full px-2 py-0.5 text-[10px] font-bold" style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>{selo}</span> : null}
                </div>
                <p className="line-clamp-2 text-[13px] font-medium leading-snug">
                  {principal.name} + {junto.name}
                </p>
                <div className="mt-auto flex items-end justify-between pt-2">
                  {!dados?.semPreco && visao.mostrarPreco && total !== null ? (
                    <div>
                      {soma !== null && total < soma ? <p className="text-[11px] text-[var(--vd-muted-fg)] line-through">{emReais(soma)}</p> : null}
                      <p className="text-base font-bold tabular-nums">{emReais(total)}</p>
                    </div>
                  ) : (
                    <p className="text-xs text-[var(--vd-muted-fg)]">Veja o kit</p>
                  )}
                  <span className="inline-flex h-8 items-center gap-1 px-3 text-xs font-semibold" style={{ borderRadius: RLG, backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>
                    Montar <ArrowRight className="h-3.5 w-3.5" />
                  </span>
                </div>
              </div>
            </Link>
          );
        })}
      </div>
    </Coluna>
  );
}

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

function VendorVistos({ 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 ? (
      <Coluna margem={ajuste.margem}>
        <TituloVendor texto={secao.title} />
        <Vazio icone={<Clock className="h-6 w-6" />} 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." />
      </Coluna>
    ) : null;
  }
  return (
    <VendorSecaoDeProdutos
      titulo={String(secao.title || "").trim() || "Vistos recentemente"}
      produtos={lista}
      slug={ctx.slug}
      clienteId={ctx.clienteId}
      favoritos={ctx.favoritos}
      corDaMarca={ctx.corDaMarca}
      limite={ajuste.quantidade}
    />
  );
}

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

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

function Texto({ blocos, className = "" }: { blocos: BlocoDoTexto[]; className?: string }) {
  return (
    <div className={`space-y-2.5 text-sm leading-relaxed text-[var(--vd-muted-fg)] ${className}`}>
      {blocos.map((bloco, i) =>
        bloco.tipo === "lista" ? (
          <ul key={i} className="space-y-1">
            {bloco.itens.map((item, j) => (
              <li key={j} className="flex gap-2">
                <Check className="mt-0.5 h-4 w-4 shrink-0" style={{ color: PRIMARIA }} strokeWidth={3} />
                <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 PlayerVendor({ secao }: { secao: Secao }) {
  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" style={{ borderRadius: R2XL }}>
      {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="absolute inset-0 h-full w-full object-cover" />
          ) : (
            <span className="absolute inset-0" style={{ background: `linear-gradient(135deg, var(--vd-primary), ${forte(55)})` }} />
          )}
          <span className="absolute inset-0 bg-black/20" />
          <span className="absolute left-1/2 top-1/2 flex h-14 w-14 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full shadow-xl transition group-hover:scale-110" style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>
            <Play className="ml-0.5 h-6 w-6" fill="currentColor" />
          </span>
        </button>
      )}
    </div>
  );
}

function VendorVideo({ secao }: Props) {
  const editor = useNoEditor();
  const video = lerVideo(configDaSecao(secao.config));
  if (!video.link) {
    return editor ? (
      <Coluna margem={video.margem}>
        <Vazio icone={<Play className="h-6 w-6" />} 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"} />
      </Coluna>
    ) : null;
  }
  const blocos = lerTextoSimples(video.texto);
  if (video.lado === "inteiro" || (!blocos.length && !secao.title)) {
    return (
      <Coluna margem={video.margem}>
        <TituloVendor texto={secao.title} />
        <PlayerVendor secao={secao} />
        {blocos.length ? <Texto blocos={blocos} className="mx-auto mt-4 max-w-2xl text-center" /> : null}
      </Coluna>
    );
  }
  return (
    <Coluna margem={video.margem}>
      <div className="grid items-center gap-5 sm:grid-cols-2 sm:gap-8">
        <div className={video.lado === "direita" ? "sm:order-2" : ""}>
          <PlayerVendor secao={secao} />
        </div>
        <div>
          {secao.title ? <h2 className="mb-2 text-lg font-bold sm:text-2xl">{secao.title}</h2> : null}
          <Texto blocos={blocos} />
        </div>
      </div>
    </Coluna>
  );
}

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

function VendorTextoComImagem({ 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 estiloDoBotao = { borderRadius: RLG, backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA };
  const classeDoBotao = "mt-4 inline-flex h-10 items-center gap-1.5 px-5 text-[13px] font-semibold transition hover:brightness-110";
  return (
    <Coluna margem={bloco.margem}>
      <div className="grid items-center gap-5 overflow-hidden border sm:grid-cols-2" style={{ borderRadius: R2XL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}>
        <div className={`relative w-full bg-[var(--vd-muted-bg)] ${bloco.lado === "direita" ? "sm: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="absolute inset-0 h-full w-full object-cover" />
          ) : (
            <span className="absolute inset-0 flex flex-col items-center justify-center gap-2 text-xs font-bold text-[var(--vd-muted-fg)]">
              <ImagePlus className="h-6 w-6" /> Escolha a imagem no painel
            </span>
          )}
        </div>
        <div className="px-5 pb-6 sm:px-8 sm:py-8">
          {bloco.chamada ? <p className="mb-1.5 text-[11px] font-bold uppercase tracking-[0.18em]" style={{ color: PRIMARIA }}>{bloco.chamada}</p> : null}
          {secao.title ? <h2 className="mb-3 text-xl font-bold leading-tight sm:text-2xl">{secao.title}</h2> : null}
          {blocos.length ? <Texto blocos={blocos} /> : editor ? <p className="text-xs font-semibold text-[var(--vd-muted-fg)]">Escreva o texto no painel.</p> : null}
          {destino ? (
            destino.externo ? (
              <a href={destino.href} className={classeDoBotao} style={estiloDoBotao} {...(destino.novaAba ? { target: "_blank", rel: "noopener noreferrer" } : {})}>
                {bloco.botao.texto} <ArrowRight className="h-4 w-4" />
              </a>
            ) : (
              <Link href={destino.href} className={classeDoBotao} style={estiloDoBotao} {...(destino.novaAba ? { target: "_blank", rel: "noopener noreferrer" } : {})}>
                {bloco.botao.texto} <ArrowRight className="h-4 w-4" />
              </Link>
            )
          ) : null}
        </div>
      </div>
    </Coluna>
  );
}

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

function VendorPerguntas({ 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 ? (
      <Coluna margem={ajuste.margem}>
        <TituloVendor texto={secao.title} />
        <Vazio texto="Perguntas frequentes: escreva as perguntas e respostas no painel" />
      </Coluna>
    ) : null;
  }
  return (
    <Coluna margem={ajuste.margem}>
      <TituloVendor texto={secao.title} />
      <div className="mx-auto max-w-3xl space-y-2">
        {ajuste.itens.map((item, indice) => {
          const aberto = aberta === indice;
          const id = `vd-faq-${secao.id}-${indice}`;
          return (
            <div key={indice} className="overflow-hidden border" style={{ borderRadius: RXL, borderColor: aberto ? PRIMARIA : "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}>
              <h3>
                <button
                  type="button"
                  id={`${id}-botao`}
                  aria-expanded={aberto}
                  aria-controls={`${id}-resposta`}
                  onClick={() => setAberta(aberto ? null : indice)}
                  className="flex w-full items-center justify-between gap-3 px-4 py-3.5 text-left text-sm font-semibold sm:text-[15px]"
                >
                  <span>{item.pergunta}</span>
                  <span aria-hidden className="flex h-6 w-6 shrink-0 items-center justify-center rounded-full" style={{ backgroundColor: aberto ? PRIMARIA : "var(--vd-muted-bg)", color: aberto ? SOBRE_A_PRIMARIA : "inherit" }}>
                    {aberto ? <Minus className="h-3.5 w-3.5" strokeWidth={3} /> : <Plus className="h-3.5 w-3.5" strokeWidth={3} />}
                  </span>
                </button>
              </h3>
              <div id={`${id}-resposta`} role="region" aria-labelledby={`${id}-botao`} hidden={!aberto} className="px-4 pb-4">
                <Texto blocos={lerTextoSimples(item.resposta)} />
              </div>
            </div>
          );
        })}
      </div>
    </Coluna>
  );
}

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

function VendorOndeEstamos({ 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 ? (
      <Coluna margem={ajuste.margem}>
        <TituloVendor texto={secao.title} />
        <Vazio icone={<MapPin className="h-6 w-6" />} texto={ajuste.usarDaLoja ? "A empresa ainda não tem endereço cadastrado" : "Escreva o endereço no painel"} />
      </Coluna>
    ) : 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 (
    <Coluna margem={ajuste.margem}>
      <TituloVendor texto={secao.title} />
      <div className="grid overflow-hidden border sm:grid-cols-[minmax(0,2fr)_minmax(0,3fr)]" style={{ borderRadius: R2XL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}>
        <div className="flex flex-col gap-4 p-5 sm:p-6">
          <div className="flex gap-3">
            <MapPin className="mt-0.5 h-5 w-5 shrink-0" style={{ color: PRIMARIA }} />
            <address className="text-sm not-italic leading-relaxed">
              {endereco.linhas.map((l) => (
                <span key={l} className="block">
                  {l}
                </span>
              ))}
            </address>
          </div>
          {horarios.length ? (
            <div className="flex gap-3">
              <Clock className="mt-0.5 h-5 w-5 shrink-0" style={{ color: PRIMARIA }} />
              <ul className="text-sm leading-relaxed">
                {horarios.map((h) => (
                  <li key={h}>{h}</li>
                ))}
              </ul>
            </div>
          ) : null}
          {telefone ? (
            <div className="flex items-center gap-3 text-sm">
              <Phone className="h-5 w-5 shrink-0" style={{ color: PRIMARIA }} /> {telefone}
            </div>
          ) : null}
          <a
            href={enderecoDaRota(endereco.busca)}
            target="_blank"
            rel="noopener noreferrer"
            className="inline-flex h-10 items-center gap-1.5 self-start px-4 text-[13px] font-semibold transition hover:brightness-110"
            style={{ borderRadius: RLG, backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}
          >
            <Navigation className="h-4 w-4" /> Traçar rota
          </a>
          {retiradas.length ? (
            <div className="border-t pt-3" style={{ borderColor: "var(--vd-border)" }}>
              <p className="mb-1.5 text-[11px] font-bold uppercase tracking-wider text-[var(--vd-muted-fg)]">Pontos de retirada</p>
              <ul className="space-y-2">
                {retiradas.map((r) => (
                  <li key={r.nome + r.endereco.busca} className="text-xs">
                    <span className="font-semibold">{r.nome}</span>
                    <span className="block text-[var(--vd-muted-fg)]">{r.endereco.linhas.slice(0, 2).join(" · ")}</span>
                  </li>
                ))}
              </ul>
            </div>
          ) : null}
        </div>
        {ajuste.mostrarMapa ? (
          <div className="relative min-h-[240px] bg-[var(--vd-muted-bg)] sm:min-h-[320px]">
            {editor ? (
              <span className="absolute inset-0 flex flex-col items-center justify-center gap-2 text-xs font-semibold text-[var(--vd-muted-fg)]">
                <MapPin className="h-8 w-8" style={{ color: PRIMARIA }} /> 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="absolute inset-0 h-full w-full border-0" loading="lazy" referrerPolicy="no-referrer-when-downgrade" />
            )}
          </div>
        ) : null}
      </div>
    </Coluna>
  );
}

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

function VendorFaixa({ secao, ctx }: Props) {
  const editor = useNoEditor();
  const reduzido = useMovimentoReduzido();
  const faixa = lerFaixa(configDaSecao(secao.config), ctx.corDaMarca || "#111827");
  if (!faixa.itens.length) {
    return editor ? (
      <Coluna margem="pequeno">
        <Vazio texto="Faixa que desliza: escreva as frases no painel" />
      </Coluna>
    ) : null;
  }
  const tamanho = faixa.tamanho === "g" ? "text-lg sm:text-2xl py-3.5" : faixa.tamanho === "p" ? "text-[11px] py-1.5" : "text-[13px] sm:text-sm py-2.5";
  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 font-semibold">
          <span className="px-4 sm:px-6">{item}</span>
          <span aria-hidden className="opacity-60">•</span>
        </span>
      ))}
    </span>
  );
  return (
    <div className="mt-3 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={`vd-faixa-desliza flex overflow-hidden ${tamanho}`} role="marquee" aria-label={faixa.itens.join(" • ")}>
          <div className="vd-faixa-desliza-trilho flex" style={{ animationDuration: `${SEGUNDOS_DA_FAIXA[faixa.velocidade]}s` }}>
            {grupo(false)}
            {grupo(true)}
          </div>
        </div>
      )}
      <style>{`@keyframes vd-faixa-desliza{from{transform:translateX(0)}to{transform:translateX(-50%)}}.vd-faixa-desliza-trilho{animation-name:vd-faixa-desliza;animation-timing-function:linear;animation-iteration-count:infinite;will-change:transform}.vd-faixa-desliza:hover .vd-faixa-desliza-trilho{animation-play-state:paused}@media (prefers-reduced-motion: reduce){.vd-faixa-desliza-trilho{animation:none}}`}</style>
    </div>
  );
}

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

function VendorPontos({ 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 ? (
      <Coluna margem={ajuste.margem}>
        <TituloVendor texto={secao.title} />
        <Vazio texto="Imagem com pontos: escolha a imagem e toque nela no painel para marcar os produtos" />
      </Coluna>
    ) : null;
  }
  return (
    <Coluna margem={ajuste.margem}>
      <TituloVendor texto={secao.title} />
      <div className="relative w-full" style={{ aspectRatio: String(PROPORCOES_DOS_PONTOS[ajuste.proporcao]) }} onMouseLeave={() => setAberto(null)}>
        <div className="absolute inset-0 overflow-hidden bg-[var(--vd-muted-bg)]" style={{ borderRadius: R2XL }}>
          {/* 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 VendorProduto;
          const ativo = aberto === indice;
          const preco = precoDoCartao(produto as never, 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="-ml-3.5 -mt-3.5 flex h-7 w-7 items-center justify-center rounded-full border-2 border-white shadow-lg transition hover:scale-110"
                style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}
              >
                <span className="h-2 w-2 rounded-full bg-white" />
              </button>
              {ativo ? (
                <Link
                  href={`/${ctx.slug}/p/${encodeURIComponent(produto.id)}`}
                  className={`absolute flex w-52 items-center gap-2.5 border p-2 shadow-xl ${ponto.x > 60 ? "right-5" : "left-5"} ${ponto.y > 55 ? "bottom-1" : "top-1"}`}
                  style={{ borderRadius: RXL, borderColor: "var(--vd-border)", backgroundColor: "var(--vd-surface)" }}
                >
                  {foto ? (
                    /* eslint-disable-next-line @next/next/no-img-element */
                    <img src={foto} alt="" className="h-12 w-12 shrink-0 object-cover" style={{ borderRadius: RLG }} />
                  ) : null}
                  <span className="min-w-0">
                    <span className="line-clamp-2 text-xs font-semibold leading-snug">{produto.name}</span>
                    <span className="block text-[13px] font-bold">{preco.texto}</span>
                  </span>
                </Link>
              ) : null}
            </div>
          );
        })}
      </div>
    </Coluna>
  );
}

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

function VendorAntesEDepois({ 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 ? (
      <Coluna margem={ajuste.margem}>
        <TituloVendor texto={secao.title} />
        <Vazio texto="Antes e depois: escolha as duas imagens no painel" />
      </Coluna>
    ) : null;
  }
  return (
    <Coluna margem={ajuste.margem}>
      <TituloVendor texto={secao.title} />
      <div
        ref={caixa}
        {...eventosDaCaixa}
        className="relative w-full touch-pan-y select-none overflow-hidden bg-[var(--vd-muted-bg)]"
        style={{ borderRadius: R2XL, 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-3 left-3 rounded-md bg-white/90 px-2 py-0.5 text-[11px] font-semibold text-[var(--vd-foreground,#111827)]">{ajuste.rotuloAntes}</span>
        <span className="pointer-events-none absolute bottom-3 right-3 rounded-md px-2 py-0.5 text-[11px] font-semibold" style={{ backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA }}>
          {ajuste.rotuloDepois}
        </span>
        <span className="pointer-events-none absolute inset-y-0 w-0.5 -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-10 w-10 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full border-2 border-white shadow-lg focus-visible:outline focus-visible:outline-4 focus-visible:outline-offset-2"
          style={{ left: `${posicao}%`, backgroundColor: PRIMARIA, color: SOBRE_A_PRIMARIA, outlineColor: PRIMARIA }}
        >
          <span aria-hidden className="text-sm font-bold">‹›</span>
        </span>
      </div>
    </Coluna>
  );
}

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

export function VendorWidgetDaHome(props: Props) {
  switch (modoDaSecao(props.secao)) {
    case "flash_offer":
      return <VendorOferta {...props} />;
    case "coupon_highlight":
      return <VendorCupom {...props} />;
    case "order_cutoff":
      return <VendorCorte {...props} />;
    case "next_live":
      return <VendorLive {...props} />;
    case "auto_list":
      return <VendorLista {...props} />;
    case "combo_highlight":
      return <VendorKits {...props} />;
    case "recently_viewed":
      return <VendorVistos {...props} />;
    case "video_section":
      return <VendorVideo {...props} />;
    case "text_image":
      return <VendorTextoComImagem {...props} />;
    case "faq":
      return <VendorPerguntas {...props} />;
    case "store_location":
      return <VendorOndeEstamos {...props} />;
    case "marquee":
      return <VendorFaixa {...props} />;
    case "shoppable_image":
      return <VendorPontos {...props} />;
    case "before_after":
      return <VendorAntesEDepois {...props} />;
    default:
      return null;
  }
}
