"use client";

import type { ReactNode } from "react";
import { AlignCenter, AlignLeft, AlignRight, ArrowDown, ArrowUp, Copy, Eye, EyeOff, Plus, Trash2, X } from "lucide-react";
import { ColorField } from "@/components/ui/color-field";
import {
  FORMATOS_DE_BANNER,
  LIMITE_DE_ATALHOS,
  LIMITE_DE_PRODUTOS,
  LIMITE_DO_CARROSSEL,
  NOME_DO_MODO,
  PROPORCAO_DO_CELULAR,
  PROPORCOES_DA_IMAGEM,
  QUANTAS_NA_GRADE,
  RESUMO_DO_MODO,
  ehFamiliaVendor,
  lerLink,
  type FormatoDeBanner,
  type LayoutDaGrade,
  type LinkDaSecao,
  type ProporcaoDaImagem,
  type SecaoDoEditor,
  type Tema,
} from "@/lib/pagina-inicial";
import {
  Ajuste,
  CampoDeImagem,
  CampoDeLink,
  Chave,
  DesenhoDaProporcao,
  Escolha,
  ListaDeProdutos,
  Miniaturas,
  Segmentos,
  Texto,
  nomeDaCategoria,
  type CategoriaDoEditor,
  type ProdutoDoEditor,
} from "./campos";
import { SeloDoModo } from "./icones";
import { AjustesDoWidget } from "./ajustes-dos-widgets";
import { ehWidget } from "@/lib/widgets-da-home";
import { AjustesDeExibicao } from "./exibicao";
import { BotaoDeGerarBanner } from "./gerador-de-banner";

/*
  O painel de ajustes da seção escolhida. Cada mudança vai direto para o
  rascunho (e a loja ao lado redesenha na hora); nada é gravado até
  "Publicar".
*/

type Props = {
  secao: SecaoDoEditor;
  tema: Tema;
  produtos: ProdutoDoEditor[];
  categorias: CategoriaDoEditor[];
  aoMudar: (secao: SecaoDoEditor) => void;
  aoSubir: () => void;
  aoDescer: () => void;
  aoDuplicar: () => void;
  aoAlternar: () => void;
  aoApagar: () => void;
  aoFechar?: () => void;
  fixa: boolean;
  primeira: boolean;
  ultima: boolean;
};

type Item = { imagem?: string; imagem_celular?: string; legenda?: string; link?: LinkDaSecao };

function itensDe(config: Record<string, unknown>): Item[] {
  return Array.isArray(config.itens) ? (config.itens as Item[]).map((item) => ({ ...(item || {}) })) : [];
}

const DESENHO_DA_GRADE: Record<LayoutDaGrade, ReactNode> = {
  "2": (
    <span className="flex gap-1">
      <span className="h-6 w-5 rounded-[3px] bg-current" />
      <span className="h-6 w-5 rounded-[3px] bg-current" />
    </span>
  ),
  "3": (
    <span className="flex gap-1">
      {[0, 1, 2].map((i) => (
        <span key={i} className="h-6 w-3.5 rounded-[3px] bg-current" />
      ))}
    </span>
  ),
  "4": (
    <span className="flex gap-0.5">
      {[0, 1, 2, 3].map((i) => (
        <span key={i} className="h-6 w-2.5 rounded-[2px] bg-current" />
      ))}
    </span>
  ),
  "1+2": (
    <span className="flex gap-1">
      <span className="h-6 w-5 rounded-[3px] bg-current" />
      <span className="flex flex-col gap-1">
        <span className="h-2.5 w-5 rounded-[2px] bg-current" />
        <span className="h-2.5 w-5 rounded-[2px] bg-current" />
      </span>
    </span>
  ),
  "2+1": (
    <span className="flex gap-1">
      <span className="flex flex-col gap-1">
        <span className="h-2.5 w-5 rounded-[2px] bg-current" />
        <span className="h-2.5 w-5 rounded-[2px] bg-current" />
      </span>
      <span className="h-6 w-5 rounded-[3px] bg-current" />
    </span>
  ),
};

function BotaoDoTopo({ titulo, onClick, children, perigo, desligado }: { titulo: string; onClick: () => void; children: ReactNode; perigo?: boolean; desligado?: boolean }) {
  return (
    <button
      type="button"
      title={titulo}
      aria-label={titulo}
      disabled={desligado}
      onClick={onClick}
      className={`flex h-8 w-8 items-center justify-center rounded-lg transition disabled:opacity-30 ${
        perigo
          ? "text-[var(--ks-color-text-soft)] hover:bg-rose-50 hover:text-rose-600"
          : "text-[var(--ks-color-text-soft)] hover:bg-[var(--ks-color-bg-hover)] hover:text-[var(--ks-color-primary)]"
      }`}
    >
      {children}
    </button>
  );
}

export function AjustesDaSecao(props: Props) {
  const { secao, tema, produtos, categorias, aoMudar } = props;
  const c = secao.config;
  /* A família Vendor (Vendor e Boutique): o desenho do tema manda. */
  const vendor = ehFamiliaVendor(tema);

  const mudar = (parcial: Partial<SecaoDoEditor>) => aoMudar({ ...secao, ...parcial });
  const mudarConfig = (parcial: Record<string, unknown>) => aoMudar({ ...secao, config: { ...secao.config, ...parcial } });

  const titulo = (
    <Ajuste rotulo="Título da seção" dica={secao.modo === "image_grid" || secao.modo === "banner_carousel" ? undefined : "Aparece em cima da seção na loja."}>
      <Texto valor={secao.title} aoMudar={(title) => mudar({ title })} placeholder={NOME_DO_MODO[secao.modo]} rotulo="Título da seção" />
    </Ajuste>
  );

  /* Cores, alinhamento e tamanho do título valem nos temas Padrão e Vitrine;
     o Vendor e a Boutique têm o desenho deles. */
  const aparenciaDoTitulo = vendor ? null : (
    <>
      <Ajuste rotulo="Alinhamento do título">
        <Segmentos
          rotulo="Alinhamento do título"
          valor={secao.title_align}
          aoMudar={(title_align) => mudar({ title_align })}
          opcoes={[
            { valor: "left", rotulo: <AlignLeft size={15} />, titulo: "À esquerda" },
            { valor: "center", rotulo: <AlignCenter size={15} />, titulo: "No centro" },
            { valor: "right", rotulo: <AlignRight size={15} />, titulo: "À direita" },
          ]}
        />
      </Ajuste>
      <Ajuste rotulo="Tamanho do título">
        <Segmentos
          rotulo="Tamanho do título"
          valor={secao.title_size}
          aoMudar={(title_size) => mudar({ title_size })}
          opcoes={[
            { valor: "sm", rotulo: "P" },
            { valor: "md", rotulo: "M" },
            { valor: "lg", rotulo: "G" },
            { valor: "xl", rotulo: "GG" },
          ]}
        />
      </Ajuste>
    </>
  );

  const cores = vendor ? null : (
    <Ajuste rotulo="Cores" dica={secao.layout_width === "contained" ? "Na caixa, o fundo vira um cartão arredondado." : undefined}>
      <div className="grid grid-cols-1 gap-2.5">
        <ColorField label="Fundo" value={secao.background_color} onChange={(background_color) => mudar({ background_color })} allowAuto={false} />
        <ColorField label="Título" value={secao.text_color} onChange={(text_color) => mudar({ text_color })} allowAuto={false} />
      </div>
    </Ajuste>
  );

  const largura = (rotuloCheio: string, rotuloCaixa: string, dica?: string) => (
    <Ajuste rotulo="Largura" dica={dica}>
      <Segmentos
        rotulo="Largura"
        valor={secao.layout_width}
        aoMudar={(layout_width) => mudar({ layout_width })}
        opcoes={[
          { valor: "contained", rotulo: rotuloCaixa },
          { valor: "full", rotulo: rotuloCheio },
        ]}
      />
    </Ajuste>
  );

  const margem = (
    <Ajuste rotulo="Espaço em cima e embaixo">
      <Segmentos
        rotulo="Espaço em cima e embaixo"
        valor={String(c.margem || "normal")}
        aoMudar={(valor) => mudarConfig({ margem: valor })}
        opcoes={[
          { valor: "nenhum", rotulo: "Colado" },
          { valor: "pequeno", rotulo: "Pequeno" },
          { valor: "normal", rotulo: "Normal" },
        ]}
      />
    </Ajuste>
  );

  const categoriaEscolhida = (somenteFilhas: boolean) => (
    <Ajuste rotulo={somenteFilhas ? "Subcategoria" : "Categoria"} dica={somenteFilhas ? "Só os produtos desta subcategoria." : undefined}>
      <Escolha
        valor={String(c.target_category_id || "")}
        itens={somenteFilhas ? categorias.filter((cat) => cat.parent_id) : categorias}
        aoEscolher={(categoria) =>
          aoMudar({
            ...secao,
            title: !secao.title || secao.title === NOME_DO_MODO[secao.modo] ? categoria.name : secao.title,
            config: { ...secao.config, target_category_id: categoria.id, target_category_slug: categoria.slug },
          })
        }
        textoDoItem={(categoria) => nomeDaCategoria(categoria, categorias)}
        placeholder={somenteFilhas ? "Escolher a subcategoria" : "Escolher a categoria"}
        vazio="Nenhuma categoria visível com esse nome."
      />
    </Ajuste>
  );

  const quantidade = (padrao: number, opcoes = [4, 8, 12]) => (
    <Ajuste rotulo="Quantos produtos">
      <Segmentos
        rotulo="Quantos produtos"
        valor={String(Number(c.quantidade) || padrao)}
        aoMudar={(valor) => mudarConfig({ quantidade: Number(valor) })}
        opcoes={opcoes.map((n) => ({ valor: String(n), rotulo: String(n) }))}
      />
    </Ajuste>
  );

  /* --------------------------------------------- os ajustes de cada tipo */
  let corpo: ReactNode = null;

  if (secao.modo === "manual_products") {
    corpo = (
      <>
        {titulo}
        <Ajuste rotulo={`Produtos (${secao.produtos.length})`} dica="A ordem aqui é a ordem na loja.">
          <ListaDeProdutos ids={secao.produtos} aoMudar={(ids) => mudar({ produtos: ids })} produtos={produtos} limite={LIMITE_DE_PRODUTOS} />
        </Ajuste>
        {vendor ? null : largura("Inteira", "Na caixa")}
        {aparenciaDoTitulo}
        {cores}
      </>
    );
  } else if (secao.modo === "all_products") {
    corpo = (
      <>
        {titulo}
        <div className="border-t border-[var(--ks-n-100)] px-5 py-4 text-[12px] leading-5 text-[var(--ks-color-text-soft)]">
          Mostra todos os produtos da loja, na ordem da lista de produtos, com &quot;Ver mais&quot; no fim.
          {vendor ? null : " Nos modelos Padrão e Vitrine esta grade sempre existe: dá para mudar o lugar e o título, não tirar."}
        </div>
        {aparenciaDoTitulo}
      </>
    );
  } else if (secao.modo === "category_products" || secao.modo === "subcategory_products") {
    const somenteFilhas = secao.modo === "subcategory_products";
    corpo = (
      <>
        {categoriaEscolhida(somenteFilhas)}
        {titulo}
        {somenteFilhas ? null : (
          <Chave
            ligada={c.so_da_categoria !== true}
            aoMudar={(ligada) => mudarConfig({ so_da_categoria: !ligada })}
            rotulo="Incluir as subcategorias"
            dica="Desligado: só os produtos que estão direto nesta categoria."
          />
        )}
        <Chave
          ligada={c.show_view_more !== false}
          aoMudar={(ligada) => mudarConfig({ show_view_more: ligada })}
          rotulo='Botão "Ver todos"'
          dica="Leva para a página da categoria."
        />
        {vendor ? quantidade(4) : null}
        {vendor ? null : largura("Inteira", "Na caixa")}
        {aparenciaDoTitulo}
        {cores}
      </>
    );
  } else if (secao.modo === "featured_products") {
    corpo = (
      <>
        {titulo}
        {quantidade(4)}
        <div className="border-t border-[var(--ks-n-100)] px-5 py-4 text-[12px] leading-5 text-[var(--ks-color-text-soft)]">
          Os primeiros produtos na ordem da aba Produtos. Para trocar quem aparece, arraste os produtos lá.
        </div>
        {aparenciaDoTitulo}
        {cores}
      </>
    );
  } else if (secao.modo === "category_circles") {
    corpo = (
      <>
        <div className="px-5 py-4 text-[12px] leading-5 text-[var(--ks-color-text-soft)]">
          As categorias principais da loja, em círculos, cada uma com a foto do primeiro produto dela. Categoria nova entra sozinha.
          Para escolher quais e trocar as fotos, use &quot;Atalhos de categorias&quot;.
        </div>
        {vendor ? null : titulo}
        <Ajuste rotulo="Quantas aparecem">
          <Segmentos
            rotulo="Quantas aparecem"
            valor={String(Number(c.limite) || 0)}
            aoMudar={(valor) => mudarConfig({ limite: Number(valor) || null })}
            opcoes={[
              { valor: "0", rotulo: "Todas" },
              { valor: "4", rotulo: "4" },
              { valor: "6", rotulo: "6" },
              { valor: "8", rotulo: "8" },
            ]}
          />
        </Ajuste>
      </>
    );
  } else if (secao.modo === "category_navigator") {
    const itens = (Array.isArray(c.items) ? (c.items as Array<Record<string, string>>) : []).slice(0, LIMITE_DE_ATALHOS);
    const mudarItens = (novos: Array<Record<string, string>>) => mudarConfig({ items: novos.slice(0, LIMITE_DE_ATALHOS) });
    corpo = (
      <>
        {titulo}
        <Ajuste
          rotulo={`Atalhos (${itens.length} de ${LIMITE_DE_ATALHOS})`}
          direita={
            itens.length < LIMITE_DE_ATALHOS ? (
              <button
                type="button"
                onClick={() => mudarItens([...itens, { target_category_id: "", target_category_slug: "", label: "", image_url: "" }])}
                className="inline-flex items-center gap-1 text-[12px] font-bold text-[var(--ks-color-primary)] hover:underline"
              >
                <Plus size={14} /> Atalho
              </button>
            ) : null
          }
        >
          <div className="space-y-3">
            {itens.map((item, indice) => (
              <div key={indice} className="rounded-xl border border-[var(--ks-color-border-subtle)] p-3">
                <div className="mb-2 flex items-center justify-between">
                  <span className="text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">Atalho {indice + 1}</span>
                  <button
                    type="button"
                    aria-label="Tirar atalho"
                    onClick={() => mudarItens(itens.filter((_, i) => i !== indice))}
                    className="flex h-7 w-7 items-center justify-center rounded-lg text-[var(--ks-color-text-soft)] hover:bg-rose-50 hover:text-rose-600"
                  >
                    <X size={14} />
                  </button>
                </div>
                <div className="space-y-2">
                  <Escolha
                    valor={item.target_category_id}
                    itens={categorias}
                    aoEscolher={(categoria) =>
                      mudarItens(itens.map((x, i) => (i === indice ? { ...x, target_category_id: categoria.id, target_category_slug: categoria.slug } : x)))
                    }
                    textoDoItem={(categoria) => nomeDaCategoria(categoria, categorias)}
                    placeholder="Escolher a categoria"
                  />
                  <Texto
                    valor={item.label || ""}
                    aoMudar={(label) => mudarItens(itens.map((x, i) => (i === indice ? { ...x, label } : x)))}
                    placeholder="Nome embaixo da foto (opcional)"
                    max={40}
                  />
                  <div className="w-28">
                    <CampoDeImagem
                      valor={item.image_url || ""}
                      aoMudar={(image_url) => mudarItens(itens.map((x, i) => (i === indice ? { ...x, image_url } : x)))}
                      proporcao={1}
                      largura={480}
                      altura={480}
                      dica="Foto redonda."
                    />
                  </div>
                </div>
              </div>
            ))}
            {!itens.length ? (
              <p className="rounded-xl bg-[var(--ks-color-bg-inset)] px-3 py-4 text-center text-[12px] text-[var(--ks-color-text-soft)]">
                Toque em &quot;Atalho&quot; para pôr a primeira categoria.
              </p>
            ) : null}
          </div>
        </Ajuste>
        {aparenciaDoTitulo}
      </>
    );
  } else if (secao.modo === "image_banner") {
    const formato = (typeof c.formato === "string" && c.formato in FORMATOS_DE_BANNER ? c.formato : "faixa") as FormatoDeBanner;
    const medida = FORMATOS_DE_BANNER[formato];
    const link = c.link ? lerLink(c.link) : c.link_url ? lerLink({ tipo: "url", url: c.link_url, nova_aba: c.open_in_new_tab === true }) : lerLink(null);
    /* Mexeu no banner antigo: ele passa a ter formato (o antigo, sem formato,
       continua com o desenho de sempre até alguém mexer). */
    const mudarBanner = (parcial: Record<string, unknown>) => mudarConfig({ formato, link, ...parcial });
    corpo = (
      <>
        <Ajuste rotulo="Formato">
          <Miniaturas<FormatoDeBanner>
            valor={formato}
            colunas={4}
            aoMudar={(novo) => mudarBanner({ formato: novo })}
            opcoes={(Object.keys(FORMATOS_DE_BANNER) as FormatoDeBanner[]).map((chave) => ({
              valor: chave,
              nome: FORMATOS_DE_BANNER[chave].nome,
              detalhe: FORMATOS_DE_BANNER[chave].medida,
              desenho: <DesenhoDaProporcao proporcao={FORMATOS_DE_BANNER[chave].proporcao} />,
            }))}
          />
        </Ajuste>
        <Ajuste rotulo="Imagem">
          <CampoDeImagem
            valor={String(c.image_url || "")}
            aoMudar={(image_url) => mudarBanner({ image_url })}
            proporcao={medida.proporcao}
            largura={medida.largura}
            altura={medida.altura}
          />
          <BotaoDeGerarBanner largura={medida.largura} altura={medida.altura} aoUsar={(image_url) => mudarBanner({ image_url })} />
        </Ajuste>
        <Ajuste rotulo="Imagem para celular" dica="Opcional. Sem ela, o celular mostra a mesma imagem, menor.">
          <div className="w-40">
            <CampoDeImagem
              valor={String(c.imagem_celular || "")}
              aoMudar={(imagem_celular) => mudarBanner({ imagem_celular })}
              proporcao={PROPORCAO_DO_CELULAR.proporcao}
              largura={PROPORCAO_DO_CELULAR.largura}
              altura={PROPORCAO_DO_CELULAR.altura}
              dica={`${PROPORCAO_DO_CELULAR.medida}`}
            />
          </div>
        </Ajuste>
        <Ajuste rotulo="Link">
          <CampoDeLink link={link} aoMudar={(novo) => mudarBanner({ link: novo })} produtos={produtos} categorias={categorias} />
        </Ajuste>
        {formato === "faixa" ? null : (
          <Ajuste rotulo="Texto por cima" dica="Opcional. Fica bom em foto sem texto.">
            <div className="space-y-2">
              <Texto valor={String(c.titulo_na_imagem || "")} aoMudar={(v) => mudarBanner({ titulo_na_imagem: v })} placeholder="Título (ex.: Coleção de verão)" max={90} />
              <Texto valor={String(c.subtitulo || "")} aoMudar={(v) => mudarBanner({ subtitulo: v })} placeholder="Frase de apoio" max={160} />
              <Texto valor={String(c.botao || "")} aoMudar={(v) => mudarBanner({ botao: v })} placeholder="Texto do botão (ex.: Ver agora)" max={30} />
              {c.titulo_na_imagem || c.subtitulo || c.botao ? (
                <div className="grid grid-cols-2 gap-2 pt-1">
                  <Segmentos
                    rotulo="Posição do texto"
                    valor={String(c.alinhamento_do_texto || "esquerda")}
                    aoMudar={(v) => mudarBanner({ alinhamento_do_texto: v })}
                    opcoes={[
                      { valor: "esquerda", rotulo: <AlignLeft size={15} />, titulo: "À esquerda" },
                      { valor: "centro", rotulo: <AlignCenter size={15} />, titulo: "No centro" },
                    ]}
                  />
                  <Segmentos
                    rotulo="Cor do texto"
                    valor={String(c.tom_do_texto || "claro")}
                    aoMudar={(v) => mudarBanner({ tom_do_texto: v })}
                    opcoes={[
                      { valor: "claro", rotulo: "Branco" },
                      { valor: "escuro", rotulo: "Escuro" },
                    ]}
                  />
                </div>
              ) : null}
            </div>
          </Ajuste>
        )}
        {vendor ? null : largura("De ponta a ponta", "Na caixa")}
        {margem}
      </>
    );
  } else if (secao.modo === "banner_carousel") {
    const formato = (typeof c.formato === "string" && c.formato in FORMATOS_DE_BANNER ? c.formato : "largo") as FormatoDeBanner;
    const medida = FORMATOS_DE_BANNER[formato];
    const itens = itensDe(c).slice(0, LIMITE_DO_CARROSSEL);
    const mudarItens = (novos: Item[]) => mudarConfig({ itens: novos.slice(0, LIMITE_DO_CARROSSEL) });
    corpo = (
      <>
        <Ajuste rotulo="Formato">
          <Miniaturas<FormatoDeBanner>
            valor={formato}
            colunas={4}
            aoMudar={(novo) => mudarConfig({ formato: novo })}
            opcoes={(Object.keys(FORMATOS_DE_BANNER) as FormatoDeBanner[]).map((chave) => ({
              valor: chave,
              nome: FORMATOS_DE_BANNER[chave].nome,
              detalhe: FORMATOS_DE_BANNER[chave].medida,
              desenho: <DesenhoDaProporcao proporcao={FORMATOS_DE_BANNER[chave].proporcao} />,
            }))}
          />
        </Ajuste>
        <Ajuste
          rotulo={`Banners (${itens.length} de ${LIMITE_DO_CARROSSEL})`}
          direita={
            itens.length < LIMITE_DO_CARROSSEL ? (
              <button type="button" onClick={() => mudarItens([...itens, { imagem: "", link: { tipo: "nenhum" } }])} className="inline-flex items-center gap-1 text-[12px] font-bold text-[var(--ks-color-primary)] hover:underline">
                <Plus size={14} /> Banner
              </button>
            ) : null
          }
        >
          <div className="space-y-3">
            {itens.map((item, indice) => (
              <BlocoDaImagem
                key={indice}
                indice={indice}
                total={itens.length}
                rotulo={`Banner ${indice + 1}`}
                item={item}
                proporcao={medida.proporcao}
                largura={medida.largura}
                altura={medida.altura}
                comCelular
                produtos={produtos}
                categorias={categorias}
                aoMudar={(novo) => mudarItens(itens.map((x, i) => (i === indice ? novo : x)))}
                aoTirar={() => mudarItens(itens.filter((_, i) => i !== indice))}
                aoMover={(direcao) => {
                  const alvo = indice + direcao;
                  if (alvo < 0 || alvo >= itens.length) return;
                  const novos = [...itens];
                  [novos[indice], novos[alvo]] = [novos[alvo], novos[indice]];
                  mudarItens(novos);
                }}
              />
            ))}
            {!itens.length ? (
              <button
                type="button"
                onClick={() => mudarItens([{ imagem: "", link: { tipo: "nenhum" } }])}
                className="flex w-full items-center justify-center gap-2 rounded-xl border-2 border-dashed border-[var(--ks-brand-200)] px-3 py-5 text-[12.5px] font-bold text-[var(--ks-color-primary)] hover:border-[var(--ks-color-primary)]"
              >
                <Plus size={16} /> Pôr o primeiro banner
              </button>
            ) : null}
          </div>
        </Ajuste>
        <Chave ligada={c.automatico !== false} aoMudar={(ligada) => mudarConfig({ automatico: ligada })} rotulo="Passar sozinho" dica="Para quando o cliente põe o mouse em cima." />
        {c.automatico !== false ? (
          <Ajuste rotulo="Tempo de cada banner">
            <Segmentos
              rotulo="Tempo de cada banner"
              valor={String(Number(c.intervalo) || 6)}
              aoMudar={(v) => mudarConfig({ intervalo: Number(v) })}
              opcoes={[
                { valor: "4", rotulo: "4 s" },
                { valor: "6", rotulo: "6 s" },
                { valor: "8", rotulo: "8 s" },
                { valor: "10", rotulo: "10 s" },
              ]}
            />
          </Ajuste>
        ) : null}
        {vendor ? null : largura("De ponta a ponta", "Na caixa")}
        {margem}
        <Chave ligada={c.mostrar_titulo === true} aoMudar={(ligada) => mudarConfig({ mostrar_titulo: ligada })} rotulo="Mostrar o título em cima" />
        {c.mostrar_titulo === true ? titulo : null}
      </>
    );
  } else if (secao.modo === "image_grid") {
    const layout = (["2", "3", "4", "1+2", "2+1"].includes(String(c.layout)) ? String(c.layout) : "3") as LayoutDaGrade;
    const proporcao = (typeof c.proporcao === "string" && c.proporcao in PROPORCOES_DA_IMAGEM ? c.proporcao : "quadrado") as ProporcaoDaImagem;
    const medida = PROPORCOES_DA_IMAGEM[proporcao];
    const quantas = QUANTAS_NA_GRADE[layout];
    const itens = Array.from({ length: quantas }, (_, i) => itensDe(c)[i] || { imagem: "", link: { tipo: "nenhum" as const } });
    const guardados = itensDe(c);
    const mudarItem = (indice: number, novo: Item) => {
      const lista = Array.from({ length: Math.max(guardados.length, quantas) }, (_, i) => guardados[i] || { imagem: "", link: { tipo: "nenhum" } });
      lista[indice] = novo;
      mudarConfig({ itens: lista });
    };
    corpo = (
      <>
        <Ajuste rotulo="Arrumação">
          <Miniaturas<LayoutDaGrade>
            valor={layout}
            colunas={3}
            aoMudar={(novo) => mudarConfig({ layout: novo })}
            opcoes={[
              { valor: "2", nome: "2 colunas", desenho: DESENHO_DA_GRADE["2"] },
              { valor: "3", nome: "3 colunas", desenho: DESENHO_DA_GRADE["3"] },
              { valor: "4", nome: "4 colunas", desenho: DESENHO_DA_GRADE["4"] },
              { valor: "1+2", nome: "1 grande + 2", desenho: DESENHO_DA_GRADE["1+2"] },
              { valor: "2+1", nome: "2 + 1 grande", desenho: DESENHO_DA_GRADE["2+1"] },
            ]}
          />
        </Ajuste>
        <Ajuste rotulo="Formato das imagens">
          <Miniaturas<ProporcaoDaImagem>
            valor={proporcao}
            colunas={4}
            aoMudar={(novo) => mudarConfig({ proporcao: novo })}
            opcoes={(Object.keys(PROPORCOES_DA_IMAGEM) as ProporcaoDaImagem[]).map((chave) => ({
              valor: chave,
              nome: PROPORCOES_DA_IMAGEM[chave].nome,
              detalhe: PROPORCOES_DA_IMAGEM[chave].medida,
              desenho: <DesenhoDaProporcao proporcao={PROPORCOES_DA_IMAGEM[chave].proporcao} />,
            }))}
          />
        </Ajuste>
        <Ajuste rotulo={`Imagens (${quantas})`} dica="Cada imagem leva para um lugar. Sem imagem, o lugar não aparece na loja.">
          <div className="space-y-3">
            {itens.map((item, indice) => (
              <BlocoDaImagem
                key={indice}
                indice={indice}
                total={quantas}
                rotulo={layout === "1+2" && indice === 0 ? "Imagem grande" : layout === "2+1" && indice === 2 ? "Imagem grande" : `Imagem ${indice + 1}`}
                item={item}
                proporcao={medida.proporcao}
                largura={medida.largura}
                altura={medida.altura}
                comLegenda
                produtos={produtos}
                categorias={categorias}
                aoMudar={(novo) => mudarItem(indice, novo)}
                aoMover={(direcao) => {
                  const alvo = indice + direcao;
                  if (alvo < 0 || alvo >= quantas) return;
                  const lista = Array.from({ length: Math.max(guardados.length, quantas) }, (_, i) => guardados[i] || { imagem: "", link: { tipo: "nenhum" } });
                  [lista[indice], lista[alvo]] = [lista[alvo], lista[indice]];
                  mudarConfig({ itens: lista });
                }}
              />
            ))}
          </div>
        </Ajuste>
        <Ajuste rotulo="No celular">
          <Segmentos
            rotulo="No celular"
            valor={String(c.celular || "deslizar")}
            aoMudar={(v) => mudarConfig({ celular: v })}
            opcoes={[
              { valor: "deslizar", rotulo: "Deslizar" },
              { valor: "lado_a_lado", rotulo: "2 por linha" },
              { valor: "empilhar", rotulo: "Uma embaixo" },
            ]}
          />
        </Ajuste>
        <Ajuste rotulo="Espaço entre as imagens">
          <Segmentos
            rotulo="Espaço entre as imagens"
            valor={String(c.espaco || "medio")}
            aoMudar={(v) => mudarConfig({ espaco: v })}
            opcoes={[
              { valor: "nenhum", rotulo: "Sem" },
              { valor: "pequeno", rotulo: "Pequeno" },
              { valor: "medio", rotulo: "Médio" },
            ]}
          />
        </Ajuste>
        <Ajuste rotulo="Cantos">
          <Segmentos
            rotulo="Cantos"
            valor={String(c.cantos || "suaves")}
            aoMudar={(v) => mudarConfig({ cantos: v })}
            opcoes={[
              { valor: "retos", rotulo: "Retos" },
              { valor: "suaves", rotulo: "Suaves" },
              { valor: "redondos", rotulo: "Redondos" },
            ]}
          />
        </Ajuste>
        {vendor ? null : largura("De ponta a ponta", "Na caixa")}
        {margem}
        <Chave ligada={c.mostrar_titulo === true} aoMudar={(ligada) => mudarConfig({ mostrar_titulo: ligada })} rotulo="Mostrar o título em cima" />
        {c.mostrar_titulo === true ? (
          <>
            {titulo}
            {aparenciaDoTitulo}
          </>
        ) : null}
      </>
    );
  } else if (ehWidget(secao.modo)) {
    /* Os blocos novos (oferta, cupom, vídeo, perguntas...): ajustes-dos-widgets. */
    corpo = <AjustesDoWidget secao={secao} tema={tema} produtos={produtos} categorias={categorias} aoMudar={aoMudar} titulo={titulo} margem={margem} />;
  }

  return (
    <div className="flex h-full flex-col">
      <div className="flex items-start gap-3 border-b border-[var(--ks-n-100)] px-5 pb-4 pt-5">
        <SeloDoModo modo={secao.modo} tamanho={36} />
        <div className="min-w-0 flex-1">
          <p className="text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-primary)]">{NOME_DO_MODO[secao.modo]}</p>
          <p className="truncate text-[15px] font-extrabold text-[var(--ks-color-text-primary)]">{secao.title || NOME_DO_MODO[secao.modo]}</p>
          <p className="mt-0.5 text-[11.5px] text-[var(--ks-color-text-soft)]">{RESUMO_DO_MODO[secao.modo]}</p>
        </div>
        {props.aoFechar ? (
          <button type="button" aria-label="Fechar" onClick={props.aoFechar} className="flex h-8 w-8 items-center justify-center rounded-lg text-[var(--ks-color-text-soft)] hover:bg-[var(--ks-color-bg-hover)]">
            <X size={16} />
          </button>
        ) : null}
      </div>
      <div className="flex items-center gap-0.5 border-b border-[var(--ks-n-100)] px-3 py-1.5">
        <BotaoDoTopo titulo="Subir" onClick={props.aoSubir} desligado={props.primeira}>
          <ArrowUp size={16} />
        </BotaoDoTopo>
        <BotaoDoTopo titulo="Descer" onClick={props.aoDescer} desligado={props.ultima}>
          <ArrowDown size={16} />
        </BotaoDoTopo>
        {props.fixa ? (
          <span className="ml-auto pr-2 text-[11px] font-semibold text-[var(--ks-color-text-soft)]">Grade fixa do modelo</span>
        ) : (
          <>
            <BotaoDoTopo titulo="Duplicar" onClick={props.aoDuplicar}>
              <Copy size={16} />
            </BotaoDoTopo>
            <BotaoDoTopo titulo={secao.ativa ? "Esconder da loja" : "Mostrar na loja"} onClick={props.aoAlternar}>
              {secao.ativa ? <EyeOff size={16} /> : <Eye size={16} />}
            </BotaoDoTopo>
            <span className="ml-auto" />
            <BotaoDoTopo titulo="Apagar a seção" perigo onClick={props.aoApagar}>
              <Trash2 size={16} />
            </BotaoDoTopo>
          </>
        )}
      </div>
      {!secao.ativa ? (
        <div className="mx-5 mt-4 rounded-xl bg-[var(--ks-color-bg-inset)] px-3 py-2.5 text-[12px] font-semibold text-[var(--ks-color-text-secondary)]">
          Escondida: fica guardada, mas não aparece na loja.
        </div>
      ) : null}
      <div className="flex-1 overflow-y-auto pb-6">
        {corpo}
        {/* Agendar, aparelho, fundo e espaço: valem para qualquer seção. */}
        <AjustesDeExibicao key={secao.chave} secao={secao} aoMudar={aoMudar} />
      </div>
    </div>
  );
}

function BlocoDaImagem({
  indice,
  total,
  rotulo,
  item,
  proporcao,
  largura,
  altura,
  comLegenda,
  comCelular,
  produtos,
  categorias,
  aoMudar,
  aoTirar,
  aoMover,
}: {
  indice: number;
  total: number;
  rotulo: string;
  item: Item;
  proporcao: number;
  largura: number;
  altura: number;
  comLegenda?: boolean;
  comCelular?: boolean;
  produtos: ProdutoDoEditor[];
  categorias: CategoriaDoEditor[];
  aoMudar: (item: Item) => void;
  aoTirar?: () => void;
  aoMover: (direcao: -1 | 1) => void;
}) {
  return (
    <div data-bloco={indice} className="rounded-xl border border-[var(--ks-color-border-subtle)] p-3">
      <div className="mb-2.5 flex items-center justify-between">
        <span className="text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">{rotulo}</span>
        <span className="flex items-center">
          <BotaoDoTopo titulo="Para trás" onClick={() => aoMover(-1)} desligado={indice === 0}>
            <ArrowUp size={14} />
          </BotaoDoTopo>
          <BotaoDoTopo titulo="Para frente" onClick={() => aoMover(1)} desligado={indice >= total - 1}>
            <ArrowDown size={14} />
          </BotaoDoTopo>
          {aoTirar ? (
            <BotaoDoTopo titulo="Tirar" perigo onClick={aoTirar}>
              <X size={14} />
            </BotaoDoTopo>
          ) : null}
        </span>
      </div>
      <div className="space-y-2.5">
        <div>
          <CampoDeImagem valor={item.imagem || ""} aoMudar={(imagem) => aoMudar({ ...item, imagem })} proporcao={proporcao} largura={largura} altura={altura} />
          <BotaoDeGerarBanner largura={largura} altura={altura} aoUsar={(imagem) => aoMudar({ ...item, imagem })} />
        </div>
        {comCelular ? (
          <details className="group rounded-lg bg-[var(--ks-color-bg-inset)] px-3 py-2">
            <summary className="cursor-pointer text-[12px] font-semibold text-[var(--ks-color-text-secondary)]">
              Imagem para celular {item.imagem_celular ? "(escolhida)" : "(opcional)"}
            </summary>
            <div className="mt-2 w-40">
              <CampoDeImagem
                valor={item.imagem_celular || ""}
                aoMudar={(imagem_celular) => aoMudar({ ...item, imagem_celular })}
                proporcao={PROPORCAO_DO_CELULAR.proporcao}
                largura={PROPORCAO_DO_CELULAR.largura}
                altura={PROPORCAO_DO_CELULAR.altura}
                dica={PROPORCAO_DO_CELULAR.medida}
              />
            </div>
          </details>
        ) : null}
        {comLegenda ? (
          <Texto valor={item.legenda || ""} aoMudar={(legenda) => aoMudar({ ...item, legenda })} placeholder="Legenda por cima (opcional)" max={80} />
        ) : null}
        <CampoDeLink link={lerLink(item.link)} aoMudar={(link) => aoMudar({ ...item, link })} produtos={produtos} categorias={categorias} />
      </div>
    </div>
  );
}
