"use client";

import { useMemo, type ComponentProps } from "react";
import StoreContent, { type CatalogSection } from "@/components/StoreContent";
import { VendorHome } from "@/templates/vendor/VendorHome";
import type { VendorSecaoDaHome } from "@/templates/vendor/VendorSecoesDaHome";
import { BoutiqueHome } from "@/templates/boutique/BoutiqueHome";
import type { BoutiqueSecaoDaHome } from "@/templates/boutique/BoutiqueSecoesDaHome";
import { modoDaSecao, secoesParaOsTemasAntigos, type SecaoDaPagina, type SecaoDoRascunho } from "@/lib/pagina-inicial";
import { useDadosDosWidgets } from "@/components/home/contexto-dos-widgets";
import { MolduraDaSecao, PaginaVaziaNoEditor, ProvedorDoEditor, rotuloDaSecao, useConversaComOPainel } from "./EditorDaLoja";

/*
  As homes dentro do editor: a dos temas Padrão e Vitrine (StoreContent), a
  do Vendor e a da Boutique. Cada uma desenha o rascunho que o painel manda
  com o próprio desenho, e põe a moldura do editor em volta de cada seção.
*/

type ProdutoDaLoja = { id: string } & Record<string, unknown>;

type Comum = {
  origemDoPainel: string;
  tema: string;
  homeEditada: boolean;
  arranjoAutomatico: SecaoDaPagina[] | null;
  /* Todos os produtos que uma seção de produtos escolhidos pode mostrar:
     os da loja e os que já estavam nas seções salvas. */
  produtosPorId: Record<string, ProdutoDaLoja>;
};

function produtosDaLista(ids: string[], produtosPorId: Record<string, ProdutoDaLoja>) {
  return ids.map((id) => produtosPorId[id]).filter(Boolean);
}

export function HomePadraoNoEditor({
  propsDaLoja,
  ...comum
}: Comum & { propsDaLoja: ComponentProps<typeof StoreContent> }) {
  const conversa = useConversaComOPainel(comum);
  const { rascunho } = conversa;
  /* Os mais vendidos de verdade (para as listas automáticas do rascunho). */
  const maisVendidos = useDadosDosWidgets()?.maisVendidos;

  const secoes = useMemo<CatalogSection[] | undefined>(() => {
    if (!rascunho) return propsDaLoja.sections;
    const montadas = rascunho.map((s: SecaoDoRascunho, posicao) => ({
      id: s.id,
      title: s.title,
      background_color: s.background_color,
      text_color: s.text_color,
      layout_width: s.layout_width,
      title_align: s.title_align,
      title_size: s.title_size,
      section_type: s.section_type,
      config: s.config,
      previa_no_ar: s.previa_no_ar === true,
      placement: "above" as const,
      position: posicao,
      products: produtosDaLista(s.produtos, comum.produtosPorId),
    }));
    return secoesParaOsTemasAntigos(montadas, propsDaLoja.products as never, propsDaLoja.categories as never, { maisVendidos }) as unknown as CatalogSection[];
  }, [rascunho, propsDaLoja.sections, propsDaLoja.products, propsDaLoja.categories, comum.produtosPorId, maisVendidos]);

  const total = secoes?.length ?? 0;

  return (
    <ProvedorDoEditor
      selecionada={conversa.selecionada}
      enviarAcao={conversa.enviarAcao}
      rotulos={conversa.rotulos}
      zoom={conversa.zoom}
      total={total}
      foraDoPainel={conversa.foraDoPainel}
    >
      <StoreContent
        {...propsDaLoja}
        sections={secoes}
        envolverSecao={(secao, indice, conteudo) => (
          <MolduraDaSecao
            key={secao.id}
            id={secao.id}
            indice={indice}
            rotulo={rotuloDaSecao(secao, conversa.rotulos.get(secao.id))}
            podeApagar={modoDaSecao(secao) !== "all_products"}
          >
            {conteudo}
          </MolduraDaSecao>
        )}
      />
    </ProvedorDoEditor>
  );
}

export function HomeVendorNoEditor({
  propsDoVendor,
  secoesSalvas,
  ...comum
}: Comum & { propsDoVendor: ComponentProps<typeof VendorHome>; secoesSalvas: VendorSecaoDaHome[] | null }) {
  const conversa = useConversaComOPainel(comum);
  const { rascunho } = conversa;

  /* Antes do primeiro rascunho chegar: o que a loja mostra hoje (as seções
     publicadas, ou a home automática escrita como seções). */
  const secoes = useMemo<VendorSecaoDaHome[]>(() => {
    const base = rascunho ?? secoesSalvas ?? comum.arranjoAutomatico ?? [];
    return base.map((s) => ({
      id: s.id,
      title: s.title,
      layout_width: s.layout_width,
      section_type: s.section_type,
      config: s.config,
      previa_no_ar: "previa_no_ar" in s ? s.previa_no_ar === true : undefined,
      products:
        "produtos" in s && Array.isArray(s.produtos)
          ? (produtosDaLista(s.produtos as string[], comum.produtosPorId) as never)
          : ((s as VendorSecaoDaHome).products ?? []),
    }));
  }, [rascunho, secoesSalvas, comum.arranjoAutomatico, comum.produtosPorId]);

  return (
    <ProvedorDoEditor
      selecionada={conversa.selecionada}
      enviarAcao={conversa.enviarAcao}
      rotulos={conversa.rotulos}
      zoom={conversa.zoom}
      total={secoes.length}
      foraDoPainel={conversa.foraDoPainel}
    >
      <VendorHome
        {...propsDoVendor}
        secoesDaHome={secoes}
        envolverSecao={(secao, indice, conteudo) => (
          <MolduraDaSecao key={secao.id} id={secao.id} indice={indice} rotulo={rotuloDaSecao(secao, conversa.rotulos.get(secao.id))}>
            {conteudo}
          </MolduraDaSecao>
        )}
      />
      {secoes.length === 0 ? <PaginaVaziaNoEditor /> : null}
    </ProvedorDoEditor>
  );
}

/* A Boutique, como o Vendor, desenha o rascunho com os componentes dela (pasta
   própria em templates/boutique): a conversa com o painel e a moldura são as
   mesmas, só o desenho muda. */
export function HomeBoutiqueNoEditor({
  propsDaBoutique,
  secoesSalvas,
  ...comum
}: Comum & { propsDaBoutique: ComponentProps<typeof BoutiqueHome>; secoesSalvas: BoutiqueSecaoDaHome[] | null }) {
  const conversa = useConversaComOPainel(comum);
  const { rascunho } = conversa;

  /* Antes do primeiro rascunho chegar: o que a loja mostra hoje (as seções
     publicadas, ou a home automática escrita como seções). */
  const secoes = useMemo<BoutiqueSecaoDaHome[]>(() => {
    const base = rascunho ?? secoesSalvas ?? comum.arranjoAutomatico ?? [];
    return base.map((s) => ({
      id: s.id,
      title: s.title,
      layout_width: s.layout_width,
      section_type: s.section_type,
      config: s.config,
      previa_no_ar: "previa_no_ar" in s ? s.previa_no_ar === true : undefined,
      products:
        "produtos" in s && Array.isArray(s.produtos)
          ? (produtosDaLista(s.produtos as string[], comum.produtosPorId) as never)
          : ((s as BoutiqueSecaoDaHome).products ?? []),
    }));
  }, [rascunho, secoesSalvas, comum.arranjoAutomatico, comum.produtosPorId]);

  return (
    <ProvedorDoEditor
      selecionada={conversa.selecionada}
      enviarAcao={conversa.enviarAcao}
      rotulos={conversa.rotulos}
      zoom={conversa.zoom}
      total={secoes.length}
      foraDoPainel={conversa.foraDoPainel}
    >
      <BoutiqueHome
        {...propsDaBoutique}
        secoesDaHome={secoes}
        envolverSecao={(secao, indice, conteudo) => (
          <MolduraDaSecao key={secao.id} id={secao.id} indice={indice} rotulo={rotuloDaSecao(secao, conversa.rotulos.get(secao.id))}>
            {conteudo}
          </MolduraDaSecao>
        )}
      />
      {secoes.length === 0 ? <PaginaVaziaNoEditor /> : null}
    </ProvedorDoEditor>
  );
}
