import type { Metadata } from "next";

type CatalogSeoProfile = {
  slug?: string | null;
  updated_at?: string | null;
  catalog_name?: string | null;
  store_name?: string | null;
  logo_url?: string | null;
  catalog_logo_url?: string | null;
  catalog_meta_title?: string | null;
  catalog_meta_description?: string | null;
  catalog_meta_keywords?: string | null;
  catalog_og_title?: string | null;
  catalog_og_description?: string | null;
  catalog_og_image_url?: string | null;
  catalog_favicon_url?: string | null;
  catalog_noindex?: boolean | null;
  catalog_twitter_handle?: string | null;
  /* Regras da loja: fechada ou so para clientes, sai do Google tambem. */
  catalog_access_mode?: string | null;
  catalog_status?: string | null;
};

function trimValue(value: string | null | undefined) {
  return String(value || "").trim();
}

/* Google corta a descricao perto de 160 caracteres e o WhatsApp bem antes.
   Descricao de produto costuma ser um texto longo de venda: sem corte, a previa
   fica com uma frase picada no meio. Corta na ultima palavra inteira. */
function clampDescription(value: string, maxLength = 160) {
  const clean = value.replace(/\s+/g, " ").trim();
  if (clean.length <= maxLength) return clean;
  const cut = clean.slice(0, maxLength);
  const lastSpace = cut.lastIndexOf(" ");
  return `${(lastSpace > 60 ? cut.slice(0, lastSpace) : cut).replace(/[\s.,;:-]+$/, "")}…`;
}

function normalizeKeywords(raw: string) {
  return raw
    .split(",")
    .map((keyword) => keyword.trim())
    .filter(Boolean);
}

function dedupeKeywords(values: string[]) {
  const seen = new Set<string>();
  const output: string[] = [];
  values.forEach((value) => {
    const normalized = value.toLowerCase();
    if (!normalized || seen.has(normalized)) return;
    seen.add(normalized);
    output.push(value);
  });
  return output;
}

function buildAutomaticKeywords(params: {
  storeName: string;
  pageTitle: string;
  pageDescription: string;
}) {
  const wordsFromTitle = params.pageTitle
    .toLowerCase()
    .replace(/[^a-z0-9à-úç\s-]/gi, " ")
    .split(/\s+/)
    .map((word) => word.trim())
    .filter((word) => word.length >= 4);

  const wordsFromDescription = params.pageDescription
    .toLowerCase()
    .replace(/[^a-z0-9à-úç\s-]/gi, " ")
    .split(/\s+/)
    .map((word) => word.trim())
    .filter((word) => word.length >= 5);

  const seed = [
    params.storeName,
    "catálogo online",
    "comprar online",
    "orçamento online",
    ...wordsFromTitle.slice(0, 6),
    ...wordsFromDescription.slice(0, 5),
  ].map((value) => value.trim()).filter(Boolean);

  return dedupeKeywords(seed).slice(0, 14);
}

function normalizeTwitterHandle(value: string) {
  const clean = value.trim();
  if (!clean) return "";
  return clean.startsWith("@") ? clean : `@${clean}`;
}

function buildCanonicalUrl(slug: string, path: string) {
  const base = trimValue(process.env.NEXT_PUBLIC_PUBLIC_CATALOG_BASE_URL || "https://ktalogu.com.br").replace(/\/$/, "");
  const safePath = path.startsWith("/") ? path : `/${path}`;
  return `${base}/${slug}${safePath === "/" ? "" : safePath}`;
}

export function buildCatalogMetadata(params: {
  profile: CatalogSeoProfile | null | undefined;
  pageTitle?: string;
  pageDescription?: string;
  path?: string;
  /**
   * "store" = a pagina E a loja (home). Ai o que o lojista escreveu na aba
   * Metadados e SEO e o conteudo proprio da pagina e vence.
   *
   * "page" = pagina interna (produto, categoria, busca). O titulo e a descricao
   * daquela pagina vencem; o SEO da loja so entra como rede de seguranca quando
   * a pagina nao tem texto proprio.
   *
   * Sem essa separacao o SEO da loja sobrescrevia TODA pagina: quem preenchia a
   * aba passava a compartilhar links de produto com o titulo e a descricao da
   * loja, e o produto sumia da previa.
   */
  scope?: "store" | "page";
  /** Imagem propria da pagina (foto do produto). Vence a imagem da loja. */
  image?: string | null;
  imageAlt?: string | null;
}): Metadata {
  const profile = params.profile;
  const escopo = params.scope || "page";
  const daLoja = escopo === "store";
  const slug = trimValue(profile?.slug);
  const storeName = trimValue(profile?.catalog_name) || trimValue(profile?.store_name) || "Loja";
  const fallbackTitle = params.pageTitle || storeName;
  const fallbackDescription = params.pageDescription || `Conheça os produtos de ${storeName}.`;
  const seoTitle = trimValue(profile?.catalog_meta_title);
  const seoDescription = trimValue(profile?.catalog_meta_description);
  const seoOgTitle = trimValue(profile?.catalog_og_title);
  const seoOgDescription = trimValue(profile?.catalog_og_description);
  const metaTitle = daLoja ? seoTitle || fallbackTitle : fallbackTitle || seoTitle;
  const metaDescription = daLoja
    ? seoDescription || fallbackDescription
    : fallbackDescription || seoDescription;
  const ogTitle = daLoja ? seoOgTitle || metaTitle : metaTitle || seoOgTitle;
  const ogDescription = daLoja
    ? seoOgDescription || metaDescription
    : metaDescription || seoOgDescription;
  const metaDescriptionShort = clampDescription(metaDescription);
  const ogDescriptionShort = clampDescription(ogDescription);
  const pageImage = trimValue(params.image);
  const ogImageUrl = pageImage || trimValue(profile?.catalog_og_image_url) || trimValue(profile?.catalog_logo_url) || trimValue(profile?.logo_url) || "/brand-logo.svg";
  const faviconUrl = trimValue(profile?.catalog_favicon_url) || trimValue(profile?.catalog_logo_url) || trimValue(profile?.logo_url);
  const customKeywords = normalizeKeywords(trimValue(profile?.catalog_meta_keywords));
  const autoKeywords = buildAutomaticKeywords({
    storeName,
    pageTitle: metaTitle,
    pageDescription: metaDescription,
  });
  const keywords = customKeywords.length > 0 ? dedupeKeywords([...customKeywords, ...autoKeywords]) : autoKeywords;
  const twitterHandle = normalizeTwitterHandle(trimValue(profile?.catalog_twitter_handle));
  const lojaForaDoAr = profile?.catalog_access_mode === "clients" || profile?.catalog_status === "closed";
  const robotsIndex = !Boolean(profile?.catalog_noindex) && !lojaForaDoAr;
  const path = params.path || "/";
  const canonical = slug ? buildCanonicalUrl(slug, path) : undefined;
  const faviconVersion = trimValue(profile?.updated_at);
  /* "f=2": a geração do endereço. Mudou de 1 para 2 em 09/09/2026, quando a
     rota passou a servir o ícone pequeno: navegador e Cloudflare guardam o
     favicon pelo endereço, e sem trocar o endereço quem viu o ícone errado
     (ou o pesado) durante o deploy continuaria vendo por meses. */
  const faviconPath = slug
    ? `/${slug}/favicon.ico?${faviconVersion ? `v=${encodeURIComponent(faviconVersion)}&` : ""}f=2`
    : "";

  const metadata: Metadata = {
    title: { absolute: metaTitle },
    description: metaDescriptionShort,
    keywords: keywords.length > 0 ? keywords : undefined,
    robots: {
      index: robotsIndex,
      follow: robotsIndex,
      googleBot: {
        index: robotsIndex,
        follow: robotsIndex,
        /* Sem `max-image-preview: large` o Google mostra so uma miniatura (ou
           nenhuma) do produto no resultado — e a foto e o que faz clicar. */
        "max-image-preview": "large",
        "max-snippet": -1,
        "max-video-preview": -1,
      },
    },
    alternates: canonical
      ? {
          canonical,
        }
      : undefined,
    openGraph: {
      title: ogTitle,
      description: ogDescriptionShort,
      siteName: storeName,
      type: "website",
      locale: "pt_BR",
      url: canonical,
      images: [
        {
          url: ogImageUrl,
          alt: trimValue(params.imageAlt) || storeName,
          /* WhatsApp e Facebook so garantem a previa grande quando sabem a
             proporcao antes de baixar a imagem. */
          width: 1200,
          height: 630,
        },
      ],
    },
    twitter: {
      card: "summary_large_image",
      title: ogTitle,
      description: ogDescriptionShort,
      images: [ogImageUrl],
      creator: twitterHandle || undefined,
      site: twitterHandle || undefined,
    },
  };

  if (faviconUrl) {
    metadata.icons = {
      icon: [{ url: faviconPath || faviconUrl }],
      shortcut: [{ url: faviconPath || faviconUrl }],
      apple: [{ url: faviconPath || faviconUrl }],
    };
  }

  return metadata;
}
