"use client";

import { useState, useEffect, useCallback } from "react";
import { getSupabaseClient } from "@/lib/supabase";
import { getCompanyContext, resolveCompanyPublicProfileId } from "@/lib/company-context";
import {
  Save,
  Loader2,
  Sparkles,
  Globe,
  Copy,
  Check,
  ArrowUpRight,
  Eye,
  MessageCircle,
  Building2,
  Phone,
  MapPin,
  Share2,
  Wand2,
  LayoutTemplate,
  BadgeDollarSign,
  ShoppingCart,
  Lock,
  SlidersHorizontal,
  Store,
  PanelTop,
  Timer,
  MessagesSquare,
} from "lucide-react";

import { AnimatePresence, motion } from "framer-motion";
import Image from "next/image";
import Link from "next/link";
import ImageUpload from "@/components/image-upload";
import ThemeSelector from "@/components/ThemeSelector";
import { CorteDeProducao } from "@/components/producao/corte-de-producao";
import { CustomSelect } from "@/components/ui/custom-select";
import { CATALOG_FONT_OPTIONS, HREF_DAS_FONTES_DO_SELETOR } from "@/lib/catalog-fonts";

/* Cabecalhos de grupo entram como opcao desabilitada: sao so divisorias
   visuais na lista. O `value` precisa ser unico porque e a key do React. */
const CATALOG_FONT_SELECT_OPTIONS = [
  { value: "", label: "Padrão da loja" },
  ...CATALOG_FONT_OPTIONS.map((f) =>
    f.tipo === "grupo"
      ? { value: `__grupo:${f.label}`, label: f.label, disabled: true, group_header: true }
      : { value: f.key, label: f.label, labelFontFamily: f.fontFamily }
  ),
];
import { PageHeader } from "@/components/ui/page-header";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { usePermissoes } from "@/lib/permissoes-do-usuario";
import { ColorField } from "@/components/ui/color-field";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Aviso } from "@/components/ui/aviso";
import {
  AreaDeTexto,
  ChaveDeAjuste,
  EscolhaDeAjuste,
  FolhaDeAjustes,
  LinhaDeAjuste,
  SecaoDeAjustes,
  type ItemDoIndice,
} from "@/components/ui/folha-de-ajustes";
import { EntradaDecimal } from "@/components/ui/campo-decimal";
import ChatDaLojaAjuste from "@/components/catalog/chat-da-loja-ajuste";
import PickupLocationsTab, { type CompanyAddress } from "@/components/catalog/pickup-locations-tab";
import { getPublicCatalogOrigin } from "@/lib/public-catalog-url";
import { avisarALojaAgora } from "@/lib/gravacoes-da-vitrine";

/* ------------------------------------------------ a aba "Regras da loja"

   Cada regra é uma escolha entre poucas opções ou uma chave liga/desliga,
   desenhada com a folha de ajustes da casa (components/ui/folha-de-ajustes):
   seções corridas, uma linha por ajuste e o índice ao lado. */

type ModoDePreco = "public" | "hidden" | "clients";
type ModoDeCompra = "cart" | "quote" | "whatsapp" | "showcase";
type ModoDeAcesso = "public" | "clients";
type ModoDeCadastro = "open" | "approval" | "closed";
type EstoqueNaLoja = "exact" | "low_only" | "never";
type ProdutoEsgotado = "show" | "hide" | "quote";
type SituacaoDaLoja = "open" | "paused" | "closed";

/* O texto que o botão do produto e o de fechar têm quando a loja não escreve
   o seu. É o que aparece esmaecido no campo. */
const PADRAO_DO_BOTAO_DO_PRODUTO: Record<ModoDeCompra, string> = {
  cart: "Adicionar ao carrinho",
  quote: "Pedir orçamento",
  whatsapp: "Pedir pelo WhatsApp",
  showcase: "",
};
const PADRAO_DO_BOTAO_DE_FECHAR: Record<ModoDeCompra, string> = {
  cart: "Finalizar pedido",
  quote: "Enviar pedido de orçamento",
  whatsapp: "",
  showcase: "",
};

/* O índice da folha: o que está escolhido em cada parte, numa frase, e se a
   parte está diferente do padrão (ponto violeta). Só leitura do estado. */
function indiceDasRegras(r: {
  precoModo: ModoDePreco;
  precoTexto: string;
  precoLogin: string;
  precoAviso: string;
  compraModo: ModoDeCompra;
  botaoDoProduto: string;
  botaoDeFechar: string;
  abrirWhatsapp: boolean;
  acessoModo: ModoDeAcesso;
  cadastroModo: ModoDeCadastro;
  soCnpj: boolean;
  mensagemDeLogin: string;
  loginParaFechar: boolean;
  minimoReais: number;
  minimoUnidades: number;
  estoque: EstoqueNaLoja;
  esgotado: ProdutoEsgotado;
  avaliacoes: boolean;
  sku: boolean;
  prazo: boolean;
  situacao: SituacaoDaLoja;
  recado: string;
  voltaEm: string;
}): ItemDoIndice[] {
  const preco: Record<ModoDePreco, string> = {
    public: "Todos veem os preços",
    hidden: `Ninguém vê · "${r.precoTexto.trim() || "Sob consulta"}"`,
    clients: "Só quem entrou na conta",
  };
  const compra: Record<ModoDeCompra, string> = { cart: "Carrinho", quote: "Pedido de orçamento", whatsapp: "Pelo WhatsApp", showcase: "Só vitrine" };
  const cadastro: Record<ModoDeCadastro, string> = { open: "cadastro livre", approval: "cadastro com aprovação", closed: "cadastro fechado" };
  const situacao: Record<SituacaoDaLoja, string> = { open: "Aberta", paused: "Em pausa", closed: "Fechada" };
  const reais = r.minimoReais > 0 ? r.minimoReais.toLocaleString("pt-BR", { style: "currency", currency: "BRL" }) : null;
  const minimo = reais
    ? `Mínimo ${reais}${r.minimoUnidades > 0 ? ` ou ${r.minimoUnidades} un.` : ""}`
    : r.minimoUnidades > 0
      ? `Mínimo ${r.minimoUnidades} un.`
      : "Sem pedido mínimo";
  const volta = r.voltaEm && r.situacao !== "open" ? ` até ${r.voltaEm.slice(8, 10)}/${r.voltaEm.slice(5, 7)}` : "";
  return [
    {
      id: "regras-precos",
      titulo: "Preços",
      Icone: BadgeDollarSign,
      resumo: preco[r.precoModo],
      mexido: r.precoModo !== "public" || Boolean(r.precoTexto.trim() || r.precoLogin.trim() || r.precoAviso.trim()),
    },
    {
      id: "regras-fechamento",
      titulo: "Como o cliente fecha",
      Icone: ShoppingCart,
      resumo: r.botaoDoProduto.trim() ? `${compra[r.compraModo]} · "${r.botaoDoProduto.trim()}"` : compra[r.compraModo],
      mexido: r.compraModo !== "cart" || Boolean(r.botaoDoProduto.trim() || r.botaoDeFechar.trim()) || !r.abrirWhatsapp,
    },
    {
      id: "regras-acesso",
      titulo: "Quem pode entrar",
      Icone: Lock,
      resumo: `${r.acessoModo === "clients" ? "Só clientes" : "Loja aberta"} · ${cadastro[r.cadastroModo]}`,
      mexido: r.acessoModo !== "public" || r.cadastroModo !== "open" || r.soCnpj || r.loginParaFechar || Boolean(r.mensagemDeLogin.trim()),
    },
    {
      id: "regras-venda",
      titulo: "Regras de venda",
      Icone: SlidersHorizontal,
      resumo: minimo,
      mexido:
        r.minimoReais > 0 || r.minimoUnidades > 0 || r.estoque !== "exact" || r.esgotado !== "show" || !r.avaliacoes || r.sku || !r.prazo,
    },
    {
      id: "regras-situacao",
      titulo: "Situação da loja",
      Icone: Store,
      resumo: `${situacao[r.situacao]}${volta}`,
      mexido: r.situacao !== "open" || Boolean(r.recado.trim() || r.voltaEm),
    },
    { id: "regras-whatsapp", titulo: "Mensagens do WhatsApp", Icone: MessageCircle, resumo: "Em WhatsApp > Mensagens" },
  ];
}

/* O índice da aba Personalização: o que está escolhido em cada parte. */
function indiceDaPersonalizacao(v: {
  nome: string;
  tema: string;
  mostrarNome: boolean;
  mostrarSlogan: boolean;
  whatsapp: string;
  avancada: boolean;
  corteLigado: boolean;
  corteHora: string;
  slug: string;
  dominio: string;
  dominioOnline: boolean;
  telefone: string;
}): ItemDoIndice[] {
  const temas: Record<string, string> = { default: "Padrão", neo: "Neo", vitrine: "Vitrine", vendor: "Vendor", boutique: "Ateliê" };
  const cabecalho = v.mostrarNome && v.mostrarSlogan ? "Nome e slogan" : v.mostrarNome ? "Só o nome" : v.mostrarSlogan ? "Só o slogan" : "Só a logo";
  const dominio = v.dominio.trim();
  const link = dominio ? `${dominio}${v.dominioOnline ? "" : " · aguardando DNS"}` : v.slug.trim() ? `ktalogu.com/${v.slug.trim()}` : "Sem link ainda";
  return [
    { id: "visual-identidade", titulo: "Identidade visual", Icone: Sparkles, resumo: v.nome.trim() || "Sem nome ainda" },
    { id: "visual-template", titulo: "Template da loja", Icone: LayoutTemplate, resumo: temas[v.tema] ?? v.tema },
    { id: "visual-cabecalho", titulo: "Cabeçalho e cores", Icone: PanelTop, resumo: cabecalho },
    { id: "visual-whatsapp", titulo: "WhatsApp na loja", Icone: MessageCircle, resumo: v.whatsapp.trim() || "Sem número" },
    { id: "visual-avancada", titulo: "Personalização avançada", Icone: Wand2, resumo: v.avancada ? "Ligada" : "Desligada" },
    { id: "visual-corte", titulo: "Corte de produção", Icone: Timer, resumo: v.corteLigado ? `Até ${v.corteHora}` : "Sem aviso na loja" },
    { id: "visual-chats", titulo: "Chats na loja", Icone: MessagesSquare, resumo: "Balão de conversa na vitrine" },
    { id: "visual-link", titulo: "Link do catálogo", Icone: Globe, resumo: link },
    { id: "visual-rodape", titulo: "Rodapé", Icone: Building2, resumo: v.telefone.trim() || "Endereço, contato e redes" },
  ];
}

/* O índice da aba Metadados e SEO. */
function indiceDoSeo(v: { titulo: string; imagem: string; favicon: string; indexar: boolean }): ItemDoIndice[] {
  return [
    { id: "seo-google", titulo: "Busca no Google", Icone: Globe, resumo: v.indexar ? v.titulo.trim() || "Título padrão da loja" : "Fora das buscas" },
    { id: "seo-compartilhamento", titulo: "Compartilhamento", Icone: Share2, resumo: v.imagem.trim() ? "Com imagem" : "Sem imagem ainda" },
    { id: "seo-favicon", titulo: "Aba do navegador", Icone: PanelTop, resumo: v.favicon.trim() ? "Favicon definido" : "Sem favicon" },
    { id: "seo-previa", titulo: "Prévia", Icone: Eye, resumo: "Como o link aparece" },
  ];
}

export default function CatalogSettingsPage() {
  const { pode } = usePermissoes();
  const podeMexerNoCatalogo = pode("catalog.store.write");

  type DomainDnsRecord = { type: string; host: string; value: string; host_label?: string; required?: boolean };
  const [loading, setLoading] = useState(true);
  /* O "Salvar alterações" grava o formulário inteiro. Se a leitura do perfil
     falhou, o formulário está em branco, e salvar apagaria nome, cores e logo
     da loja. */
  const [profileLoadFailed, setProfileLoadFailed] = useState(false);
  const [saving, setSaving] = useState(false);
  const [userId, setUserId] = useState<string | null>(null);
  const [slug, setSlug] = useState("");
  const [catalogName, setCatalogName] = useState("");
  const [primaryColor, setPrimaryColor] = useState("#4F46E5");
  const [catalogLogoUrl, setCatalogLogoUrl] = useState("");
  const [whatsapp, setWhatsapp] = useState(""); // WhatsApp do Catálogo
  /* O botão verde flutuante na loja: escolha da loja, e não consequência de ter
     um número cadastrado. */
  const [whatsappFloat, setWhatsappFloat] = useState(true);
  const [companyPhone, setCompanyPhone] = useState("");
  const [companyWhatsapp, setCompanyWhatsapp] = useState("");
  const [companyAddress, setCompanyAddress] = useState("");
  const [footerColor, setFooterColor] = useState("");
  const [socialFacebook, setSocialFacebook] = useState("");
  const [socialInstagram, setSocialInstagram] = useState("");
  const [socialTwitter, setSocialTwitter] = useState("");
  const [socialLinkedin, setSocialLinkedin] = useState("");
  const [socialYoutube, setSocialYoutube] = useState("");
  const [catalogSlogan, setCatalogSlogan] = useState("");
  const [catalogShowNameInHeader, setCatalogShowNameInHeader] = useState(true);
  const [catalogShowSloganInHeader, setCatalogShowSloganInHeader] = useState(true);
  const [catalogShowDocument, setCatalogShowDocument] = useState(true);
  const [catalogNameColor, setCatalogNameColor] = useState("");
  const [catalogSloganColor, setCatalogSloganColor] = useState("");
  const [catalogHeaderIconColor, setCatalogHeaderIconColor] = useState("");
  const [catalogLogoEffectEnabled, setCatalogLogoEffectEnabled] = useState(false);
  const [catalogLogoEffect, setCatalogLogoEffect] = useState<"none" | "rotate_3d" | "blink" | "pulse_glow">("none");
  const [catalogLogoEffectSpeed, setCatalogLogoEffectSpeed] = useState(100);
  const [catalogLogoEffectIntensity, setCatalogLogoEffectIntensity] = useState(100);
  const [catalogMetaTitle, setCatalogMetaTitle] = useState("");
  const [catalogMetaDescription, setCatalogMetaDescription] = useState("");
  const [catalogMetaKeywords, setCatalogMetaKeywords] = useState("");
  const [catalogOgTitle, setCatalogOgTitle] = useState("");
  const [catalogOgDescription, setCatalogOgDescription] = useState("");
  const [catalogOgImageUrl, setCatalogOgImageUrl] = useState("");
  const [catalogFaviconUrl, setCatalogFaviconUrl] = useState("");
  const [catalogTwitterHandle, setCatalogTwitterHandle] = useState("");
  const [catalogNoIndex, setCatalogNoIndex] = useState(false);
  const [catalogTheme, setCatalogTheme] = useState<"default" | "neo" | "vitrine" | "vendor" | "boutique">("default");
  /* O corte de produção é campo desta página: entra e sai pelo mesmo
     "Salvar alterações" do resto. */
  const [corteLigado, setCorteLigado] = useState(false);
  const [corteHora, setCorteHora] = useState("16:00");
  const [catalogBuybarBgColor, setCatalogBuybarBgColor] = useState("");
  const [catalogBuybarButtonColor, setCatalogBuybarButtonColor] = useState("");
  const [catalogBuybarTextColor, setCatalogBuybarTextColor] = useState("");
  const [catalogAdvancedEnabled, setCatalogAdvancedEnabled] = useState(false);
  const [catalogHeaderColor, setCatalogHeaderColor] = useState("");
  const [catalogHeaderTextColor, setCatalogHeaderTextColor] = useState("");
  const [catalogMenuColor, setCatalogMenuColor] = useState("");
  const [catalogMenuTextColor, setCatalogMenuTextColor] = useState("");
  const [catalogPageBgColor, setCatalogPageBgColor] = useState("");
  const [catalogCardButtonColor, setCatalogCardButtonColor] = useState("");
  const [catalogFontHeading, setCatalogFontHeading] = useState("");
  const [catalogFontBody, setCatalogFontBody] = useState("");
  const [catalogVitrineProductLayout, setCatalogVitrineProductLayout] = useState<"mosaic" | "standard">("mosaic");
  const isVitrineTheme = catalogTheme === "vitrine";
  const [activeTab, setActiveTab] = useState<"visual" | "rules" | "logistics" | "seo">("visual");
  /* Regras da loja (migration 159). Cada estado nasce no valor que reproduz
     o comportamento de hoje: quem não mexer na aba não muda nada. */
  const [catalogPriceMode, setCatalogPriceMode] = useState<ModoDePreco>("public");
  const [catalogPriceHiddenText, setCatalogPriceHiddenText] = useState("");
  const [catalogPriceLoginText, setCatalogPriceLoginText] = useState("");
  const [catalogPriceNotice, setCatalogPriceNotice] = useState("");
  const [catalogPurchaseMode, setCatalogPurchaseMode] = useState<ModoDeCompra>("cart");
  const [catalogCtaLabel, setCatalogCtaLabel] = useState("");
  const [catalogCheckoutLabel, setCatalogCheckoutLabel] = useState("");
  const [catalogQuoteOpenWhatsapp, setCatalogQuoteOpenWhatsapp] = useState(true);
  const [catalogAccessMode, setCatalogAccessMode] = useState<ModoDeAcesso>("public");
  const [catalogSignupMode, setCatalogSignupMode] = useState<ModoDeCadastro>("open");
  const [catalogSignupRequireCnpj, setCatalogSignupRequireCnpj] = useState(false);
  const [catalogLoginMessage, setCatalogLoginMessage] = useState("");
  const [catalogRequireLoginToOrder, setCatalogRequireLoginToOrder] = useState(false);
  /* Zero = sem mínimo (grava NULL). */
  const [catalogMinOrderTotal, setCatalogMinOrderTotal] = useState(0);
  const [catalogMinOrderItems, setCatalogMinOrderItems] = useState(0);
  const [catalogStockDisplay, setCatalogStockDisplay] = useState<EstoqueNaLoja>("exact");
  const [catalogLowStockThreshold, setCatalogLowStockThreshold] = useState(5);
  const [catalogSoldOutMode, setCatalogSoldOutMode] = useState<ProdutoEsgotado>("show");
  const [catalogReviewsEnabled, setCatalogReviewsEnabled] = useState(true);
  const [catalogShowSku, setCatalogShowSku] = useState(false);
  const [catalogShowProductionTime, setCatalogShowProductionTime] = useState(true);
  const [catalogStatus, setCatalogStatus] = useState<SituacaoDaLoja>("open");
  const [catalogStatusMessage, setCatalogStatusMessage] = useState("");
  const [catalogStatusUntil, setCatalogStatusUntil] = useState("");
  const [companyAddressFields, setCompanyAddressFields] = useState<CompanyAddress>({
    zip: "",
    street: "",
    number: "",
    complement: "",
    neighborhood: "",
    city: "",
    state: "",
  });
  
  const [originalSlug, setOriginalSlug] = useState("");
  const [canEditPublicIdentity, setCanEditPublicIdentity] = useState(true);
  const [message, setMessage] = useState<{ type: 'success' | 'error', text: string } | null>(null);
  const [copied, setCopied] = useState(false);
  const [slugStatus, setSlugStatus] = useState<"idle" | "checking" | "available" | "taken" | "error">("idle");
  const [slugStatusText, setSlugStatusText] = useState("");
  const [customDomain, setCustomDomain] = useState("");
  const [customDomainVerified, setCustomDomainVerified] = useState(false);
  const [customDomainToken, setCustomDomainToken] = useState("");
  const [customDomainMode, setCustomDomainMode] = useState<"legacy" | "cloudflare">("legacy");
  const [customDomainKind, setCustomDomainKind] = useState<"root" | "subdomain">("subdomain");
  const [customDomainRequiresApexSupport, setCustomDomainRequiresApexSupport] = useState(false);
  const [customDomainHostnameStatus, setCustomDomainHostnameStatus] = useState("");
  const [customDomainSslStatus, setCustomDomainSslStatus] = useState("");
  const [customDomainDnsRecords, setCustomDomainDnsRecords] = useState<DomainDnsRecord[]>([]);
  const [copiedDnsKey, setCopiedDnsKey] = useState<string | null>(null);
  const [customDomainSaving, setCustomDomainSaving] = useState(false);
  const [customDomainVerifying, setCustomDomainVerifying] = useState(false);
  const [customDomainDeleting, setCustomDomainDeleting] = useState(false);
  const origin = typeof window !== "undefined" ? window.location.origin : "https://ktalogu.com.br";

  const fetchProfile = useCallback(async () => {
    try {
      const supabase = getSupabaseClient();
      const { data: { user } } = await supabase.auth.getUser();

      if (!user) return;

      /*
        A identidade visual do catalogo mora no perfil do dono. Um funcionario
        tem linha propria e vazia, entao carregar por `user.id` trazia logo,
        nome da loja, slogan, cores e template todos em branco. So o slug era
        corrigido depois, pela API de dominio, e o resto ficava vazio.
      */
      const ctx = await getCompanyContext(supabase, user);
      const profileId = resolveCompanyPublicProfileId(ctx, user.id);
      setUserId(profileId);

      const { data, error } = await supabase
        .from('profiles')
        .select('*')
        .eq('id', profileId)
        .single();

      if (error && error.code !== 'PGRST116') throw error;

      if (data) {
        setSlug(data.slug || "");
        setOriginalSlug(data.slug || "");
        setPrimaryColor(data.primary_color || "#4F46E5");
        setCatalogLogoUrl(data.catalog_logo_url || data.logo_url || "");
        setWhatsapp(data.whatsapp || "");
        setWhatsappFloat(data.catalog_whatsapp_float !== false);
        setCatalogName(data.catalog_name || data.store_name || "");
        setCompanyPhone(data.company_phone || data.phone || "");
        setCompanyWhatsapp(data.company_whatsapp || "");
        setCompanyAddress(data.address || "");
        setFooterColor(data.catalog_footer_color || "");
        setSocialFacebook(data.social_facebook || "");
        setSocialInstagram(data.social_instagram || "");
        setSocialTwitter(data.social_twitter || "");
        setSocialLinkedin(data.social_linkedin || "");
        setSocialYoutube(data.social_youtube || "");
        setCatalogSlogan(data.catalog_slogan || "");
        setCatalogShowNameInHeader(data.catalog_show_name_in_header === false ? false : true);
        setCatalogShowSloganInHeader(data.catalog_show_slogan_in_header === false ? false : true);
        setCatalogShowDocument(data.catalog_show_document === false ? false : true);
        setCatalogNameColor(data.catalog_name_color || "");
        setCatalogSloganColor(data.catalog_slogan_color || "");
        setCatalogHeaderIconColor(data.catalog_header_icon_color || "");
        setCatalogLogoEffectEnabled(Boolean(data.catalog_logo_effect_enabled));
        setCatalogLogoEffect(
          data.catalog_logo_effect === "rotate_3d" ||
            data.catalog_logo_effect === "blink" ||
            data.catalog_logo_effect === "pulse_glow"
            ? data.catalog_logo_effect
            : "none"
        );
        const speedValue = Number(data.catalog_logo_effect_speed);
        const intensityValue = Number(data.catalog_logo_effect_intensity);
        setCatalogLogoEffectSpeed(Number.isFinite(speedValue) ? Math.min(200, Math.max(50, Math.round(speedValue))) : 100);
        setCatalogLogoEffectIntensity(Number.isFinite(intensityValue) ? Math.min(180, Math.max(40, Math.round(intensityValue))) : 100);
        setCatalogMetaTitle(data.catalog_meta_title || "");
        setCatalogMetaDescription(data.catalog_meta_description || "");
        setCatalogMetaKeywords(data.catalog_meta_keywords || "");
        setCatalogOgTitle(data.catalog_og_title || "");
        setCatalogOgDescription(data.catalog_og_description || "");
        setCatalogOgImageUrl(data.catalog_og_image_url || "");
        setCatalogFaviconUrl(data.catalog_favicon_url || "");
        setCatalogTwitterHandle(data.catalog_twitter_handle || "");
        setCatalogNoIndex(Boolean(data.catalog_noindex));
        setCatalogTheme(
          data.catalog_theme === "neo" ||
          data.catalog_theme === "vitrine" ||
          data.catalog_theme === "vendor" ||
          data.catalog_theme === "boutique"
            ? data.catalog_theme
            : "default"
        );
        setCorteLigado(data.production_cutoff_enabled === true);
        setCorteHora(
          typeof data.production_cutoff_time === "string" && data.production_cutoff_time
            ? data.production_cutoff_time
            : "16:00"
        );
        setCatalogVitrineProductLayout(
          data.catalog_vitrine_product_layout === "standard" ? "standard" : "mosaic"
        );
        setCatalogBuybarBgColor(data.catalog_buybar_bg_color || "");
        setCatalogBuybarButtonColor(data.catalog_buybar_button_color || "");
        setCatalogBuybarTextColor(data.catalog_buybar_text_color || "");
        setCatalogAdvancedEnabled(data.catalog_advanced_enabled === true);
        setCatalogHeaderColor(data.catalog_header_color || "");
        setCatalogHeaderTextColor(data.catalog_header_text_color || "");
        setCatalogMenuColor(data.catalog_menu_color || "");
        setCatalogMenuTextColor(data.catalog_menu_text_color || "");
        setCatalogPageBgColor(data.catalog_page_bg_color || "");
        setCatalogCardButtonColor(data.catalog_card_button_color || "");
        setCatalogFontHeading(data.catalog_font_heading || "");
        setCatalogFontBody(data.catalog_font_body || "");
        /* Regras da loja: valor fora da lista vira o padrão, como no banco. */
        setCatalogPriceMode(
          data.catalog_price_mode === "hidden" || data.catalog_price_mode === "clients" ? data.catalog_price_mode : "public"
        );
        setCatalogPriceHiddenText(data.catalog_price_hidden_text || "");
        setCatalogPriceLoginText(data.catalog_price_login_text || "");
        setCatalogPriceNotice(data.catalog_price_notice || "");
        setCatalogPurchaseMode(
          data.catalog_purchase_mode === "quote" ||
            data.catalog_purchase_mode === "whatsapp" ||
            data.catalog_purchase_mode === "showcase"
            ? data.catalog_purchase_mode
            : "cart"
        );
        setCatalogCtaLabel(data.catalog_cta_label || "");
        setCatalogCheckoutLabel(data.catalog_checkout_label || "");
        setCatalogQuoteOpenWhatsapp(data.catalog_quote_open_whatsapp !== false);
        setCatalogAccessMode(data.catalog_access_mode === "clients" ? "clients" : "public");
        setCatalogSignupMode(
          data.catalog_signup_mode === "approval" || data.catalog_signup_mode === "closed" ? data.catalog_signup_mode : "open"
        );
        setCatalogSignupRequireCnpj(data.catalog_signup_require_cnpj === true);
        setCatalogLoginMessage(data.catalog_login_message || "");
        setCatalogRequireLoginToOrder(data.catalog_require_login_to_order === true);
        const minimoEmReais = Number(data.catalog_min_order_total);
        const minimoEmUnidades = Number(data.catalog_min_order_items);
        const avisoDeEstoque = Number(data.catalog_low_stock_threshold);
        setCatalogMinOrderTotal(Number.isFinite(minimoEmReais) && minimoEmReais > 0 ? minimoEmReais : 0);
        setCatalogMinOrderItems(Number.isFinite(minimoEmUnidades) && minimoEmUnidades > 0 ? Math.round(minimoEmUnidades) : 0);
        setCatalogStockDisplay(
          data.catalog_stock_display === "low_only" || data.catalog_stock_display === "never" ? data.catalog_stock_display : "exact"
        );
        setCatalogLowStockThreshold(
          data.catalog_low_stock_threshold !== null && Number.isFinite(avisoDeEstoque) ? Math.max(0, Math.round(avisoDeEstoque)) : 5
        );
        setCatalogSoldOutMode(
          data.catalog_sold_out_mode === "hide" || data.catalog_sold_out_mode === "quote" ? data.catalog_sold_out_mode : "show"
        );
        setCatalogReviewsEnabled(data.catalog_reviews_enabled !== false);
        setCatalogShowSku(data.catalog_show_sku === true);
        setCatalogShowProductionTime(data.catalog_show_production_time !== false);
        setCatalogStatus(data.catalog_status === "paused" || data.catalog_status === "closed" ? data.catalog_status : "open");
        setCatalogStatusMessage(data.catalog_status_message || "");
        /* A data vem como "2026-10-20" (ou com hora, se o banco mudar): o
           campo de data só aceita os dez primeiros caracteres. */
        setCatalogStatusUntil(typeof data.catalog_status_until === "string" ? data.catalog_status_until.slice(0, 10) : "");
        /* Endereco estruturado da empresa: e dele que sai o balcao de retirada
           ja pre-preenchido na aba Logistica. */
        setCompanyAddressFields({
          zip: data.address_zip || "",
          street: data.address_street || "",
          number: data.address_number || "",
          complement: data.address_complement || "",
          neighborhood: data.address_neighborhood || "",
          city: data.address_city || "",
          state: data.address_state || "",
        });
      }
      const domainResponse = await fetch("/api/catalog/custom-domain", { method: "GET" });
      const domainJson = (await domainResponse.json().catch(() => null)) as
        | {
            data?: {
              profile_id?: string;
              slug?: string | null;
              can_manage?: boolean;
              domain?: string;
              verified?: boolean;
              verification_token?: string;
              verification_mode?: "legacy" | "cloudflare";
              domain_kind?: "root" | "subdomain";
              requires_provider_apex_support?: boolean;
              cloudflare_enabled?: boolean;
              cf_hostname_status?: string | null;
              cf_ssl_status?: string | null;
              dns_records?: DomainDnsRecord[];
            } | null;
          }
        | null;
      const domainData = domainJson?.data || null;
      const publicProfileId =
        typeof domainData?.profile_id === "string" && domainData.profile_id ? domainData.profile_id : user.id;
      const canManagePublicIdentity = Boolean(domainData?.can_manage);
      setUserId(publicProfileId);
      setCanEditPublicIdentity(canManagePublicIdentity && publicProfileId === user.id);
      setSlug(typeof domainData?.slug === "string" ? domainData.slug : "");
      setOriginalSlug(typeof domainData?.slug === "string" ? domainData.slug : "");
      setCustomDomain(typeof domainData?.domain === "string" ? domainData.domain : "");
      setCustomDomainVerified(Boolean(domainData?.verified));
      setCustomDomainToken(typeof domainData?.verification_token === "string" ? domainData.verification_token : "");
      setCustomDomainMode(domainData?.verification_mode === "cloudflare" ? "cloudflare" : "legacy");
      setCustomDomainKind(domainData?.domain_kind === "root" ? "root" : "subdomain");
      setCustomDomainRequiresApexSupport(Boolean(domainData?.requires_provider_apex_support));
      setCustomDomainHostnameStatus(String(domainData?.cf_hostname_status || ""));
      setCustomDomainSslStatus(String(domainData?.cf_ssl_status || ""));
      setCustomDomainDnsRecords(Array.isArray(domainData?.dns_records) ? domainData.dns_records : []);
      setProfileLoadFailed(false);
    } catch (error) {
      console.error('Error fetching profile:', error);
      setProfileLoadFailed(true);
      setMessage({ type: 'error', text: 'Erro ao carregar dados.' });
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchProfile();
  }, [fetchProfile]);

  /* A prévia das fontes no seletor vem do Google pelo navegador, e não pelo
     build (ver lib/catalog-fonts). A folha entra uma vez só, sem segurar a
     tela: enquanto não chega, cada nome aparece na fonte de reserva. */
  useEffect(() => {
    const id = "ks-fontes-do-seletor";
    if (document.getElementById(id)) return;
    const link = document.createElement("link");
    link.id = id;
    link.rel = "stylesheet";
    link.href = HREF_DAS_FONTES_DO_SELETOR;
    document.head.appendChild(link);
  }, []);

  const maskPhone = (value: string) => {
    return value
      .replace(/\D/g, '')
      .replace(/^(\d{2})(\d)/, '($1) $2')
      .replace(/(\d)(\d{4})$/, '$1-$2')
      .slice(0, 15);
  };

  const normalizeSlug = (value: string) =>
    value
      .toLowerCase()
      .replace(/[^a-z0-9-]/g, '-')
      .replace(/-+/g, '-')
      .replace(/^-|-$/g, '');

  useEffect(() => {
    if (!canEditPublicIdentity) {
      setSlugStatus("idle");
      setSlugStatusText(originalSlug ? "Link público gerenciado pela conta principal da empresa." : "");
      return;
    }
    if (!userId) return;
    const cleanSlug = normalizeSlug(slug);
    if (!cleanSlug) {
      setSlugStatus("idle");
      setSlugStatusText("");
      return;
    }
    if (cleanSlug.length < 3) {
      setSlugStatus("error");
      setSlugStatusText("O link precisa ter pelo menos 3 caracteres.");
      return;
    }
    if (cleanSlug === originalSlug) {
      setSlugStatus("available");
      setSlugStatusText("Este link já é seu.");
      return;
    }
    setSlugStatus("checking");
    setSlugStatusText("Verificando disponibilidade...");
    const timer = window.setTimeout(async () => {
      try {
        const supabase = getSupabaseClient();
        const { data } = await supabase
          .from("profiles")
          .select("id")
          .eq("slug", cleanSlug)
          .neq("id", userId)
          .limit(1);
        if (data && data.length > 0) {
          setSlugStatus("taken");
          setSlugStatusText("Este link já está em uso.");
          return;
        }
        setSlugStatus("available");
        setSlugStatusText("Link disponível.");
      } catch {
        setSlugStatus("error");
        setSlugStatusText("Não foi possível verificar agora.");
      }
    }, 350);
    return () => window.clearTimeout(timer);
  }, [canEditPublicIdentity, originalSlug, slug, userId]);

  async function handleSave(e: React.FormEvent) {
    e.preventDefault();
    if (profileLoadFailed) {
      setMessage({ type: 'error', text: 'Os dados da loja não carregaram. Recarregue a página antes de salvar, para não gravar o formulário em branco.' });
      return;
    }
    setSaving(true);
    setMessage(null);

    const cleanSlug = normalizeSlug(slug);
    
    if (canEditPublicIdentity && cleanSlug.length < 3) {
      setMessage({ type: 'error', text: 'O link da loja deve ter pelo menos 3 caracteres.' });
      setSaving(false);
      return;
    }
    if (canEditPublicIdentity && (slugStatus === "taken" || slugStatus === "checking")) {
      setMessage({ type: 'error', text: 'Escolha um link disponível para continuar.' });
      setSaving(false);
      return;
    }

    try {
      const supabase = getSupabaseClient();
      const { data: { user } } = await supabase.auth.getUser();

      if (!user) throw new Error("Usuário não autenticado");

      /*
        A aparência da loja mora no perfil do DONO, que é de onde esta tela
        lê (fetchProfile). Gravar em `user.id` fazia o funcionário salvar na
        própria linha: a tela dizia "salvo", a loja não mudava e, ao
        recarregar, o tema antigo voltava.
      */
      const profileId = userId || user.id;

      if (canEditPublicIdentity && cleanSlug !== originalSlug) {
        const { data: existing } = await supabase
          .from('profiles')
          .select('id')
          .eq('slug', cleanSlug)
          .neq('id', profileId) // Exclude current profile
          .single();

        if (existing) {
          setMessage({ type: 'error', text: 'Este link já está em uso. Escolha outro.' });
          setSaving(false);
          return;
        }
      }

      const normalizedCatalogName = catalogName.trim();
      const normalizedCatalogLogoUrl = catalogLogoUrl.trim();
      const normalizedCompanyAddress = companyAddress.trim();
      const normalizedFooterColor = footerColor.trim();
      const normalizedSocialFacebook = socialFacebook.trim();
      const normalizedSocialInstagram = socialInstagram.trim();
      const normalizedSocialTwitter = socialTwitter.trim();
      const normalizedSocialLinkedin = socialLinkedin.trim();
      const normalizedSocialYoutube = socialYoutube.trim();
      const normalizedCatalogSlogan = catalogSlogan.trim();
      const normalizedCatalogNameColor = catalogNameColor.trim();
      const normalizedCatalogSloganColor = catalogSloganColor.trim();
      const normalizedCatalogHeaderIconColor = catalogHeaderIconColor.trim();
      const normalizedCatalogLogoEffect = catalogLogoEffect === "rotate_3d" || catalogLogoEffect === "blink" || catalogLogoEffect === "pulse_glow" ? catalogLogoEffect : "none";
      const normalizedCatalogLogoEffectSpeed = Math.min(200, Math.max(50, Math.round(Number(catalogLogoEffectSpeed) || 100)));
      const normalizedCatalogLogoEffectIntensity = Math.min(180, Math.max(40, Math.round(Number(catalogLogoEffectIntensity) || 100)));
      const normalizedCatalogMetaTitle = catalogMetaTitle.trim();
      const normalizedCatalogMetaDescription = catalogMetaDescription.trim();
      const normalizedCatalogMetaKeywords = catalogMetaKeywords.trim();
      const normalizedCatalogOgTitle = catalogOgTitle.trim();
      const normalizedCatalogOgDescription = catalogOgDescription.trim();
      const normalizedCatalogOgImageUrl = catalogOgImageUrl.trim();
      const normalizedCatalogFaviconUrl = catalogFaviconUrl.trim();
      const normalizedCatalogTwitterHandle = catalogTwitterHandle.trim();
      /* Tema que não estiver nesta lista grava "default": todo modelo novo
         entra aqui também. */
      const normalizedCatalogTheme =
        catalogTheme === "neo" || catalogTheme === "vitrine" || catalogTheme === "vendor" || catalogTheme === "boutique"
          ? catalogTheme
          : "default";
      const normalizedCatalogVitrineProductLayout =
        catalogVitrineProductLayout === "standard" ? "standard" : "mosaic";

      const updates: Record<string, unknown> = {
        id: profileId,
        primary_color: primaryColor,
        catalog_logo_url: normalizedCatalogLogoUrl || null,
        whatsapp: whatsapp,
        catalog_whatsapp_float: whatsappFloat,
        catalog_name: normalizedCatalogName || null,
        company_phone: companyPhone || null,
        company_whatsapp: companyWhatsapp || null,
        address: normalizedCompanyAddress || null,
        catalog_footer_color: normalizedFooterColor || null,
        social_facebook: normalizedSocialFacebook || null,
        social_instagram: normalizedSocialInstagram || null,
        social_twitter: normalizedSocialTwitter || null,
        social_linkedin: normalizedSocialLinkedin || null,
        social_youtube: normalizedSocialYoutube || null,
        catalog_slogan: normalizedCatalogSlogan || null,
        catalog_show_name_in_header: catalogShowNameInHeader,
        catalog_show_slogan_in_header: catalogShowSloganInHeader,
        catalog_show_document: catalogShowDocument,
        catalog_name_color: normalizedCatalogNameColor || null,
        catalog_slogan_color: normalizedCatalogSloganColor || null,
        catalog_header_icon_color: normalizedCatalogHeaderIconColor || null,
        catalog_logo_effect_enabled: catalogLogoEffectEnabled,
        catalog_logo_effect: catalogLogoEffectEnabled ? normalizedCatalogLogoEffect : "none",
        catalog_logo_effect_speed: catalogLogoEffectEnabled ? normalizedCatalogLogoEffectSpeed : 100,
        catalog_logo_effect_intensity: catalogLogoEffectEnabled ? normalizedCatalogLogoEffectIntensity : 100,
        catalog_meta_title: normalizedCatalogMetaTitle || null,
        catalog_meta_description: normalizedCatalogMetaDescription || null,
        catalog_meta_keywords: normalizedCatalogMetaKeywords || null,
        catalog_og_title: normalizedCatalogOgTitle || null,
        catalog_og_description: normalizedCatalogOgDescription || null,
        catalog_og_image_url: normalizedCatalogOgImageUrl || null,
        catalog_favicon_url: normalizedCatalogFaviconUrl || null,
        catalog_twitter_handle: normalizedCatalogTwitterHandle || null,
        catalog_noindex: catalogNoIndex,
        catalog_theme: normalizedCatalogTheme,
        production_cutoff_enabled: corteLigado,
        production_cutoff_time: corteLigado ? corteHora : null,
        catalog_vitrine_product_layout: normalizedCatalogVitrineProductLayout,
        /* Vazio grava NULL: e assim que a vitrine sabe que deve calcular a cor
           sozinha em vez de usar uma escolhida. */
        catalog_buybar_bg_color: catalogBuybarBgColor.trim() || null,
        catalog_buybar_button_color: catalogBuybarButtonColor.trim() || null,
        catalog_buybar_text_color: catalogBuybarTextColor.trim() || null,
        /* A chave e gravada mesmo desligada: desligar precisa voltar a loja ao
           padrao SEM apagar as escolhas, para o lojista poder religar depois. */
        catalog_advanced_enabled: catalogAdvancedEnabled,
        catalog_header_color: catalogHeaderColor.trim() || null,
        catalog_header_text_color: catalogHeaderTextColor.trim() || null,
        catalog_menu_color: catalogMenuColor.trim() || null,
        catalog_menu_text_color: catalogMenuTextColor.trim() || null,
        catalog_page_bg_color: catalogPageBgColor.trim() || null,
        catalog_card_button_color: catalogCardButtonColor.trim() || null,
        catalog_font_heading: catalogFontHeading.trim() || null,
        catalog_font_body: catalogFontBody.trim() || null,
        /* Regras da loja (migration 159). Texto vazio e número vazio gravam
           NULL: é assim que a loja sabe que deve usar o padrão dela. */
        catalog_price_mode: catalogPriceMode,
        catalog_price_hidden_text: catalogPriceHiddenText.trim() || null,
        catalog_price_login_text: catalogPriceLoginText.trim() || null,
        catalog_price_notice: catalogPriceNotice.trim() || null,
        catalog_purchase_mode: catalogPurchaseMode,
        catalog_cta_label: catalogCtaLabel.trim() || null,
        catalog_checkout_label: catalogCheckoutLabel.trim() || null,
        catalog_quote_open_whatsapp: catalogQuoteOpenWhatsapp,
        catalog_access_mode: catalogAccessMode,
        catalog_signup_mode: catalogSignupMode,
        catalog_signup_require_cnpj: catalogSignupRequireCnpj,
        catalog_login_message: catalogLoginMessage.trim() || null,
        catalog_require_login_to_order: catalogRequireLoginToOrder,
        catalog_min_order_total: catalogMinOrderTotal > 0 ? Number(catalogMinOrderTotal.toFixed(2)) : null,
        catalog_min_order_items: catalogMinOrderItems > 0 ? Math.round(catalogMinOrderItems) : null,
        catalog_stock_display: catalogStockDisplay,
        catalog_low_stock_threshold: Math.max(0, Math.round(catalogLowStockThreshold)),
        catalog_sold_out_mode: catalogSoldOutMode,
        catalog_reviews_enabled: catalogReviewsEnabled,
        catalog_show_sku: catalogShowSku,
        catalog_show_production_time: catalogShowProductionTime,
        catalog_status: catalogStatus,
        catalog_status_message: catalogStatusMessage.trim() || null,
        catalog_status_until: catalogStatusUntil.trim() || null,
        updated_at: new Date().toISOString(),
      };

      if (canEditPublicIdentity) {
        updates.slug = cleanSlug;
      }

      if (normalizedCatalogLogoUrl) {
        updates.catalog_logo_url = normalizedCatalogLogoUrl;
      }

      let lastError: unknown = null;
      for (let attempt = 0; attempt < 30; attempt++) {
        const { error } = await supabase.from('profiles').upsert(updates);
        if (!error) {
          lastError = null;
          break;
        }

        lastError = error;
        const errorMessage = String((error as { message?: unknown } | null)?.message ?? "");
        const match = errorMessage.match(/column ["']?([a-zA-Z0-9_]+)["']? .*does not exist/i);
        const unknownColumn = match?.[1];
        if (!unknownColumn || !(unknownColumn in updates)) break;
        delete updates[unknownColumn];
      }

      if (lastError) throw lastError;

      /* A loja guarda o retrato da vitrine por dois minutos. O "salvo" só
         aparece depois de ela esquecer o antigo, para quem abrir a loja em
         seguida já encontrar o tema novo. */
      await avisarALojaAgora();

      if (canEditPublicIdentity) {
        setSlug(cleanSlug);
        setOriginalSlug(cleanSlug);
      }
      setMessage({ type: 'success', text: 'Configurações do catálogo salvas!' });
    } catch (error) {
      console.error('Error saving profile:', error);
      const errorMessage = String((error as { message?: unknown } | null)?.message ?? 'Erro ao salvar configurações.');
      setMessage({ type: 'error', text: errorMessage });
    } finally {
      setSaving(false);
    }
  }

  const copyToClipboard = () => {
    const url = buildCurrentCatalogUrl();
    navigator.clipboard.writeText(url);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };
  const buildCurrentCatalogUrl = () => {
    const base = getPublicCatalogOrigin(origin, {
      slug: originalSlug,
      custom_domain: customDomain,
      custom_domain_verified: customDomainVerified,
    });
    if (customDomainVerified && customDomain) return base;
    return originalSlug ? `${base}/${originalSlug}` : "";
  };
  /*
    Espelha a regra da vitrine: cor vazia significa padrao, e o texto do botao
    e sempre calculado sobre a cor do botao para nao sumir num tom claro.
  */
  const buybarPreview = (() => {
    const lerLuminancia = (hex: string) => {
      const limpo = hex.replace("#", "");
      const cheio = limpo.length === 3 ? limpo.split("").map((c) => c + c).join("") : limpo;
      if (!/^[0-9a-fA-F]{6}$/.test(cheio)) return 1;
      const canal = (i: number) => {
        const v = parseInt(cheio.slice(i, i + 2), 16) / 255;
        return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
      };
      return 0.2126 * canal(0) + 0.7152 * canal(2) + 0.0722 * canal(4);
    };
    const textoLegivel = (fundo: string) => (lerLuminancia(fundo) > 0.4 ? "#111827" : "#FFFFFF");
    const bg = catalogBuybarBgColor.trim() || "#FFFFFF";
    const button = catalogBuybarButtonColor.trim() || primaryColor;
    const text = catalogBuybarTextColor.trim() || textoLegivel(bg);
    return {
      bg,
      button,
      text,
      buttonText: textoLegivel(button),
      mutedText: lerLuminancia(bg) > 0.4 ? "#6B7280" : "rgba(255,255,255,0.72)",
    };
  })();

  const publicCatalogUrl = buildCurrentCatalogUrl();
  const seoPreviewTitle = catalogOgTitle.trim() || catalogMetaTitle.trim() || catalogName.trim() || "Sua loja";
  const seoPreviewDescription =
    catalogOgDescription.trim() ||
    catalogMetaDescription.trim() ||
    "Defina uma descrição estratégica para melhorar cliques e indexação.";
  const seoPreviewImage = catalogOgImageUrl.trim() || catalogLogoUrl.trim() || "";
  const openPublicCatalog = () => {
    if (!publicCatalogUrl) return;
    window.open(publicCatalogUrl, "_blank", "noopener,noreferrer");
  };

  const copyDnsField = async (value: string, key: string) => {
    if (!value) return;
    await navigator.clipboard.writeText(value);
    setCopiedDnsKey(key);
    setTimeout(() => setCopiedDnsKey(null), 1300);
  };

  const toFriendlyStatus = (value: string) => {
    const normalized = String(value || "").trim().toLowerCase();
    if (!normalized) return "Aguardando configuração";
    if (normalized === "active" || normalized === "verified") return "Online";
    if (normalized.includes("pending") || normalized.includes("initial")) return "Pendente";
    if (normalized.includes("error") || normalized.includes("failed")) return "Atenção";
    return "Em análise";
  };

  const getStatusBadgeClass = (value: string) => {
    const normalized = String(value || "").trim().toLowerCase();
    if (normalized === "active" || normalized === "verified") {
      return "bg-emerald-50 text-emerald-700 border-emerald-200";
    }
    if (normalized.includes("pending") || normalized.includes("initial")) {
      return "bg-red-50 text-red-700 border-red-200";
    }
    if (normalized.includes("error") || normalized.includes("failed")) {
      return "bg-red-50 text-red-700 border-red-200";
    }
    return "bg-amber-50 text-amber-700 border-amber-200";
  };

  const formatDnsEntryName = (record: DomainDnsRecord) => {
    const fullHost = String(record.host_label || record.host || "").trim();
    const domain = String(customDomain || "").trim().toLowerCase();
    if (!fullHost) return fullHost;
    if (customDomainKind === "subdomain") {
      const [subdomainLabel] = domain.split(".");
      if (record.type === "CNAME" && fullHost === domain) {
        return subdomainLabel || fullHost;
      }
      if (record.type === "TXT" && subdomainLabel) {
        if (fullHost === `_cf-custom-hostname.${domain}`) {
          return `_cf-custom-hostname.${subdomainLabel}`;
        }
        if (fullHost === `_acme-challenge.${domain}`) {
          return `_acme-challenge.${subdomainLabel}`;
        }
      }
    }
    if (!domain) return fullHost;
    if (fullHost === domain) return "@";
    const suffix = `.${domain}`;
    if (!fullHost.endsWith(suffix)) return fullHost;
    return fullHost.slice(0, -suffix.length) || "@";
  };

  const syncCustomDomainStatus = useCallback(
    async (silent = true) => {
      if (!customDomain.trim()) return;
      try {
        const res = await fetch("/api/catalog/custom-domain/verify", { method: "POST" });
        const json = (await res.json().catch(() => null)) as
          | {
              error?: string;
              data?: {
                verified?: boolean;
                verification_mode?: "legacy" | "cloudflare";
                domain_kind?: "root" | "subdomain";
                requires_provider_apex_support?: boolean;
                cf_hostname_status?: string | null;
                cf_ssl_status?: string | null;
              };
            }
          | null;
        if (!res.ok) throw new Error(json?.error || "Não foi possível verificar o domínio.");
        setCustomDomainVerified(Boolean(json?.data?.verified));
        setCustomDomainMode(json?.data?.verification_mode === "cloudflare" ? "cloudflare" : customDomainMode);
        if (json?.data?.domain_kind) setCustomDomainKind(json.data.domain_kind);
        if (typeof json?.data?.requires_provider_apex_support === "boolean") {
          setCustomDomainRequiresApexSupport(json.data.requires_provider_apex_support);
        }
        setCustomDomainHostnameStatus(String(json?.data?.cf_hostname_status || customDomainHostnameStatus));
        setCustomDomainSslStatus(String(json?.data?.cf_ssl_status || customDomainSslStatus));
        if (!silent) setMessage({ type: "success", text: "Tudo certo. Seu domínio foi atualizado." });
      } catch (error) {
        if (!silent) {
          const errorMessage = error instanceof Error ? error.message : "Erro ao validar domínio.";
          setMessage({ type: "error", text: errorMessage });
        }
      }
    },
    [customDomain, customDomainMode, customDomainHostnameStatus, customDomainSslStatus]
  );

  useEffect(() => {
    if (!customDomain.trim()) return;
    if (customDomainVerified) return;
    const timer = window.setInterval(() => {
      void syncCustomDomainStatus(true);
    }, 25000);
    return () => window.clearInterval(timer);
  }, [customDomain, customDomainVerified, syncCustomDomainStatus]);

  async function handleSaveCustomDomain() {
    setCustomDomainSaving(true);
    setMessage(null);
    try {
      const res = await fetch("/api/catalog/custom-domain", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ domain: customDomain }),
      });
      const json = (await res.json().catch(() => null)) as
        | {
            error?: string;
            data?: {
              domain?: string;
              verification_token?: string;
              verified?: boolean;
              verification_mode?: "legacy" | "cloudflare";
              domain_kind?: "root" | "subdomain";
              requires_provider_apex_support?: boolean;
              cf_hostname_status?: string | null;
              cf_ssl_status?: string | null;
              dns_records?: DomainDnsRecord[];
            };
          }
        | null;
      if (!res.ok) throw new Error(json?.error || "Não foi possível salvar o domínio.");
      const nextDomain = String(json?.data?.domain || customDomain).trim().toLowerCase();
      setCustomDomain(nextDomain);
      setCustomDomainVerified(Boolean(json?.data?.verified));
      setCustomDomainToken(String(json?.data?.verification_token || ""));
      setCustomDomainMode(json?.data?.verification_mode === "cloudflare" ? "cloudflare" : "legacy");
      setCustomDomainKind(json?.data?.domain_kind === "root" ? "root" : "subdomain");
      setCustomDomainRequiresApexSupport(Boolean(json?.data?.requires_provider_apex_support));
      setCustomDomainHostnameStatus(String(json?.data?.cf_hostname_status || ""));
      setCustomDomainSslStatus(String(json?.data?.cf_ssl_status || ""));
      setCustomDomainDnsRecords(Array.isArray(json?.data?.dns_records) ? json.data.dns_records : []);
      setMessage({
        type: "success",
        text:
          json?.data?.verification_mode === "cloudflare"
            ? "Domínio salvo. Configure os registros DNS e depois valide."
            : "Domínio salvo. Configure o TXT e depois valide.",
      });
      window.setTimeout(() => {
        window.location.reload();
      }, 350);
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Erro ao salvar domínio.";
      setMessage({ type: "error", text: errorMessage });
    } finally {
      setCustomDomainSaving(false);
    }
  }

  async function handleVerifyCustomDomain() {
    setCustomDomainVerifying(true);
    setMessage(null);
    try {
      await syncCustomDomainStatus(false);
    } finally {
      setCustomDomainVerifying(false);
    }
  }

  async function handleRemoveCustomDomain() {
    setCustomDomainDeleting(true);
    setMessage(null);
    try {
      const res = await fetch("/api/catalog/custom-domain", { method: "DELETE" });
      const json = (await res.json().catch(() => null)) as { error?: string } | null;
      if (!res.ok) throw new Error(json?.error || "Não foi possível remover o domínio.");
      setCustomDomain("");
      setCustomDomainToken("");
      setCustomDomainVerified(false);
      setCustomDomainKind("subdomain");
      setCustomDomainRequiresApexSupport(false);
      setCustomDomainHostnameStatus("");
      setCustomDomainSslStatus("");
      setCustomDomainDnsRecords([]);
      setMessage({ type: "success", text: "Domínio customizado removido." });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : "Erro ao remover domínio.";
      setMessage({ type: "error", text: errorMessage });
    } finally {
      setCustomDomainDeleting(false);
    }
  }

  if (loading) {
    return (
      <div className="ks-surface flex items-center justify-center min-h-[50vh]">
        <Loader2 className="w-8 h-8 animate-spin text-[var(--ks-color-primary)]" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow="Catálogo"
        title="Personalização da vitrine"
        subtitle="Ajuste identidade visual, link público e informações de contato do catálogo."
        actions={
          <Button
            type="button"
            variant="outline"
            onClick={openPublicCatalog}
            disabled={!publicCatalogUrl}
            icon={<Eye className="w-4 h-4" />}
          >
            Prévia do catálogo
          </Button>
        }
      />

      <motion.form
        initial={{ opacity: 0, y: 20 }}
        animate={{ opacity: 1, y: 0 }}
        onSubmit={handleSave}
        className="space-y-6 max-w-full"
      >
        {/*
          Tabs com estilo sublinhado, so nesta pagina: o componente e
          compartilhado com outras 6 telas do admin, entao o restyle entra por
          className (o `cn` do projeto usa twMerge, que resolve o conflito de
          classes Tailwind corretamente) em vez de editar o componente base.
        */}
        <Tabs
          value={activeTab}
          onValueChange={(value) => setActiveTab(value as "visual" | "rules" | "logistics" | "seo")}
          className="w-full"
        >
          <TabsList className="h-auto w-full justify-start gap-1 rounded-none border-b border-[var(--ks-color-border-subtle)] bg-transparent p-0">
            <TabsTrigger
              value="visual"
              className="rounded-none border-b-2 border-transparent bg-transparent px-1 pb-3 pt-1 font-medium text-[var(--ks-color-text-soft)] shadow-none data-[state=active]:border-[var(--ks-color-primary)] data-[state=active]:bg-transparent data-[state=active]:text-[var(--ks-color-primary)] data-[state=active]:shadow-none"
            >
              Personalização
            </TabsTrigger>
            <TabsTrigger
              value="rules"
              className="rounded-none border-b-2 border-transparent bg-transparent px-1 pb-3 pt-1 ml-5 font-medium text-[var(--ks-color-text-soft)] shadow-none data-[state=active]:border-[var(--ks-color-primary)] data-[state=active]:bg-transparent data-[state=active]:text-[var(--ks-color-primary)] data-[state=active]:shadow-none"
            >
              Regras da loja
            </TabsTrigger>
            <TabsTrigger
              value="logistics"
              className="rounded-none border-b-2 border-transparent bg-transparent px-1 pb-3 pt-1 ml-5 font-medium text-[var(--ks-color-text-soft)] shadow-none data-[state=active]:border-[var(--ks-color-primary)] data-[state=active]:bg-transparent data-[state=active]:text-[var(--ks-color-primary)] data-[state=active]:shadow-none"
            >
              Logística
            </TabsTrigger>
            <TabsTrigger
              value="seo"
              className="rounded-none border-b-2 border-transparent bg-transparent px-1 pb-3 pt-1 ml-5 font-medium text-[var(--ks-color-text-soft)] shadow-none data-[state=active]:border-[var(--ks-color-primary)] data-[state=active]:bg-transparent data-[state=active]:text-[var(--ks-color-primary)] data-[state=active]:shadow-none"
            >
              Metadados e SEO
            </TabsTrigger>
          </TabsList>

          <TabsContent value="visual" className="space-y-5">
            <FolhaDeAjustes
              indice={indiceDaPersonalizacao({
                nome: catalogName,
                tema: catalogTheme,
                mostrarNome: catalogShowNameInHeader,
                mostrarSlogan: catalogShowSloganInHeader,
                whatsapp,
                avancada: catalogAdvancedEnabled,
                corteLigado,
                corteHora,
                slug,
                dominio: customDomain,
                dominioOnline: customDomainVerified,
                telefone: companyPhone,
              })}
            >
              {/* a) Identidade visual */}
              <SecaoDeAjustes
                id="visual-identidade"
                Icone={Sparkles}
                titulo="Identidade visual"
                texto="O que identifica a sua loja: a logo, o nome e o slogan."
              >
                <LinhaDeAjuste
                  titulo="Logo do catálogo"
                  texto={
                    isVitrineTheme
                      ? "Para o tema Vitrine, envie uma logo horizontal: proporção perto de 4:1, fundo transparente e pouco espaço vazio nas laterais (1200x300 ou 1600x400)."
                      : "Recomendado: imagem horizontal ou quadrada em alta resolução."
                  }
                >
                  <ImageUpload
                    bucket="products"
                    folder="logos"
                    value={catalogLogoUrl}
                    onChange={setCatalogLogoUrl}
                    enableCrop
                    cropAspect={isVitrineTheme ? 4 : 1}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogName" titulo="Nome da loja" texto="O nome do catálogo, no cabeçalho e no título da aba.">
                  <Input id="catalogName" placeholder="Ex: Minha Loja Online" value={catalogName} onChange={(e) => setCatalogName(e.target.value)} />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogSlogan" titulo="Slogan" texto="Uma frase curta embaixo do nome.">
                  <Input
                    id="catalogSlogan"
                    placeholder="Ex: Personalizados com entrega rápida"
                    value={catalogSlogan}
                    onChange={(e) => setCatalogSlogan(e.target.value)}
                  />
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* b) Template */}
              <SecaoDeAjustes
                id="visual-template"
                Icone={LayoutTemplate}
                titulo="Template da loja"
                texto="Troca só o visual do catálogo. Produtos, dados, carrinho e regras continuam iguais."
              >
                <LinhaDeAjuste largo titulo="Template">
                  <ThemeSelector value={catalogTheme} onChange={setCatalogTheme} />
                </LinhaDeAjuste>
                {isVitrineTheme ? (
                  <LinhaDeAjuste titulo="Listagem dos produtos" texto="O mosaico editorial da Vitrine ou a listagem normal com todos os cards.">
                    <EscolhaDeAjuste<"mosaic" | "standard">
                      rotulo="Listagem dos produtos"
                      valor={catalogVitrineProductLayout}
                      aoEscolher={setCatalogVitrineProductLayout}
                      opcoes={[
                        { valor: "mosaic", titulo: "Estilo mosaico", texto: "Mantém os destaques maiores e a diagramação editorial do tema Vitrine." },
                        { valor: "standard", titulo: "Listagem normal", texto: "Exibe todos os produtos com cards padrão, como no tema tradicional." },
                      ]}
                    />
                  </LinhaDeAjuste>
                ) : null}
              </SecaoDeAjustes>

              {/* c) Cabeçalho e cores */}
              <SecaoDeAjustes
                id="visual-cabecalho"
                Icone={PanelTop}
                titulo="Cabeçalho e cores"
                texto="O que aparece no topo da loja e as cores da marca."
              >
                <ChaveDeAjuste titulo="Exibir o nome no cabeçalho" ligado={catalogShowNameInHeader} aoMudar={setCatalogShowNameInHeader} />
                <ChaveDeAjuste titulo="Exibir o slogan no cabeçalho" ligado={catalogShowSloganInHeader} aoMudar={setCatalogShowSloganInHeader} />
                <ChaveDeAjuste
                  titulo="Efeito da logo"
                  texto="Uma animação discreta na logo do cabeçalho."
                  ligado={catalogLogoEffectEnabled}
                  aoMudar={setCatalogLogoEffectEnabled}
                />
                {catalogLogoEffectEnabled ? (
                  <>
                    <LinhaDeAjuste titulo="Tipo de efeito">
                      <CustomSelect
                        options={[
                          { value: "rotate_3d", label: "Rotação 3D" },
                          { value: "pulse_glow", label: "Pulse premium" },
                          { value: "blink", label: "Brilho ritmado" },
                          { value: "none", label: "Sem efeito" },
                        ]}
                        value={catalogLogoEffect}
                        onChange={(valor) =>
                          setCatalogLogoEffect(valor === "rotate_3d" || valor === "blink" || valor === "pulse_glow" ? valor : "none")
                        }
                      />
                    </LinhaDeAjuste>
                    <LinhaDeAjuste titulo="Velocidade" texto={`${catalogLogoEffectSpeed}%`}>
                      <input
                        type="range"
                        min={50}
                        max={200}
                        step={5}
                        value={catalogLogoEffectSpeed}
                        onChange={(e) => setCatalogLogoEffectSpeed(Number(e.target.value))}
                        aria-label="Velocidade do efeito"
                        className="mt-2 w-full accent-[var(--ks-color-primary)]"
                      />
                    </LinhaDeAjuste>
                    <LinhaDeAjuste titulo="Intensidade" texto={`${catalogLogoEffectIntensity}%`}>
                      <input
                        type="range"
                        min={40}
                        max={180}
                        step={5}
                        value={catalogLogoEffectIntensity}
                        onChange={(e) => setCatalogLogoEffectIntensity(Number(e.target.value))}
                        aria-label="Intensidade do efeito"
                        className="mt-2 w-full accent-[var(--ks-color-primary)]"
                      />
                    </LinhaDeAjuste>
                  </>
                ) : null}
                <LinhaDeAjuste
                  largo
                  titulo="Cores do catálogo"
                  texto="A cor principal é a base de botões, destaques e do cabeçalho. As outras seguem a principal enquanto ficam em branco."
                >
                  <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-4">
                    <ColorField
                      label="Cor principal"
                      value={primaryColor}
                      onChange={(valor) => setPrimaryColor(valor || "#4F46E5")}
                      fallback="#4F46E5"
                      allowAuto={false}
                    />
                    <ColorField label="Cor do nome" value={catalogNameColor} onChange={setCatalogNameColor} fallback={primaryColor} />
                    <ColorField label="Cor do slogan" value={catalogSloganColor} onChange={setCatalogSloganColor} fallback={primaryColor} />
                    <ColorField label="Ícones e menus" value={catalogHeaderIconColor} onChange={setCatalogHeaderIconColor} fallback={primaryColor} />
                  </div>
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* d) WhatsApp na loja */}
              <SecaoDeAjustes
                id="visual-whatsapp"
                Icone={MessageCircle}
                titulo="WhatsApp na loja"
                texto="O número que a loja usa no rodapé, na ficha do produto e no pedido."
              >
                <LinhaDeAjuste htmlFor="whatsapp" titulo="WhatsApp do catálogo">
                  <Input
                    id="whatsapp"
                    placeholder="(00) 90000-0000"
                    value={whatsapp}
                    onChange={(e) => setWhatsapp(maskPhone(e.target.value))}
                    maxLength={15}
                    icon={<MessageCircle className="h-4 w-4" />}
                  />
                </LinhaDeAjuste>
                {/*
                  O botão flutuante é escolha, e não consequência: o número serve
                  para o rodapé, a ficha e o pedido; o botão verde no canto é outra
                  decisão. Quem atende pelo Ktalogu Chats costuma querer só o balão.
                */}
                {whatsapp.trim() ? (
                  <ChaveDeAjuste
                    titulo="Mostrar o botão flutuante do WhatsApp na loja"
                    texto="Desligando, o número continua no rodapé e na ficha do produto; só some o botão verde do canto. Se você usa o Ktalogu Chats, os dois ficam lado a lado."
                    ligado={whatsappFloat}
                    aoMudar={setWhatsappFloat}
                  />
                ) : null}
              </SecaoDeAjustes>

              {/* e) Personalização avançada */}
              <SecaoDeAjustes
                id="visual-avancada"
                Icone={Wand2}
                titulo="Personalização avançada"
                texto="Cores de cabeçalho, menu, fundo, botões e a tipografia da loja. Desligada, a vitrine usa o padrão e nada aqui tem efeito; desligar devolve o visual original sem apagar o que você escolheu."
              >
                <ChaveDeAjuste titulo="Usar a personalização avançada" ligado={catalogAdvancedEnabled} aoMudar={setCatalogAdvancedEnabled} />
                <AnimatePresence initial={false}>
                  {catalogAdvancedEnabled && (
                    <motion.div
                      key="advanced-content"
                      initial={{ height: 0, opacity: 0 }}
                      animate={{ height: "auto", opacity: 1 }}
                      exit={{ height: 0, opacity: 0 }}
                      transition={{ duration: 0.22, ease: "easeInOut" }}
                      className="overflow-hidden"
                    >
                      <LinhaDeAjuste largo titulo="Cores da vitrine" texto="Em branco, cada cor segue o padrão indicado no campo.">
                        <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3">
                          {[
                            { rotulo: "Header", valor: catalogHeaderColor, set: setCatalogHeaderColor, padrao: primaryColor },
                            { rotulo: "Texto do header", valor: catalogHeaderTextColor, set: setCatalogHeaderTextColor, padrao: "#ffffff" },
                            { rotulo: "Barra do menu", valor: catalogMenuColor, set: setCatalogMenuColor, padrao: primaryColor },
                            { rotulo: "Texto do menu", valor: catalogMenuTextColor, set: setCatalogMenuTextColor, padrao: "#ffffff" },
                            { rotulo: "Fundo da página", valor: catalogPageBgColor, set: setCatalogPageBgColor, padrao: "#f9fafb" },
                            { rotulo: "Botões dos cards", valor: catalogCardButtonColor, set: setCatalogCardButtonColor, padrao: primaryColor },
                          ].map((campo) => (
                            <ColorField key={campo.rotulo} label={campo.rotulo} value={campo.valor} onChange={campo.set} fallback={campo.padrao} />
                          ))}
                        </div>
                      </LinhaDeAjuste>
                      <LinhaDeAjuste largo titulo="Tipografia" texto="Em branco, a loja usa a fonte padrão do tema.">
                        <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                          <div className="space-y-1.5">
                            <span className="block text-xs font-medium text-[var(--ks-color-text-muted)]">Fonte dos títulos</span>
                            <CustomSelect
                              options={CATALOG_FONT_SELECT_OPTIONS}
                              value={catalogFontHeading}
                              onChange={setCatalogFontHeading}
                              placeholder="Padrão da loja"
                              searchable
                            />
                          </div>
                          <div className="space-y-1.5">
                            <span className="block text-xs font-medium text-[var(--ks-color-text-muted)]">Fonte dos textos</span>
                            <CustomSelect
                              options={CATALOG_FONT_SELECT_OPTIONS}
                              value={catalogFontBody}
                              onChange={setCatalogFontBody}
                              placeholder="Padrão da loja"
                              searchable
                            />
                          </div>
                        </div>
                      </LinhaDeAjuste>
                      <LinhaDeAjuste
                        largo
                        titulo="Barra de compra"
                        texto="A barra fixa da página do produto. O texto do botão é calculado sobre a cor escolhida, para nunca sumir."
                      >
                        <div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
                          {[
                            { rotulo: "Cor da barra", valor: catalogBuybarBgColor, set: setCatalogBuybarBgColor, padrao: "#ffffff" },
                            { rotulo: "Cor do botão", valor: catalogBuybarButtonColor, set: setCatalogBuybarButtonColor, padrao: primaryColor },
                            { rotulo: "Cor dos textos", valor: catalogBuybarTextColor, set: setCatalogBuybarTextColor, padrao: "#111827" },
                          ].map((campo) => (
                            <ColorField key={campo.rotulo} label={campo.rotulo} value={campo.valor} onChange={campo.set} fallback={campo.padrao} />
                          ))}
                        </div>
                        <div
                          className="mt-3 flex items-center justify-center gap-4 rounded-2xl border border-[var(--ks-color-border-subtle)] px-4 py-3"
                          style={{ backgroundColor: buybarPreview.bg }}
                        >
                          <div className="min-w-0">
                            <div className="truncate text-sm font-medium" style={{ color: buybarPreview.text }}>
                              {catalogName.trim() || "Nome do produto"}
                            </div>
                            <div className="mt-1 flex items-center gap-3">
                              <span className="text-[11px] uppercase tracking-[0.08em]" style={{ color: buybarPreview.mutedText }}>
                                Total
                              </span>
                              <span className="text-2xl font-semibold tracking-[-0.04em]" style={{ color: buybarPreview.text }}>
                                R$ 149,90
                              </span>
                            </div>
                          </div>
                          <span
                            className="inline-flex h-11 shrink-0 items-center justify-center rounded-full px-5 text-sm font-semibold"
                            style={{ backgroundColor: buybarPreview.button, color: buybarPreview.buttonText }}
                          >
                            Comprar
                          </span>
                        </div>
                      </LinhaDeAjuste>
                    </motion.div>
                  )}
                </AnimatePresence>
              </SecaoDeAjustes>

              {/* f) A promessa de prazo e o atendimento vêm antes do endereço da
                  loja: são o que o lojista mexe com frequência. */}
              <CorteDeProducao
                ligado={corteLigado}
                hora={corteHora}
                aoMudar={({ ligado, hora }) => {
                  setCorteLigado(ligado);
                  setCorteHora(hora);
                }}
              />

              <ChatDaLojaAjuste />

              {/* g) Link do catálogo */}
              <SecaoDeAjustes
                id="visual-link"
                Icone={Globe}
                titulo="Link do catálogo"
                texto="O endereço público da loja e o domínio próprio."
              >
                {!canEditPublicIdentity ? (
                  <div className="pt-3">
                    <Aviso tom="neutro">
                      O link público desta empresa é herdado da conta principal. Nesta conta ele fica somente para consulta.
                    </Aviso>
                  </div>
                ) : null}
                <LinhaDeAjuste
                  htmlFor="slug"
                  titulo="URL personalizada"
                  texto={
                    slugStatusText ? (
                      <span
                        className={[
                          slugStatus === "available" ? "text-[var(--ks-color-success)]" : "",
                          slugStatus === "checking" ? "text-[var(--ks-color-text-muted)]" : "",
                          slugStatus === "taken" || slugStatus === "error" ? "text-red-600" : "",
                        ]
                          .filter(Boolean)
                          .join(" ")}
                      >
                        {slugStatusText}
                      </span>
                    ) : (
                      "O endereço da loja dentro do Ktalogu."
                    )
                  }
                >
                  <div className="flex items-stretch">
                    <span className="inline-flex items-center rounded-l-xl border-[1.5px] border-r-0 border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-inset)] px-3 text-sm text-[var(--ks-color-text-soft)]">
                      ktalogu.com/
                    </span>
                    <input
                      type="text"
                      id="slug"
                      value={slug}
                      onChange={(e) => setSlug(e.target.value)}
                      disabled={!canEditPublicIdentity}
                      className="ks-field"
                      style={{ borderTopLeftRadius: 0, borderBottomLeftRadius: 0 }}
                      placeholder="minha-loja"
                      required
                    />
                  </div>
                </LinhaDeAjuste>
                {originalSlug ? (
                  <LinhaDeAjuste titulo="Seu link está ativo" texto={<span className="break-all">{publicCatalogUrl}</span>}>
                    <div className="flex flex-wrap items-center gap-2 md:justify-end">
                      <Button type="button" onClick={openPublicCatalog} variant="secondary" size="sm" iconRight={<ArrowUpRight size={16} />}>
                        Abrir
                      </Button>
                      <Button
                        type="button"
                        onClick={copyToClipboard}
                        variant="secondary"
                        size="sm"
                        icon={copied ? <Check size={16} /> : <Copy size={16} />}
                      >
                        {copied ? "Copiado" : "Copiar link"}
                      </Button>
                    </div>
                  </LinhaDeAjuste>
                ) : null}
                <LinhaDeAjuste
                  htmlFor="customDomain"
                  titulo="Domínio próprio"
                  texto="Você salva o domínio, copia as entradas DNS e cola no provedor onde comprou o domínio. Depois disso a validação acontece sozinha, em alguns segundos."
                >
                  <div className="space-y-3">
                    <Input
                      id="customDomain"
                      placeholder="catalogo.sualoja.com.br"
                      value={customDomain}
                      onChange={(e) => setCustomDomain(e.target.value)}
                      disabled={!canEditPublicIdentity}
                    />
                    <div className="flex flex-wrap gap-2">
                      {podeMexerNoCatalogo && (
                        <Button
                          type="button"
                          onClick={handleSaveCustomDomain}
                          disabled={!canEditPublicIdentity || customDomainSaving || !customDomain.trim()}
                          size="sm"
                        >
                          {customDomainSaving ? "Salvando..." : "Salvar domínio"}
                        </Button>
                      )}
                      <Button
                        type="button"
                        onClick={handleVerifyCustomDomain}
                        disabled={!canEditPublicIdentity || customDomainVerifying || !customDomain.trim()}
                        variant="secondary"
                        size="sm"
                      >
                        {customDomainVerifying ? "Verificando..." : "Verificar agora"}
                      </Button>
                      <Button
                        type="button"
                        onClick={handleRemoveCustomDomain}
                        disabled={!canEditPublicIdentity || customDomainDeleting || !customDomain.trim()}
                        variant="secondary"
                        size="sm"
                      >
                        {customDomainDeleting ? "Removendo..." : "Remover"}
                      </Button>
                    </div>
                    <div className="space-y-3 text-sm text-[var(--ks-color-text-primary)]">
                      <div className="flex flex-wrap items-center gap-2">
                        <span className="inline-flex items-center rounded-full border border-[var(--ks-color-border-subtle)] px-2 py-0.5 text-[11px] text-[var(--ks-color-text-primary)]">
                          Tipo: {customDomainKind === "root" ? "Domínio raiz" : "Subdomínio"}
                        </span>
                        <span
                          className={[
                            "inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-semibold",
                            customDomainVerified
                              ? "bg-emerald-50 text-emerald-700 border-emerald-200"
                              : customDomain
                                ? "bg-red-50 text-red-700 border-red-200"
                                : "bg-[var(--ks-color-bg-subtle)] text-[var(--ks-color-text-primary)] border-[var(--ks-color-border-subtle)]",
                          ].join(" ")}
                        >
                          {customDomainVerified ? "Domínio online" : customDomain ? "Aguardando configuração DNS" : "Domínio não configurado"}
                        </span>
                      </div>
                      {customDomainMode === "cloudflare" ? (
                        <>
                          <div className="flex flex-wrap gap-2">
                            <span
                              className={["inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-semibold", getStatusBadgeClass(customDomainHostnameStatus)].join(" ")}
                            >
                              Conexão do domínio: {toFriendlyStatus(customDomainHostnameStatus)}
                            </span>
                            <span
                              className={["inline-flex items-center rounded-full border px-2 py-0.5 text-[11px] font-semibold", getStatusBadgeClass(customDomainSslStatus)].join(" ")}
                            >
                              Segurança SSL: {toFriendlyStatus(customDomainSslStatus)}
                            </span>
                          </div>
                          {customDomainRequiresApexSupport ? (
                            <Aviso tom="atencao">
                              Para domínio raiz, alguns provedores exigem suporte especial para o registro principal. Se houver erro, use
                              subdomínio.
                            </Aviso>
                          ) : null}
                          {customDomainDnsRecords.length > 0 ? (
                            <div className="space-y-2 pt-1">
                              {customDomainDnsRecords.map((record, index) => {
                                const fullHost = String(record.host_label || record.host || "").trim();
                                const hostLabel = formatDnsEntryName(record);
                                const hostKey = `host-${index}`;
                                const valueKey = `value-${index}`;
                                return (
                                  <div
                                    key={`${record.type}-${record.host}-${index}`}
                                    className="rounded-xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-inset)] px-3 py-2"
                                  >
                                    <div className="text-[11px] font-semibold uppercase tracking-wide text-[var(--ks-color-text-muted)]">
                                      {record.type} {record.required ? "obrigatório" : "opcional"}
                                    </div>
                                    <div className="mt-1 grid grid-cols-1 gap-2">
                                      <div className="flex items-center gap-2 text-sm text-[var(--ks-color-text-primary)]">
                                        <span className="font-medium">Entrada:</span>
                                        <span className="font-semibold">{hostLabel}</span>
                                        <button
                                          type="button"
                                          onClick={() => copyDnsField(hostLabel, hostKey)}
                                          className="inline-flex items-center text-[var(--ks-color-primary)] hover:opacity-80"
                                          aria-label={`Copiar entrada ${index + 1}`}
                                        >
                                          {copiedDnsKey === hostKey ? <Check size={14} /> : <Copy size={14} />}
                                        </button>
                                      </div>
                                      {record.type === "CNAME" && fullHost && fullHost !== hostLabel ? (
                                        <div className="text-xs text-[var(--ks-color-text-muted)]">
                                          Se o seu provedor pedir nome completo, use: <span className="font-semibold">{fullHost}</span>
                                        </div>
                                      ) : null}
                                      <div className="flex items-center gap-2 break-all text-sm text-[var(--ks-color-text-primary)]">
                                        <span className="font-medium">Valor:</span>
                                        <span className="font-semibold">{record.value}</span>
                                        <button
                                          type="button"
                                          onClick={() => copyDnsField(record.value, valueKey)}
                                          className="inline-flex items-center text-[var(--ks-color-primary)] hover:opacity-80"
                                          aria-label={`Copiar valor ${index + 1}`}
                                        >
                                          {copiedDnsKey === valueKey ? <Check size={14} /> : <Copy size={14} />}
                                        </button>
                                      </div>
                                    </div>
                                  </div>
                                );
                              })}
                            </div>
                          ) : null}
                        </>
                      ) : customDomain && customDomainToken ? (
                        <>
                          <p>Crie um TXT no DNS:</p>
                          <p>Host: _ktalogu-verification.{customDomain}</p>
                          <p>Valor: {customDomainToken}</p>
                        </>
                      ) : null}
                      <p className="text-xs text-[var(--ks-color-text-muted)]">Você não precisa atualizar a página: o sistema verifica sozinho.</p>
                    </div>
                  </div>
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* h) Rodapé */}
              <SecaoDeAjustes
                id="visual-rodape"
                Icone={Building2}
                titulo="Rodapé do catálogo"
                texto="Endereço, contato e redes sociais exibidos no rodapé."
              >
                <LinhaDeAjuste htmlFor="companyAddress" titulo="Endereço" texto="Aparece no rodapé do catálogo público.">
                  <div className="relative">
                    <MapPin className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-[var(--ks-color-text-soft)]" />
                    <AreaDeTexto
                      id="companyAddress"
                      value={companyAddress}
                      onChange={(e) => setCompanyAddress(e.target.value)}
                      rows={3}
                      style={{ paddingLeft: "2.5rem" }}
                      placeholder="Rua, número, bairro, cidade - UF"
                    />
                  </div>
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="companyPhone" titulo="Telefone">
                  <Input
                    id="companyPhone"
                    placeholder="(00) 0000-0000"
                    value={companyPhone}
                    onChange={(e) => setCompanyPhone(maskPhone(e.target.value))}
                    maxLength={15}
                    icon={<Phone className="h-4 w-4" />}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="companyWhatsapp" titulo="WhatsApp da empresa">
                  <Input
                    id="companyWhatsapp"
                    placeholder="(00) 90000-0000"
                    value={companyWhatsapp}
                    onChange={(e) => setCompanyWhatsapp(maskPhone(e.target.value))}
                    maxLength={15}
                    icon={<MessageCircle className="h-4 w-4" />}
                  />
                </LinhaDeAjuste>
                <ChaveDeAjuste
                  titulo="Mostrar CPF/CNPJ"
                  texto="Exibe seu documento no rodapé do catálogo para passar mais credibilidade."
                  ligado={catalogShowDocument}
                  aoMudar={setCatalogShowDocument}
                />
                <LinhaDeAjuste titulo="Cor do rodapé" texto="Sem escolha, o rodapé segue a cor principal do tema.">
                  <div className="sm:max-w-xs">
                    <ColorField label="Cor do rodapé" value={footerColor} onChange={setFooterColor} fallback={primaryColor} />
                  </div>
                </LinhaDeAjuste>
                <LinhaDeAjuste largo titulo="Redes sociais" texto="Os links viram ícones no rodapé. Em branco, o ícone não aparece.">
                  <div className="grid grid-cols-1 gap-3 md:grid-cols-2">
                    <Input
                      id="socialInstagram"
                      label="Instagram"
                      placeholder="https://instagram.com/sua_loja"
                      value={socialInstagram}
                      onChange={(e) => setSocialInstagram(e.target.value)}
                    />
                    <Input
                      id="socialFacebook"
                      label="Facebook"
                      placeholder="https://facebook.com/sua_pagina"
                      value={socialFacebook}
                      onChange={(e) => setSocialFacebook(e.target.value)}
                    />
                    <Input
                      id="socialLinkedin"
                      label="LinkedIn"
                      placeholder="https://linkedin.com/company/sua-empresa"
                      value={socialLinkedin}
                      onChange={(e) => setSocialLinkedin(e.target.value)}
                    />
                    <Input
                      id="socialYoutube"
                      label="YouTube"
                      placeholder="https://youtube.com/@seu_canal"
                      value={socialYoutube}
                      onChange={(e) => setSocialYoutube(e.target.value)}
                    />
                    <div className="md:col-span-2">
                      <Input
                        id="socialTwitter"
                        label="X (Twitter)"
                        placeholder="https://x.com/sua_conta"
                        value={socialTwitter}
                        onChange={(e) => setSocialTwitter(e.target.value)}
                      />
                    </div>
                  </div>
                </LinhaDeAjuste>
              </SecaoDeAjustes>
            </FolhaDeAjustes>
          </TabsContent>

          <TabsContent value="rules" className="space-y-5">
            <Aviso tom="neutro">Tudo aqui nasce no padrão de hoje. Só muda o que você trocar.</Aviso>

            <FolhaDeAjustes
              indice={indiceDasRegras({
                precoModo: catalogPriceMode,
                precoTexto: catalogPriceHiddenText,
                precoLogin: catalogPriceLoginText,
                precoAviso: catalogPriceNotice,
                compraModo: catalogPurchaseMode,
                botaoDoProduto: catalogCtaLabel,
                botaoDeFechar: catalogCheckoutLabel,
                abrirWhatsapp: catalogQuoteOpenWhatsapp,
                acessoModo: catalogAccessMode,
                cadastroModo: catalogSignupMode,
                soCnpj: catalogSignupRequireCnpj,
                mensagemDeLogin: catalogLoginMessage,
                loginParaFechar: catalogRequireLoginToOrder,
                minimoReais: catalogMinOrderTotal,
                minimoUnidades: catalogMinOrderItems,
                estoque: catalogStockDisplay,
                esgotado: catalogSoldOutMode,
                avaliacoes: catalogReviewsEnabled,
                sku: catalogShowSku,
                prazo: catalogShowProductionTime,
                situacao: catalogStatus,
                recado: catalogStatusMessage,
                voltaEm: catalogStatusUntil,
              })}
            >
              {/* a) Preços */}
              <SecaoDeAjustes
                id="regras-precos"
                Icone={BadgeDollarSign}
                titulo="Preços"
                texto="Quem vê o preço na loja. A equipe vê os preços sempre, no mesmo navegador em que usa o painel."
              >
                <LinhaDeAjuste titulo="Quem vê o preço" texto="Esconder o preço não é o mesmo que marcar um produto como sob consulta: aqui a regra vale para a loja inteira.">
                  <EscolhaDeAjuste<ModoDePreco>
                    rotulo="Quem vê o preço"
                    valor={catalogPriceMode}
                    aoEscolher={setCatalogPriceMode}
                    opcoes={[
                      { valor: "public", titulo: "Todos veem os preços", texto: "Como sempre: o preço aparece para quem abrir a loja." },
                      { valor: "hidden", titulo: "Ninguém vê os preços", texto: "No lugar do preço entra um texto, e o cliente pede orçamento." },
                      { valor: "clients", titulo: "Só quem entrou na conta", texto: "Visitante vê um botão de entrar; cliente aprovado vê o preço." },
                    ]}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste
                  htmlFor="catalogPriceHiddenText"
                  titulo="Texto no lugar do preço"
                  texto="Vale também para os produtos marcados como sob consulta."
                >
                  <Input
                    id="catalogPriceHiddenText"
                    placeholder="Sob consulta"
                    value={catalogPriceHiddenText}
                    onChange={(e) => setCatalogPriceHiddenText(e.target.value)}
                    maxLength={60}
                  />
                </LinhaDeAjuste>
                {catalogPriceMode === "clients" ? (
                  <LinhaDeAjuste htmlFor="catalogPriceLoginText" titulo="Texto do botão de entrar" texto="O botão que leva o visitante à tela de entrar.">
                    <Input
                      id="catalogPriceLoginText"
                      placeholder="Entre para ver o preço"
                      value={catalogPriceLoginText}
                      onChange={(e) => setCatalogPriceLoginText(e.target.value)}
                      maxLength={60}
                    />
                  </LinhaDeAjuste>
                ) : null}
                <LinhaDeAjuste
                  htmlFor="catalogPriceNotice"
                  titulo="Aviso embaixo do preço"
                  texto="Uma linha curta, embaixo do preço e no carrinho. Em branco, não aparece."
                >
                  <Input
                    id="catalogPriceNotice"
                    placeholder="Preços sujeitos a alteração. Frete não incluso."
                    value={catalogPriceNotice}
                    onChange={(e) => setCatalogPriceNotice(e.target.value)}
                    maxLength={140}
                  />
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* b) Como o cliente fecha */}
              <SecaoDeAjustes
                id="regras-fechamento"
                Icone={ShoppingCart}
                titulo="Como o cliente fecha"
                texto="O que o botão do produto faz e como o pedido chega até você."
              >
                <LinhaDeAjuste titulo="Modo de compra">
                  <EscolhaDeAjuste<ModoDeCompra>
                    rotulo="Modo de compra"
                    valor={catalogPurchaseMode}
                    aoEscolher={setCatalogPurchaseMode}
                    opcoes={[
                      { valor: "cart", titulo: "Carrinho", texto: "Como sempre: carrinho, WhatsApp ou pagamento online conforme o tema." },
                      {
                        valor: "quote",
                        titulo: "Pedido de orçamento",
                        texto: "O cliente monta a lista e pede orçamento; o pedido chega ao painel com os preços do cadastro e você responde.",
                      },
                      { valor: "whatsapp", titulo: "Pelo WhatsApp", texto: "Sem carrinho: o botão do produto abre o WhatsApp." },
                      { valor: "showcase", titulo: "Só vitrine", texto: "Sem botão de compra." },
                    ]}
                    ajuda={
                      catalogPriceMode !== "public" && catalogPurchaseMode === "cart"
                        ? "Com o preço escondido, quem não vê o preço fecha por pedido de orçamento automaticamente."
                        : undefined
                    }
                  />
                </LinhaDeAjuste>
                {catalogPurchaseMode !== "showcase" ? (
                  <LinhaDeAjuste htmlFor="catalogCtaLabel" titulo="Texto do botão do produto" texto="Em branco, vale o texto padrão do modo escolhido.">
                    <Input
                      id="catalogCtaLabel"
                      placeholder={PADRAO_DO_BOTAO_DO_PRODUTO[catalogPurchaseMode]}
                      value={catalogCtaLabel}
                      onChange={(e) => setCatalogCtaLabel(e.target.value)}
                      maxLength={40}
                    />
                  </LinhaDeAjuste>
                ) : null}
                {catalogPurchaseMode === "cart" || catalogPurchaseMode === "quote" ? (
                  <LinhaDeAjuste
                    htmlFor="catalogCheckoutLabel"
                    titulo="Texto do botão de fechar"
                    texto={
                      catalogPurchaseMode === "cart"
                        ? "O botão que fecha o carrinho. Em branco, vale o padrão do tema."
                        : "O botão que envia a lista. Em branco, vale o texto padrão."
                    }
                  >
                    <Input
                      id="catalogCheckoutLabel"
                      placeholder={PADRAO_DO_BOTAO_DE_FECHAR[catalogPurchaseMode]}
                      value={catalogCheckoutLabel}
                      onChange={(e) => setCatalogCheckoutLabel(e.target.value)}
                      maxLength={40}
                    />
                  </LinhaDeAjuste>
                ) : null}
                {catalogPurchaseMode === "quote" ? (
                  <ChaveDeAjuste
                    titulo="Abrir o WhatsApp depois de enviar o pedido de orçamento"
                    texto="O cliente já cai na conversa com a loja, com a lista enviada (sem preços)."
                    ligado={catalogQuoteOpenWhatsapp}
                    aoMudar={setCatalogQuoteOpenWhatsapp}
                  />
                ) : null}
              </SecaoDeAjustes>

              {/* c) Quem pode entrar */}
              <SecaoDeAjustes
                id="regras-acesso"
                Icone={Lock}
                titulo="Quem pode entrar"
                texto="Loja aberta a todos ou só para clientes com conta, e como o cadastro acontece."
              >
                <LinhaDeAjuste titulo="Modo de acesso" texto="Fechada, a loja sai do Google e do diretório.">
                  <EscolhaDeAjuste<ModoDeAcesso>
                    rotulo="Modo de acesso"
                    valor={catalogAccessMode}
                    aoEscolher={setCatalogAccessMode}
                    opcoes={[
                      { valor: "public", titulo: "Loja aberta", texto: "Qualquer pessoa abre a loja e vê os produtos." },
                      { valor: "clients", titulo: "Só quem entrou na conta", texto: "Quem não entrou vê só a tela de entrar." },
                    ]}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste titulo="Modo de cadastro">
                  <EscolhaDeAjuste<ModoDeCadastro>
                    rotulo="Modo de cadastro"
                    valor={catalogSignupMode}
                    aoEscolher={setCatalogSignupMode}
                    opcoes={[
                      { valor: "open", titulo: "Livre", texto: "Como sempre: o cliente se cadastra e já entra." },
                      { valor: "approval", titulo: "Com aprovação", texto: "O cadastro fica pendente até você aprovar em Clientes." },
                      { valor: "closed", titulo: "Fechado", texto: "Só a loja cria o acesso, em Clientes > Gerar primeiro acesso." },
                    ]}
                  />
                </LinhaDeAjuste>
                <ChaveDeAjuste
                  titulo="Só CNPJ"
                  texto="O cadastro pela loja só aceita empresas (loja de revendedores)."
                  ligado={catalogSignupRequireCnpj}
                  aoMudar={setCatalogSignupRequireCnpj}
                />
                <ChaveDeAjuste
                  titulo="Exigir cadastro para fechar pedido"
                  texto="Sem conta, o cliente monta o carrinho mas não fecha."
                  ligado={catalogRequireLoginToOrder}
                  aoMudar={setCatalogRequireLoginToOrder}
                />
                <LinhaDeAjuste
                  htmlFor="catalogLoginMessage"
                  titulo="Mensagem na tela de entrar"
                  texto="Aparece na tela de entrar e de cadastrar. Em branco, não aparece."
                >
                  <AreaDeTexto
                    id="catalogLoginMessage"
                    value={catalogLoginMessage}
                    onChange={(e) => setCatalogLoginMessage(e.target.value)}
                    rows={2}
                    maxLength={300}
                    placeholder="Ex.: Loja exclusiva para revendedores. Cadastre-se com o CNPJ da sua empresa."
                  />
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* d) Regras de venda */}
              <SecaoDeAjustes
                id="regras-venda"
                Icone={SlidersHorizontal}
                titulo="Regras de venda"
                texto="Pedido mínimo, estoque e o que aparece na página do produto."
              >
                <LinhaDeAjuste titulo="Pedido mínimo" texto="Abaixo disso, o cliente não fecha. Em branco, sem mínimo. As unidades somam todos os itens do carrinho.">
                  <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
                    <EntradaDecimal
                      id="catalogMinOrderTotal"
                      aria-label="Pedido mínimo em reais"
                      placeholder="Sem mínimo em R$"
                      valor={catalogMinOrderTotal}
                      aoMudar={setCatalogMinOrderTotal}
                      zeroVazio
                      casas={2}
                    />
                    <EntradaDecimal
                      id="catalogMinOrderItems"
                      aria-label="Pedido mínimo em unidades"
                      placeholder="Sem mínimo de unidades"
                      valor={catalogMinOrderItems}
                      aoMudar={setCatalogMinOrderItems}
                      zeroVazio
                      casas={0}
                    />
                  </div>
                </LinhaDeAjuste>
                <LinhaDeAjuste titulo="Estoque na loja" texto="O que a página do produto diz sobre o saldo.">
                  <div className="space-y-3">
                    <CustomSelect
                      options={[
                        { value: "exact", label: "Mostrar o saldo" },
                        { value: "low_only", label: "Só avisar 'últimas unidades'" },
                        { value: "never", label: "Não mostrar" },
                      ]}
                      value={catalogStockDisplay}
                      onChange={(valor) => setCatalogStockDisplay(valor === "low_only" || valor === "never" ? valor : "exact")}
                    />
                    {catalogStockDisplay === "low_only" ? (
                      <EntradaDecimal
                        id="catalogLowStockThreshold"
                        label="Avisar 'últimas unidades' abaixo de"
                        placeholder="5"
                        valor={catalogLowStockThreshold}
                        aoMudar={setCatalogLowStockThreshold}
                        casas={0}
                      />
                    ) : null}
                  </div>
                </LinhaDeAjuste>
                <LinhaDeAjuste titulo="Produto esgotado" texto="Só vale para produtos com controle de estoque ligado.">
                  <CustomSelect
                    options={[
                      { value: "show", label: "Mostrar como esgotado" },
                      { value: "hide", label: "Esconder da loja" },
                      { value: "quote", label: "Virar pedir orçamento" },
                    ]}
                    value={catalogSoldOutMode}
                    onChange={(valor) => setCatalogSoldOutMode(valor === "hide" || valor === "quote" ? valor : "show")}
                  />
                </LinhaDeAjuste>
                <ChaveDeAjuste titulo="Mostrar avaliações" texto="As notas e os comentários dos clientes na página do produto." ligado={catalogReviewsEnabled} aoMudar={setCatalogReviewsEnabled} />
                <ChaveDeAjuste titulo="Mostrar código (SKU) do produto" ligado={catalogShowSku} aoMudar={setCatalogShowSku} />
                <ChaveDeAjuste
                  titulo="Mostrar prazo de produção"
                  texto="O prazo do produto e a contagem de 'entra em produção hoje'."
                  ligado={catalogShowProductionTime}
                  aoMudar={setCatalogShowProductionTime}
                />
              </SecaoDeAjustes>

              {/* e) Situação da loja */}
              <SecaoDeAjustes
                id="regras-situacao"
                Icone={Store}
                titulo="Situação da loja"
                texto="Para as férias, o estoque parado ou a reforma. A equipe continua entrando na loja pausada ou fechada."
              >
                <LinhaDeAjuste titulo="Situação">
                  <EscolhaDeAjuste<SituacaoDaLoja>
                    rotulo="Situação"
                    valor={catalogStatus}
                    aoEscolher={setCatalogStatus}
                    opcoes={[
                      { valor: "open", titulo: "Aberta", texto: "Como sempre." },
                      { valor: "paused", titulo: "Em pausa", texto: "A loja aparece, mas ninguém fecha pedido." },
                      { valor: "closed", titulo: "Fechada", texto: "Quem entra vê uma página 'em breve' com o seu recado." },
                    ]}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogStatusMessage" titulo="Recado" texto="Aparece na loja pausada ou fechada.">
                  <AreaDeTexto
                    id="catalogStatusMessage"
                    value={catalogStatusMessage}
                    onChange={(e) => setCatalogStatusMessage(e.target.value)}
                    rows={3}
                    maxLength={500}
                    placeholder="Ex.: Estamos de férias! Voltamos a atender no dia 20."
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogStatusUntil" titulo="Previsão de volta" texto="Mostrada junto com o recado.">
                  <div className="sm:max-w-[220px]">
                    <Input id="catalogStatusUntil" type="date" value={catalogStatusUntil} onChange={(e) => setCatalogStatusUntil(e.target.value)} />
                  </div>
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* f) Mensagens do WhatsApp: moram em outra tela */}
              <SecaoDeAjustes
                id="regras-whatsapp"
                Icone={MessageCircle}
                titulo="Mensagens do WhatsApp"
                texto="Os textos que a loja usa no WhatsApp (dúvida sobre produto, cabeçalho e rodapé do pedido) ficam em WhatsApp > Mensagens."
              >
                <div className="pb-3 pt-1">
                  <Link
                    href="/dashboard/whatsapp"
                    className="inline-flex items-center gap-1.5 text-sm font-semibold text-[var(--ks-color-primary)] hover:underline"
                  >
                    Abrir WhatsApp &gt; Mensagens
                    <ArrowUpRight size={16} />
                  </Link>
                </div>
              </SecaoDeAjustes>
            </FolhaDeAjustes>
          </TabsContent>

          <TabsContent value="logistics" className="space-y-6">
            <PickupLocationsTab
              profileId={userId}
              companyAddress={companyAddressFields}
              suggestedName={catalogName.trim() || "Retirada na loja"}
            />
          </TabsContent>

          <TabsContent value="seo" className="space-y-5">
            <FolhaDeAjustes
              indice={indiceDoSeo({
                titulo: catalogMetaTitle,
                imagem: catalogOgImageUrl,
                favicon: catalogFaviconUrl,
                indexar: !catalogNoIndex,
              })}
            >
              {/* a) Google */}
              <SecaoDeAjustes id="seo-google" Icone={Globe} titulo="Busca no Google" texto="O que o Google mostra quando a loja aparece na busca.">
                <LinhaDeAjuste htmlFor="catalogMetaTitle" titulo="Título SEO" texto="O título da página nos resultados. Em branco, vale o nome da loja.">
                  <Input
                    id="catalogMetaTitle"
                    placeholder="Ex: Gráfica Rápida em Recife | Nossa Gráfica"
                    value={catalogMetaTitle}
                    onChange={(e) => setCatalogMetaTitle(e.target.value)}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogMetaDescription" titulo="Descrição SEO" texto="Duas linhas com as palavras-chave e a proposta da loja.">
                  <AreaDeTexto
                    id="catalogMetaDescription"
                    value={catalogMetaDescription}
                    onChange={(e) => setCatalogMetaDescription(e.target.value)}
                    rows={3}
                    placeholder="Descreva sua loja com palavras-chave e proposta de valor."
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogMetaKeywords" titulo="Palavras-chave" texto="Separadas por vírgula.">
                  <Input
                    id="catalogMetaKeywords"
                    placeholder="Ex: gráfica rápida, cartão de visita, adesivo personalizado"
                    value={catalogMetaKeywords}
                    onChange={(e) => setCatalogMetaKeywords(e.target.value)}
                  />
                </LinhaDeAjuste>
                <ChaveDeAjuste
                  titulo="Indexação no Google"
                  texto="Desligado, o catálogo pede para não aparecer nas buscas."
                  ligado={!catalogNoIndex}
                  aoMudar={(checked) => setCatalogNoIndex(!checked)}
                />
              </SecaoDeAjustes>

              {/* b) Compartilhamento */}
              <SecaoDeAjustes
                id="seo-compartilhamento"
                Icone={Share2}
                titulo="Compartilhamento"
                texto="Como o link da loja aparece no WhatsApp, no Instagram e nas outras redes."
              >
                <LinhaDeAjuste htmlFor="catalogOgTitle" titulo="Título para compartilhamento" texto="Open Graph. Em branco, vale o título SEO.">
                  <Input
                    id="catalogOgTitle"
                    placeholder="Ex: Impressão profissional com entrega rápida"
                    value={catalogOgTitle}
                    onChange={(e) => setCatalogOgTitle(e.target.value)}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogOgDescription" titulo="Descrição para compartilhamento">
                  <AreaDeTexto
                    id="catalogOgDescription"
                    value={catalogOgDescription}
                    onChange={(e) => setCatalogOgDescription(e.target.value)}
                    rows={3}
                    placeholder="Texto que aparece quando o link do catálogo é compartilhado."
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste titulo="Imagem para compartilhamento" texto="Envie uma imagem 1200x630 para melhor aparência nos compartilhamentos.">
                  <ImageUpload
                    bucket="products"
                    folder="catalog-seo/og"
                    value={catalogOgImageUrl}
                    onChange={setCatalogOgImageUrl}
                    enableCrop
                    cropAspect={1200 / 630}
                  />
                </LinhaDeAjuste>
                <LinhaDeAjuste htmlFor="catalogTwitterHandle" titulo="Usuário X/Twitter" texto="Aparece no cartão quando o link é compartilhado no X.">
                  <Input
                    id="catalogTwitterHandle"
                    placeholder="Ex: @sualoja"
                    value={catalogTwitterHandle}
                    onChange={(e) => setCatalogTwitterHandle(e.target.value)}
                  />
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* c) Aba do navegador */}
              <SecaoDeAjustes id="seo-favicon" Icone={PanelTop} titulo="Aba do navegador" texto="O ícone da loja na aba do navegador e nos favoritos.">
                <LinhaDeAjuste titulo="Favicon do catálogo" texto="Recomendado: ícone quadrado.">
                  <ImageUpload
                    bucket="products"
                    folder="catalog-seo/favicon"
                    value={catalogFaviconUrl}
                    onChange={setCatalogFaviconUrl}
                    enableCrop
                    cropAspect={1}
                  />
                </LinhaDeAjuste>
              </SecaoDeAjustes>

              {/* d) Prévia */}
              <SecaoDeAjustes id="seo-previa" Icone={Eye} titulo="Prévia de compartilhamento" texto="Como o link da loja aparece quando alguém compartilha.">
                <LinhaDeAjuste largo titulo="Cartão do link">
                  <div className="max-w-xl space-y-3 rounded-2xl border border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-elevated)] p-4">
                    <div className="truncate text-[11px] uppercase tracking-wide text-[var(--ks-color-text-soft)]">
                      {publicCatalogUrl || "https://ktalogu.com/seu-link"}
                    </div>
                    {seoPreviewImage ? (
                      <Image
                        src={seoPreviewImage}
                        alt="Prévia Open Graph"
                        width={1200}
                        height={630}
                        className="h-40 w-full rounded-lg border border-[var(--ks-color-border-subtle)] object-cover"
                        unoptimized
                      />
                    ) : (
                      <div className="flex h-40 w-full items-center justify-center rounded-lg border border-dashed border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-subtle)] text-xs text-[var(--ks-color-text-soft)]">
                        Sem imagem de compartilhamento
                      </div>
                    )}
                    <div className="space-y-1">
                      <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">{seoPreviewTitle}</p>
                      <p className="line-clamp-3 text-xs text-[var(--ks-color-text-muted)]">{seoPreviewDescription}</p>
                    </div>
                  </div>
                </LinhaDeAjuste>
              </SecaoDeAjustes>
            </FolhaDeAjustes>
          </TabsContent>
        </Tabs>

        {/* Barra de acao fixa: a pagina e longa e o botao de salvar ficava so
            la embaixo, obrigando a rolar tudo de volta a cada ajuste. */}
        <div className="sticky bottom-3 z-30 flex flex-wrap items-center justify-end gap-3 rounded-2xl border border-[var(--ks-color-border-subtle)] bg-white/95 px-4 py-3 shadow-[0_10px_30px_-18px_rgba(15,23,42,0.45)] backdrop-blur">
          {message && (
            <motion.div
              initial={{ opacity: 0, x: 20 }}
              animate={{ opacity: 1, x: 0 }}
              className={`text-sm px-4 py-2 rounded-md ${
                message.type === "success"
                  ? "bg-[color:rgba(18,185,129,0.08)] text-[var(--ks-color-status-success)]"
                  : "bg-[color:rgba(249,115,115,0.08)] text-[var(--ks-color-status-danger)]"
              }`}
            >
              {message.text}
            </motion.div>
          )}
          
          <Button
            type="submit"
            disabled={saving}
            icon={saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
          >
            {saving ? "Salvando..." : "Salvar alterações"}
          </Button>
        </div>
      </motion.form>
    </div>
  );
}
