import type { Metadata } from "next";
import type { ReactNode } from "react";
import CatalogAnalyticsTracker from "@/components/CatalogAnalyticsTracker";
import { notFound, redirect } from 'next/navigation';
import StoreLayout from '@/components/StoreLayout';
import FontesDaLoja from "@/components/FontesDaLoja";
import { miniatura, produtoComFotoMenor, storiesComFotoMenor, TAMANHO } from "@/lib/foto";
import StoreContent from '@/components/StoreContent';
import { resolveCatalogAppearance } from "@/lib/catalog-appearance";
import { buildCatalogMetadata } from "@/lib/catalog-metadata";
import { buildStoreStructuredData } from "@/lib/catalog-structured-data";
import StructuredData from "@/components/StructuredData";
import { normalizeStoriesGroups } from "@/lib/catalog-stories";
import { createAdminClient } from "@/lib/supabase-admin";
import { VendorShell } from "@/templates/vendor/VendorShell";
import { aparenciaDoVendor } from "@/templates/vendor/aparencia";
import { VendorHome } from "@/templates/vendor/VendorHome";
import { BoutiqueShell } from "@/templates/boutique/BoutiqueShell";
import { aparenciaDaBoutique } from "@/templates/boutique/aparencia";
import { BoutiqueHome } from "@/templates/boutique/BoutiqueHome";
import { carregarLoja, carregarLojaAgora, type DadosDaLoja } from "@/lib/loja/dados-da-loja";
import { lerPassagemDoEditor, type PassagemDoEditor } from "@/lib/passagem-do-editor";
import { lerPassagemDaPrevia, temaDaPagina as escolherTemaDaPagina } from "@/lib/passagem-da-previa";
import { MarcaDaPrevia } from "@/components/home/MarcaDaPrevia";
import { SONDAGEM_DA_HOME_DA_BOUTIQUE, arranjoAutomaticoDaBoutique, arranjoAutomaticoDoVendor, secoesParaOsTemasAntigos } from "@/lib/pagina-inicial";
import { enderecoDoVideoDaBoutique, produtosComVideoDaBoutique, TETO_DE_VIDEOS_DA_BOUTIQUE } from "@/templates/boutique/videos-da-boutique.server";
import { HomeBoutiqueNoEditor, HomePadraoNoEditor, HomeVendorNoEditor } from "@/components/editor-da-loja/HomeNoEditor";
import { carregarDadosDosWidgets } from "@/lib/loja/dados-dos-widgets";
import { dadosDasPerguntas, lerPerguntas } from "@/lib/widgets-da-home";
import { ProvedorDosWidgets } from "@/components/home/contexto-dos-widgets";
import { lerVisaoDaLoja, enderecoDeLogin } from "@/lib/loja/visao.server";
import { estaEsgotado, semEsgotados, semPrecos, semPrecosNaLista, semPrecosNosStories } from "@/lib/loja/regras-da-loja";
import LojaFechada from "@/components/LojaFechada";
import { ProvedorDaNavegacao } from "@/components/navegacao/ContextoDaNavegacao";
import { NavegacaoNoEditor } from "@/components/editor-da-loja/NavegacaoNoEditor";
import { secoesNoAr } from "@/lib/exibicao-da-secao";
import { ehFamiliaVendor } from "@/themes/registry";
import { ContadorDeCliques } from "@/components/home/ContadorDeCliques";

export const revalidate = 0;

async function resolveClientAvatarUrl(rawValue: string | null | undefined) {
  const value = String(rawValue || "").trim();
  if (!value) return null;
  if (value.startsWith("data:")) return value;

  const parseStorageTarget = (input: string): { bucket: string; path: string } | null => {
    const normalized = input.replace(/^\/+/, "");

    if (/^https?:\/\//i.test(input)) {
      try {
        const parsed = new URL(input);
        const publicMarker = "/storage/v1/object/public/";
        const signMarker = "/storage/v1/object/sign/";
        const marker = parsed.pathname.includes(signMarker) ? signMarker : publicMarker;
        if (!parsed.pathname.includes(marker)) return null;
        const rest = parsed.pathname.slice(parsed.pathname.indexOf(marker) + marker.length);
        const [bucket, ...parts] = rest.split("/");
        return bucket && parts.length ? { bucket, path: parts.join("/") } : null;
      } catch {
        return null;
      }
    }

    const clean = normalized.replace(/^storage\/v1\/object\/public\//, "").replace(/^storage\/v1\/object\/sign\//, "");
    const [bucket, ...parts] = clean.split("/");
    return bucket && parts.length ? { bucket, path: parts.join("/") } : null;
  };

  const target = parseStorageTarget(value);
  if (!target) return value;

  try {
    const admin = createAdminClient();
    const { data: signedData, error: signedError } = await admin.storage
      .from(target.bucket)
      .createSignedUrl(target.path, 60 * 60 * 24 * 30);

    if (!signedError && signedData?.signedUrl) return signedData.signedUrl;

    const { data: publicData } = admin.storage.from(target.bucket).getPublicUrl(target.path);
    return publicData?.publicUrl || value;
  } catch {
    return value;
  }
}


type CatalogProduct = {
  id: string;
  name: string;
  price: number;
  image_url?: string | null;
  stock: number;
  track_inventory?: boolean | null;
  unit_type?: string | null;
  price_on_request?: boolean | null;
  min_sale_qty_enabled?: boolean | null;
  min_sale_qty?: number | null;
  max_sale_qty_enabled?: boolean | null;
  max_sale_qty?: number | null;
  allowed_sale_qty_enabled?: boolean | null;
  allowed_sale_quantities?: number[] | null;
  product_price_tiers?: Array<{
    min_qty: number;
    max_qty: number | null;
    unit_price: number;
    sort_order?: number | null;
    active?: boolean | null;
  }> | null;
  product_images?: Array<{
    id: string;
    image_url: string;
    sort_order?: number | null;
    is_primary?: boolean | null;
  }> | null;
  product_attributes?: Array<{ id: string; show_in_store?: boolean | null }>;
  has_variations?: boolean;
};

type CatalogSectionProduct = {
  section_id: string;
  product: CatalogProduct | null;
};
type CatalogBanner = {
  id: string;
  image_url: string;
  link_type?: "none" | "product" | "url" | null;
  product_id?: string | null;
  link_url?: string | null;
  open_in_new_tab?: boolean | null;
  position?: number | null;
  created_at?: string;
};
type AnnouncementCoupon = {
  id: string;
  code: string;
  type: "percent" | "value";
  value: number;
  active: boolean;
  starts_at?: string | null;
  ends_at?: string | null;
};
const LEGACY_CONFIG_PREFIX = "[[KTCFG:";
const LEGACY_CONFIG_SUFFIX = "]]";

function normalizeSectionConfig(config: unknown): Record<string, unknown> | null {
  if (config && typeof config === "object") return config as Record<string, unknown>;
  if (typeof config === "string") {
    try {
      const parsed = JSON.parse(config);
      return parsed && typeof parsed === "object" ? (parsed as Record<string, unknown>) : null;
    } catch {
      return null;
    }
  }
  return null;
}

function extractLegacySectionMetadata(rawTitle: string) {
  const title = String(rawTitle || "");
  const start = title.indexOf(LEGACY_CONFIG_PREFIX);
  if (start === -1) return { title, legacyConfig: {} as Record<string, unknown> };
  const end = title.indexOf(LEGACY_CONFIG_SUFFIX, start + LEGACY_CONFIG_PREFIX.length);
  if (end === -1) return { title, legacyConfig: {} as Record<string, unknown> };
  const encoded = title.slice(start + LEGACY_CONFIG_PREFIX.length, end);
  const cleanTitle = `${title.slice(0, start)}${title.slice(end + LEGACY_CONFIG_SUFFIX.length)}`.trim();
  try {
    const parsed = JSON.parse(decodeURIComponent(encoded));
    if (parsed && typeof parsed === "object") return { title: cleanTitle, legacyConfig: parsed as Record<string, unknown> };
  } catch {}
  return { title: cleanTitle, legacyConfig: {} as Record<string, unknown> };
}

/*
  O editor da página inicial: o painel abre esta página num quadro com
  ?editar=<passagem>. A passagem é conferida contra o dono da loja ANTES de a
  página ler o banco sem a lembrança (senão qualquer ?editar=lixo furaria a
  lembrança de dois minutos a cada visita). Ver lib/passagem-do-editor.ts.
*/
async function lerOEditor(
  slug: string,
  bruto: unknown
): Promise<{ dados: DadosDaLoja | null; passagem: PassagemDoEditor | null }> {
  const lembrados = await carregarLoja(slug);
  const dono = String(lembrados?.profile?.id || "");
  if (!bruto || !dono) return { dados: lembrados, passagem: null };
  const passagem = lerPassagemDoEditor(bruto, { dono, slug }, process.env.SUPABASE_SERVICE_ROLE_KEY || "");
  if (!passagem) return { dados: lembrados, passagem: null };
  return { dados: await carregarLojaAgora(slug), passagem };
}

/*
  A prévia dos temas (Catálogo > Personalização): o painel mostra a loja num
  quadro com ?previa=<passagem>&tema=<tema>. A passagem é conferida contra o
  dono da loja; valendo, o ?tema= escolhe o desenho também em produção. Os
  dados são os mesmos da lembrança de dois minutos (o tema é só desenho) e a
  visita não conta. Ver lib/passagem-da-previa.ts. No editor não há prévia.
*/
function lerAPrevia(slug: string, dono: string, bruto: unknown): boolean {
  if (!bruto || !dono) return false;
  return Boolean(lerPassagemDaPrevia(bruto, { dono, slug }, process.env.SUPABASE_SERVICE_ROLE_KEY || ""));
}

export async function generateMetadata(
  props: { params: Promise<{ slug: string }>; searchParams?: Promise<{ editar?: string; previa?: string }> }
): Promise<Metadata> {
  const params = await props.params;
  const { slug } = params;
  const profile = (await carregarLoja(slug))?.profile ?? null;
  const buscados = (await props.searchParams) || {};
  /* Editor e prévia dos temas nunca entram em busca (basta o parâmetro: a
     página com ?previa= não é a da loja, nem quando a passagem não vale). */
  const noEditor = Boolean(buscados.editar) || Boolean(buscados.previa);

  const metadados = buildCatalogMetadata({
    profile,
    // A home E a loja: aqui o que foi escrito na aba Metadados e SEO vence.
    scope: "store",
    pageTitle: profile?.catalog_name || profile?.store_name || "Loja",
    pageDescription: `Conheça os produtos e ofertas de ${profile?.catalog_name || profile?.store_name || "nossa loja"}.`,
    path: "/",
  });
  return noEditor ? { ...metadados, robots: { index: false, follow: false } } : metadados;
}

export default async function StorePage(props: {
  params: Promise<{ slug: string }>;
  searchParams?: Promise<{ tema?: string; editar?: string; previa?: string }>;
}) {
  const params = await props.params;
  const { slug } = params;
  const buscados = (await props.searchParams) || {};

  /* 1. A loja inteira, lembrada por dois minutos (lib/loja/dados-da-loja.ts):
     perfil, produtos enxutos, categorias, seções, banners, cupom e stories,
     em duas idas ao banco no máximo. No editor da página inicial (passagem
     conferida), lida agora, sem a lembrança. */
  const { dados, passagem } = await lerOEditor(slug, buscados.editar);
  const profile = dados?.profile;

  if (!dados || !profile) {
    return notFound();
  }
  const naPrevia = !passagem && lerAPrevia(slug, String(profile.id || ""), buscados.previa);
  /* Visita que não conta nos relatórios: o lojista no editor ou na prévia. */
  const naoConta = Boolean(passagem) || naPrevia;

  /* Quem esta olhando: cliente logado, equipe ou visitante, e o que as
     regras da loja deixam cada um ver (lib/loja/regras-da-loja.ts). */
  const { visao, cliente } = await lerVisaoDaLoja(slug, profile);
  if (visao.lojaFechada) {
    return (
      <LojaFechada
        nome={profile.catalog_name || profile.store_name || "Loja"}
        logoUrl={miniatura(profile.catalog_logo_url || profile.logo_url, TAMANHO.logo)}
        corDaMarca={profile.primary_color}
        recado={visao.regras.mensagemDaSituacao}
        voltaEm={visao.regras.voltaEm}
        whatsapp={profile.company_whatsapp || profile.whatsapp}
      />
    );
  }
  if (visao.exigeLoginNaLoja) redirect(enderecoDeLogin(slug, `/${slug}`));
  const loggedClient: { id: string; name: string; avatar_url: string | null; favorites?: string[] | null } | null = cliente
    ? { id: cliente.id, name: cliente.name, avatar_url: await resolveClientAvatarUrl(cliente.avatar_url), favorites: cliente.favorites }
    : null;
  const semPreco = !visao.mostrarPreco;

  /* 2. Os dados lembrados: produtos já enxutos (só o que card e filtro leem),
     com a foto no tamanho do card. */
  /* Esgotado some quando a regra da loja manda esconder. */
  const esconderEsgotados = visao.regras.esgotado === "hide";
  const listaDaLoja = esconderEsgotados ? semEsgotados(dados.products) : dados.products || [];
  const products = (semPreco ? semPrecosNaLista(listaDaLoja) : listaDaLoja).map((p) => produtoComFotoMenor(p, TAMANHO.card));
  const categories = dados.categories || [];
  /* A seção agendada fora da janela não sai na loja publicada. A decisão é
     de agora, a cada visita: a lembrança guarda as seções, nunca a decisão
     (lib/exibicao-da-secao.ts). No editor todas aparecem (com o selo). */
  const sectionsData = passagem ? dados.sections || [] : secoesNoAr(dados.sections || [], Date.now());
  const bannersData = dados.banners || [];
  const selectedCouponData = dados.coupon ?? null;
  const storiesGroupsData = semPreco ? semPrecosNosStories(dados.stories) : dados.stories || [];
  const sectionProducts = (dados.sectionProducts || []) as CatalogSectionProduct[];

  const sections = sectionsData.map((section) => {
    const normalizedConfig = normalizeSectionConfig((section as { config?: unknown }).config);
    const metadata = extractLegacySectionMetadata((section as { title?: string }).title || "");
    const mergedConfig = { ...(metadata.legacyConfig || {}), ...(normalizedConfig || {}) };
    const configMode =
      mergedConfig &&
      "mode" in mergedConfig
        ? mergedConfig.mode
        : undefined;
    const sectionType = configMode ?? section.section_type ?? (section as { type?: unknown }).type;
    return {
      ...section,
      title: metadata.title,
      config: mergedConfig,
      section_type: (
        sectionType === "all_products" ||
        sectionType === "category_products" ||
        sectionType === "subcategory_products" ||
        sectionType === "image_banner" ||
        sectionType === "category_navigator" ||
        sectionType === "image_grid" ||
        sectionType === "banner_carousel"
          ? sectionType
          : "manual_products"
      ) as "manual_products" | "all_products" | "category_products" | "subcategory_products" | "image_banner" | "category_navigator" | "image_grid" | "banner_carousel",
      products: sectionProducts
        .filter((sp) => sp.section_id === section.id)
        .map((sp) => (sp.product && !(esconderEsgotados && estaEsgotado(sp.product)) ? produtoComFotoMenor(semPreco ? semPrecos(sp.product) : sp.product, TAMANHO.card) : null))
        .filter(Boolean) || [],
    };
  });

  const slideEnabled = Boolean((profile as { catalog_slide_enabled?: boolean | null } | null)?.catalog_slide_enabled);
  const infoStripEnabledRaw = (profile as { catalog_info_strip_enabled?: boolean | null } | null)?.catalog_info_strip_enabled;
  const infoStripEnabled = infoStripEnabledRaw === null || infoStripEnabledRaw === undefined ? true : Boolean(infoStripEnabledRaw);
  const infoStripItemsRaw = (profile as { catalog_info_strip_items?: unknown } | null)?.catalog_info_strip_items;
  const infoStripItems = Array.isArray(infoStripItemsRaw) ? (infoStripItemsRaw as Array<{ icon?: unknown; title?: unknown; subtitle?: unknown }>).map((x) => ({
    icon: typeof x?.icon === "string" ? x.icon : "truck",
    title: typeof x?.title === "string" ? x.title : "",
    subtitle: typeof x?.subtitle === "string" ? x.subtitle : "",
  })) : [];

  const resolvedBanners: CatalogBanner[] = Array.isArray(bannersData)
    ? (bannersData as CatalogBanner[]).map((banner) => ({
        ...banner,
        image_url: miniatura(banner.image_url, TAMANHO.banner),
        created_at: banner.created_at ?? undefined,
        link_type: banner.link_type ?? undefined,
        product_id: banner.product_id ?? undefined,
        link_url: banner.link_url ?? undefined,
        open_in_new_tab: banner.open_in_new_tab ?? undefined,
        position: banner.position ?? undefined,
      }))
    : [];

  const primaryColor = profile.primary_color || '#4F46E5';
  const storeName = profile.catalog_name || profile.store_name || "Loja";
  const logoUrl = miniatura(profile.catalog_logo_url || profile.logo_url, TAMANHO.logo);
  const selectedAnnouncementCoupon = selectedCouponData as AnnouncementCoupon | null;
  const storiesGroups = storiesComFotoMenor(normalizeStoriesGroups(storiesGroupsData));

  const aparencia = resolveCatalogAppearance(profile);

  /* Store + WebSite: identifica a loja para o Google e habilita a caixa de
     busca do proprio site no resultado. */
  const dadosEstruturados = buildStoreStructuredData({
    slug,
    storeName: profile.catalog_name || profile.store_name || "Loja",
    description: profile.catalog_meta_description || profile.catalog_slogan,
    logoUrl: profile.catalog_logo_url || profile.logo_url,
    whatsapp: profile.company_whatsapp || profile.whatsapp,
    address: profile.catalog_footer_address || profile.address,
  });

  /* O Vendor é um template inteiro à parte: shell, home e página de produto
     próprios. O desvio acontece aqui, antes de qualquer coisa do Padrão ou do
     Vitrine ser montada — os três nunca se misturam na mesma árvore. */
  /* `?tema=` abre a MESMA loja em outro template. Fora de produção sempre
     (comparar lado a lado); em produção só na prévia dos temas, com a
     passagem desta loja conferida. Na loja publicada vale o perfil. */
  const temaDaPagina = escolherTemaDaPagina({
    pedido: buscados?.tema,
    naPrevia,
    producao: process.env.NODE_ENV === "production",
    salvo: profile.catalog_theme,
  });

  /* Os blocos novos da página inicial (oferta, cupom, live, mais vendidos,
     kits, onde estamos...): só lê o banco quando a loja usa um deles (ou no
     editor). Sem bloco, null: nada de provedor e a página sai como sempre. A
     família Vendor (Vendor e Boutique) só mostra as seções depois de
     publicar pelo editor. */
  const secoesQueAparecem = ehFamiliaVendor(temaDaPagina) && !dados.homeEditada ? [] : sections;
  const dadosDosWidgets = await carregarDadosDosWidgets(profile, secoesQueAparecem as never[], { noEditor: Boolean(passagem), semPreco });
  const comWidgets = (conteudo: ReactNode) =>
    dadosDosWidgets ? <ProvedorDosWidgets dados={dadosDosWidgets}>{conteudo}</ProvedorDosWidgets> : conteudo;
  /* As perguntas frequentes da página vão também para o Google (FAQPage). */
  const perguntasDaHome = passagem
    ? null
    : dadosDasPerguntas(
        secoesQueAparecem
          .filter((secao) => (secao.config as { mode?: unknown } | null)?.mode === "faq")
          .map((secao) => lerPerguntas(secao.config as Record<string, unknown>))
      );
  const dadosEstruturadosDaHome = perguntasDaHome ? [...dadosEstruturados, perguntasDaHome] : dadosEstruturados;

  /* No editor: os produtos que uma seção de produtos escolhidos pode
     mostrar (os da loja e os que já estavam nas seções salvas), para o
     rascunho montar a lista sem ir ao banco. */
  const produtosPorId: Record<string, { id: string } & Record<string, unknown>> = {};
  if (passagem) {
    for (const secao of sections) {
      for (const produto of (secao.products || []) as Array<{ id: string } & Record<string, unknown>>) {
        if (produto?.id) produtosPorId[String(produto.id)] = produto;
      }
    }
    for (const produto of products as Array<{ id: string } & Record<string, unknown>>) produtosPorId[String(produto.id)] = produto;
  }

  /* O menu e o rodapé publicados no editor (null = os de sempre). No editor,
     o rascunho que o painel manda toma o lugar deles e o cabeçalho e o
     rodapé viram regiões clicáveis. */
  const comNavegacao = (conteudo: ReactNode) =>
    passagem ? (
      <NavegacaoNoEditor origemDoPainel={passagem.origemDoPainel} publicada={dados.navegacao} paginas={dados.paginas}>
        {conteudo}
      </NavegacaoNoEditor>
    ) : (
      <ProvedorDaNavegacao navegacao={dados.navegacao}>{conteudo}</ProvedorDaNavegacao>
    );

  /* A Boutique é da família Vendor (home automática até publicar, seções no
     desenho do tema), mas com árvore própria: shell, home e componentes em
     templates/boutique. A home automática dela é escrita como seções
     (arranjoAutomaticoDaBoutique): a loja desenha essas seções e o editor
     abre com elas, então as duas são sempre iguais. */
  if (temaDaPagina === "boutique") {
    /* Antes de montar a home automática, o servidor sonda os mais vendidos
       (90 dias) e os kits do "Compre junto": sem venda, a vitrine vira a da
       maior categoria; sem kit, o "Elas vestem" nem entra. Lido junto com os
       vídeos dos produtos ("compre pelo vídeo"). No editor e na home
       publicada os dados já vieram com as seções. */
    const automaticaDaBoutique = !dados.homeEditada;
    const [widgetsDaBoutique, comVideo] = await Promise.all([
      automaticaDaBoutique && !passagem
        ? carregarDadosDosWidgets(profile, SONDAGEM_DA_HOME_DA_BOUTIQUE as never[], { noEditor: false, semPreco })
        : Promise.resolve(dadosDosWidgets),
      produtosComVideoDaBoutique(profile as never),
    ]);
    const arranjoDaBoutique = automaticaDaBoutique
      ? arranjoAutomaticoDaBoutique(products as never[], categories as never[], {
          nomeDaLoja: storeName,
          maisVendidos: widgetsDaBoutique?.maisVendidos?.["90"] ?? [],
          combos: widgetsDaBoutique?.combos ?? [],
        })
      : null;
    /* Os vídeos só de produto que este visitante vê (produto escondido,
       esgotado escondido e preço escondido já resolvidos na lista), sem os
       digitais, até o teto. */
    const visiveisPorId = new Map((products as Array<{ id: string; product_kind?: string | null }>).map((p) => [String(p.id), p]));
    const videosDaBoutique = comVideo
      .map((id) => visiveisPorId.get(id))
      .filter((p): p is { id: string; product_kind?: string | null } => Boolean(p) && p?.product_kind !== "digital")
      .slice(0, TETO_DE_VIDEOS_DA_BOUTIQUE)
      .map((produto) => ({ produto: produto as never, endereco: enderecoDoVideoDaBoutique(produto.id) }));
    const comWidgetsDaBoutique = (conteudo: ReactNode) =>
      widgetsDaBoutique ? <ProvedorDosWidgets dados={widgetsDaBoutique}>{conteudo}</ProvedorDosWidgets> : conteudo;
    /* A home montada pelo editor (a loja publicou ao menos uma vez). Sem
       publicação, null: a home automática de sempre. */
    const secoesDaBoutique = dados.homeEditada
      ? sections.map((secao) => ({
          id: String(secao.id),
          title: secao.title,
          layout_width: (secao as { layout_width?: string | null }).layout_width ?? null,
          section_type: secao.section_type,
          config: secao.config,
          products: secao.products as never[],
        }))
      : null;
    const propsDaBoutique = {
      slug,
      produtos: (products || []) as never[],
      categorias: (categories || []) as never[],
      banners: resolvedBanners as never[],
      avaliacoes: [],
      mediaDasAvaliacoes: 0,
      nomeDaLoja: storeName,
      logoUrl,
      tarja:
        profile.catalog_info_strip_enabled !== false
          ? (infoStripItems as Array<{ icon?: string | null; title?: string | null; subtitle?: string | null }>)
          : [],
      corDaMarca: primaryColor,
      clienteId: loggedClient?.id || null,
      favoritos: loggedClient?.favorites || null,
      videos: videosDaBoutique,
      stories: (profile.catalog_stories_enabled ?? true) ? (storiesGroups as never[]) : [],
      provaSocial: {
        /* No editor a prova social fica quieta: ela cobre os botões. */
        ligado: passagem ? false : profile.catalog_social_proof_enabled,
        intervaloSegundos: profile.catalog_social_proof_interval_seconds,
        duracaoSegundos: profile.catalog_social_proof_duration_seconds,
        quantosCabem: profile.catalog_social_proof_max_visible,
        posicao: profile.catalog_social_proof_position,
      },
    };
    return (
      <StoreLayout
        primaryColor={primaryColor}
        whatsappNumber={profile.whatsapp}
        cartScope={profile.id || slug}
        storeSlug={slug}
        theme={temaDaPagina}
        chatLigado={naoConta ? false : profile.store_chat_enabled === true}
        visao={visao}
      >
        <FontesDaLoja perfil={profile} />
        {naPrevia ? <MarcaDaPrevia /> : null}
        <StructuredData data={dadosEstruturadosDaHome} />
        <>
        {/* A Boutique conta as mesmas visitas que os outros temas: sem isto os
            relatórios da loja ficariam vazios só por causa do template. No
            editor quem olha é o lojista: não conta. */}
        {naoConta ? null : <CatalogAnalyticsTracker slug={slug} eventName="page_view" onceKey="page_view:home" />}
        {/* A home montada pelo editor conta os cliques de cada seção (migration 199). */}
        {!naoConta && dados.homeEditada ? <ContadorDeCliques slug={slug} /> : null}
        {comNavegacao(
        <BoutiqueShell
          slug={slug}
          nomeDaLoja={storeName}
          slogan={profile.catalog_slogan}
          logoUrl={logoUrl}
          corDaMarca={primaryColor}
          aparencia={aparenciaDaBoutique(profile as never)}
          cupomDoAviso={selectedAnnouncementCoupon as never}
          whatsappFlutuante={profile.catalog_whatsapp_float}
          categorias={(categories || []) as never[]}
          contato={{
            whatsapp: profile.whatsapp,
            telefone: profile.company_phone || profile.phone,
            email: profile.email,
            endereco: profile.catalog_footer_address || profile.address,
            cnpj: profile.catalog_show_document ? profile.cnpj : null,
            instagram: profile.social_instagram,
            facebook: profile.social_facebook,
          }}
          clienteLogado={Boolean(loggedClient)}
        >
          {comWidgetsDaBoutique(passagem ? (
            <HomeBoutiqueNoEditor
              propsDaBoutique={propsDaBoutique}
              secoesSalvas={secoesDaBoutique}
              origemDoPainel={passagem.origemDoPainel}
              tema="boutique"
              homeEditada={dados.homeEditada}
              arranjoAutomatico={arranjoDaBoutique}
              produtosPorId={produtosPorId}
            />
          ) : (
            <BoutiqueHome
              {...propsDaBoutique}
              secoesDaHome={
                secoesDaBoutique ??
                (arranjoDaBoutique || []).map((secao) => ({
                  id: secao.id,
                  title: secao.title,
                  layout_width: secao.layout_width,
                  section_type: secao.section_type,
                  config: secao.config,
                  products: [],
                }))
              }
              homeAutomatica={!secoesDaBoutique}
            />
          ))}
        </BoutiqueShell>
        )}
        </>
      </StoreLayout>
    );
  }

  if (temaDaPagina === "vendor") {
    /* A home montada pelo editor (a loja publicou ao menos uma vez). Sem
       publicação, null: a home automática de sempre. */
    const secoesDoVendor = dados.homeEditada
      ? sections.map((secao) => ({
          id: String(secao.id),
          title: secao.title,
          layout_width: (secao as { layout_width?: string | null }).layout_width ?? null,
          section_type: secao.section_type,
          config: secao.config,
          products: secao.products as never[],
        }))
      : null;
    const propsDoVendor = {
      slug,
      produtos: (products || []) as never[],
      categorias: (categories || []) as never[],
      banners: resolvedBanners as never[],
      avaliacoes: [],
      mediaDasAvaliacoes: 0,
      nomeDaLoja: storeName,
      logoUrl,
      tarja:
        profile.catalog_info_strip_enabled !== false
          ? (infoStripItems as Array<{ icon?: string | null; title?: string | null; subtitle?: string | null }>)
          : [],
      corDaMarca: primaryColor,
      clienteId: loggedClient?.id || null,
      favoritos: loggedClient?.favorites || null,
      stories: (profile.catalog_stories_enabled ?? true) ? (storiesGroups as never[]) : [],
      provaSocial: {
        /* No editor a prova social fica quieta: ela cobre os botões. */
        ligado: passagem ? false : profile.catalog_social_proof_enabled,
        intervaloSegundos: profile.catalog_social_proof_interval_seconds,
        duracaoSegundos: profile.catalog_social_proof_duration_seconds,
        quantosCabem: profile.catalog_social_proof_max_visible,
        posicao: profile.catalog_social_proof_position,
      },
    };
    return (
      <StoreLayout
        primaryColor={primaryColor}
        whatsappNumber={profile.whatsapp}
        cartScope={profile.id || slug}
        storeSlug={slug}
        theme={temaDaPagina}
        chatLigado={naoConta ? false : profile.store_chat_enabled === true}
        visao={visao}
      >
        <FontesDaLoja perfil={profile} />
        {naPrevia ? <MarcaDaPrevia /> : null}
        <StructuredData data={dadosEstruturadosDaHome} />
        <>
        {/* O Vendor conta as mesmas visitas que os outros temas: sem isto os
            relatórios da loja ficariam vazios só por causa do template. No
            editor quem olha é o lojista: não conta. */}
        {naoConta ? null : <CatalogAnalyticsTracker slug={slug} eventName="page_view" onceKey="page_view:home" />}
        {/* A home montada pelo editor conta os cliques de cada seção (migration 199). */}
        {!naoConta && dados.homeEditada ? <ContadorDeCliques slug={slug} /> : null}
        {comNavegacao(
        <VendorShell
          slug={slug}
          nomeDaLoja={storeName}
          slogan={profile.catalog_slogan}
          logoUrl={logoUrl}
          corDaMarca={primaryColor}
          aparencia={aparenciaDoVendor(profile as never)}
          cupomDoAviso={selectedAnnouncementCoupon as never}
          whatsappFlutuante={profile.catalog_whatsapp_float}
          categorias={(categories || []) as never[]}
          contato={{
            whatsapp: profile.whatsapp,
            telefone: profile.company_phone || profile.phone,
            email: profile.email,
            endereco: profile.catalog_footer_address || profile.address,
            cnpj: profile.catalog_show_document ? profile.cnpj : null,
            instagram: profile.social_instagram,
            facebook: profile.social_facebook,
          }}
          clienteLogado={Boolean(loggedClient)}
        >
          {comWidgets(passagem ? (
            <HomeVendorNoEditor
              propsDoVendor={propsDoVendor}
              secoesSalvas={secoesDoVendor}
              origemDoPainel={passagem.origemDoPainel}
              tema="vendor"
              homeEditada={dados.homeEditada}
              arranjoAutomatico={
                dados.homeEditada
                  ? null
                  : arranjoAutomaticoDoVendor(
                      products as never[],
                      categories as never[],
                      (bannersData || []) as never[]
                    )
              }
              produtosPorId={produtosPorId}
            />
          ) : (
            <VendorHome {...propsDoVendor} secoesDaHome={secoesDoVendor} />
          ))}
        </VendorShell>
        )}
        </>
      </StoreLayout>
    );
  }

  /* Os tipos novos do editor (primeiros produtos, categorias em círculos,
     categoria sem as de dentro) desenhados com o desenho dos tipos antigos.
     Loja sem tipo novo recebe as mesmas seções de sempre. */
  const secoesDaHome = secoesParaOsTemasAntigos(sections, (products || []) as never[], (categories || []) as never[], {
    maisVendidos: dadosDosWidgets?.maisVendidos,
  });

  const propsDaLoja = {
    products: products || [],
    categories: categories || [],
    banners: resolvedBanners,
    sections: secoesDaHome,
    slideEnabled: slideEnabled,
    infoStripEnabled: infoStripEnabled,
    infoStripItems: infoStripItems,
    slug: slug,
    primaryColor: primaryColor,
    storeName: storeName,
    storeSlogan: profile.catalog_slogan,
    logoUrl: logoUrl,
    showStoreNameInHeader: profile.catalog_show_name_in_header,
    showStoreSloganInHeader: profile.catalog_show_slogan_in_header,
    storeNameColor: profile.catalog_name_color,
    storeSloganColor: profile.catalog_slogan_color,
    catalogHeaderIconColor: profile.catalog_header_icon_color,
    logoEffectEnabled: profile.catalog_logo_effect_enabled,
    logoEffectType: profile.catalog_logo_effect,
    logoEffectSpeed: profile.catalog_logo_effect_speed,
    logoEffectIntensity: profile.catalog_logo_effect_intensity,
    whatsapp: profile.whatsapp,
    whatsappFloat: profile.catalog_whatsapp_float,
    phone: profile.phone,
    companyPhone: profile.company_phone,
    companyWhatsapp: profile.company_whatsapp,
    address: profile.address,
    cnpj: profile.cnpj,
    catalogShowDocument: profile.catalog_show_document,
    headerColor: aparencia.headerColor,
    headerTextColor: aparencia.headerTextColor,
    menuColor: aparencia.menuColor,
    menuTextColor: aparencia.menuTextColor,
    pageBgColor: aparencia.pageBgColor,
    cardButtonColor: aparencia.cardButtonColor,
    fontHeadingFamily: aparencia.fonts.heading,
    fontBodyFamily: aparencia.fonts.body,
    footerColor: profile.catalog_footer_color,
    footerTextColor: profile.catalog_footer_text_color,
    socialFacebook: profile.social_facebook,
    socialInstagram: profile.social_instagram,
    socialTwitter: profile.social_twitter,
    socialLinkedin: profile.social_linkedin,
    socialYoutube: profile.social_youtube,
    announcementEnabled: profile.catalog_announcement_enabled,
    announcementText: profile.catalog_announcement_text,
    announcementCountdownEnabled: profile.catalog_announcement_countdown_enabled,
    announcementCountdownEndAt: profile.catalog_announcement_countdown_end_at,
    announcementShowCouponBadge: profile.catalog_announcement_show_coupon_badge,
    announcementCouponBadgeColor: profile.catalog_announcement_coupon_badge_color,
    announcementBackgroundColor: profile.catalog_announcement_background_color,
    announcementTextColor: profile.catalog_announcement_text_color,
    announcementButtonLabel: profile.catalog_announcement_button_label,
    announcementButtonUrl: profile.catalog_announcement_button_url,
    announcementSticky: profile.catalog_announcement_sticky,
    announcementCoupon: selectedAnnouncementCoupon,
    announcementCouponId: profile.catalog_announcement_coupon_id,
    socialProofEnabled: passagem ? false : profile.catalog_social_proof_enabled,
    socialProofIntervalSeconds: profile.catalog_social_proof_interval_seconds,
    socialProofPosition: profile.catalog_social_proof_position,
    socialProofDurationSeconds: profile.catalog_social_proof_duration_seconds,
    socialProofMaxVisible: profile.catalog_social_proof_max_visible,
    vitrineProductLayout: profile.catalog_vitrine_product_layout,
    storiesGroups: storiesGroups,
    catalogStoriesEnabled: profile.catalog_stories_enabled ?? true,
    loggedClient: loggedClient,
  };

  return (
    <StoreLayout
      primaryColor={primaryColor}
      whatsappNumber={profile.whatsapp}
      cartScope={profile.id || slug}
      storeSlug={slug}
      theme={temaDaPagina}
      chatLigado={naoConta ? false : profile.store_chat_enabled === true}
      visao={visao}
    >
      <FontesDaLoja perfil={profile} />
      {naPrevia ? <MarcaDaPrevia /> : null}
      <StructuredData data={dadosEstruturadosDaHome} />
      {!naoConta && dados.homeEditada ? <ContadorDeCliques slug={slug} /> : null}
      {comNavegacao(comWidgets(passagem ? (
        <HomePadraoNoEditor
          propsDaLoja={propsDaLoja}
          origemDoPainel={passagem.origemDoPainel}
          tema={temaDaPagina || "default"}
          homeEditada={dados.homeEditada}
          arranjoAutomatico={null}
          produtosPorId={produtosPorId}
        />
      ) : (
        <StoreContent {...propsDaLoja} contarCliques={dados.homeEditada} />
      )))}
    </StoreLayout>
  );
}
