/**
 * Dados estruturados (JSON-LD) do catalogo.
 *
 * As tags Open Graph resolvem a previa em WhatsApp e redes sociais, mas quem
 * decide resultado rico no Google (foto grande, preco, estrelas, disponibilidade
 * na propria busca) e o JSON-LD. Sem isso o SEO da aba fica so no titulo.
 *
 * Schema.org: Product + Offer + BreadcrumbList na pagina de produto, Store na
 * home. So emitimos campos que existem de verdade — dado inventado ou vazio faz
 * o Google marcar a pagina com erro no Search Console e ignorar o bloco inteiro.
 */

const BASE_URL = String(
  process.env.NEXT_PUBLIC_PUBLIC_CATALOG_BASE_URL || "https://ktalogu.com.br"
).replace(/\/$/, "");

function absolutize(url: string) {
  const clean = String(url || "").trim();
  if (!clean) return "";
  if (/^https?:\/\//i.test(clean)) return clean;
  return `${BASE_URL}${clean.startsWith("/") ? "" : "/"}${clean}`;
}

function cleanText(value: unknown, maxLength = 5000) {
  return String(value || "")
    .replace(/<[^>]*>/g, " ")
    .replace(/\s+/g, " ")
    .trim()
    .slice(0, maxLength);
}

export function buildStoreUrl(slug: string, path = "/") {
  const safePath = path.startsWith("/") ? path : `/${path}`;
  return `${BASE_URL}/${slug}${safePath === "/" ? "" : safePath}`;
}

export type ProductStructuredDataInput = {
  slug: string;
  storeName: string;
  productId: string;
  name: string;
  description?: string | null;
  imageUrl?: string | null;
  price?: number | null;
  /** Produto "sob consulta" nao publica preco: Offer sem preco e invalido. */
  priceOnRequest?: boolean | null;
  inStock?: boolean;
  ratingAverage?: number | null;
  ratingCount?: number | null;
  category?: { name: string; slug: string } | null;
};

export function buildProductStructuredData(input: ProductStructuredDataInput) {
  const url = buildStoreUrl(input.slug, `/p/${input.productId}`);
  const image = absolutize(String(input.imageUrl || ""));
  const description = cleanText(input.description);

  const produto: Record<string, unknown> = {
    "@context": "https://schema.org",
    "@type": "Product",
    name: cleanText(input.name, 300),
    url,
    ...(image ? { image: [image] } : {}),
    ...(description ? { description } : {}),
    ...(input.category?.name ? { category: input.category.name } : {}),
    brand: { "@type": "Brand", name: input.storeName },
  };

  /* Offer so entra com preco real. Em "sob consulta" o preco nao existe, e um
     Offer com price 0 faria o Google anunciar o produto como gratuito. */
  const preco = Number(input.price);
  if (!input.priceOnRequest && Number.isFinite(preco) && preco > 0) {
    produto.offers = {
      "@type": "Offer",
      url,
      priceCurrency: "BRL",
      price: preco.toFixed(2),
      availability: input.inStock === false
        ? "https://schema.org/OutOfStock"
        : "https://schema.org/InStock",
      seller: { "@type": "Organization", name: input.storeName },
    };
  }

  const totalAvaliacoes = Number(input.ratingCount) || 0;
  const media = Number(input.ratingAverage) || 0;
  if (totalAvaliacoes > 0 && media > 0) {
    produto.aggregateRating = {
      "@type": "AggregateRating",
      ratingValue: media.toFixed(1),
      reviewCount: totalAvaliacoes,
      bestRating: 5,
      worstRating: 1,
    };
  }

  const trilha = [
    { name: input.storeName, item: buildStoreUrl(input.slug, "/") },
    ...(input.category
      ? [{ name: input.category.name, item: buildStoreUrl(input.slug, `/c/${input.category.slug}`) }]
      : []),
    { name: cleanText(input.name, 300), item: url },
  ];

  const breadcrumb = {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    itemListElement: trilha.map((etapa, indice) => ({
      "@type": "ListItem",
      position: indice + 1,
      name: etapa.name,
      item: etapa.item,
    })),
  };

  return [produto, breadcrumb];
}

export type StoreStructuredDataInput = {
  slug: string;
  storeName: string;
  description?: string | null;
  logoUrl?: string | null;
  whatsapp?: string | null;
  address?: string | null;
};

export function buildStoreStructuredData(input: StoreStructuredDataInput) {
  const url = buildStoreUrl(input.slug, "/");
  const logo = absolutize(String(input.logoUrl || ""));
  const description = cleanText(input.description, 500);
  const telefone = String(input.whatsapp || "").replace(/\D/g, "");

  return [
    {
      "@context": "https://schema.org",
      "@type": "Store",
      name: input.storeName,
      url,
      ...(logo ? { logo, image: [logo] } : {}),
      ...(description ? { description } : {}),
      ...(telefone ? { telephone: `+${telefone.startsWith("55") ? telefone : `55${telefone}`}` } : {}),
      ...(input.address ? { address: { "@type": "PostalAddress", streetAddress: cleanText(input.address, 300) } } : {}),
    },
    {
      "@context": "https://schema.org",
      "@type": "WebSite",
      name: input.storeName,
      url,
      potentialAction: {
        "@type": "SearchAction",
        target: {
          "@type": "EntryPoint",
          urlTemplate: `${buildStoreUrl(input.slug, "/buscar")}?q={search_term_string}`,
        },
        "query-input": "required name=search_term_string",
      },
    },
  ];
}
