import type { FaqItem, ResourceArticle, ServiceContent } from "@/content/types";
import { ogImagePath } from "@/lib/seo";
import { absoluteUrl, siteConfig } from "@/lib/site";

/** JSON-LD builders. Only supplied, verifiable facts about the company are used. */

const organizationId = `${siteConfig.url}/#organization`;
const websiteId = `${siteConfig.url}/#website`;

export type JsonLdObject = Record<string, unknown>;

export function organizationSchema(): JsonLdObject {
  return {
    "@context": "https://schema.org",
    "@type": "Organization",
    "@id": organizationId,
    name: siteConfig.name,
    legalName: siteConfig.legalName,
    url: siteConfig.url,
    logo: absoluteUrl("/brand/axidys-mark-512.png"),
    description: siteConfig.description,
    address: {
      "@type": "PostalAddress",
      streetAddress: siteConfig.address.streetAddress,
      addressLocality: siteConfig.address.addressLocality,
      addressRegion: siteConfig.address.addressRegion,
      addressCountry: siteConfig.address.addressCountry,
    },
    identifier: {
      "@type": "PropertyValue",
      propertyID: "Hong Kong Companies Registry number",
      value: siteConfig.companyNumber,
    },
    email: siteConfig.contactEmail,
    knowsAbout: [
      "SaaS growth marketing",
      "E-commerce growth marketing",
      "Paid media",
      "Search engine optimization",
      "Conversion rate optimization",
      "Marketing analytics and attribution",
      "Lifecycle marketing",
    ],
  };
}

export function websiteSchema(): JsonLdObject {
  return {
    "@context": "https://schema.org",
    "@type": "WebSite",
    "@id": websiteId,
    url: siteConfig.url,
    name: siteConfig.name,
    inLanguage: "en",
    publisher: { "@id": organizationId },
  };
}

export interface Crumb {
  name: string;
  href: string;
}

export function breadcrumbSchema(crumbs: Crumb[]): JsonLdObject {
  return {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    itemListElement: crumbs.map((crumb, index) => ({
      "@type": "ListItem",
      position: index + 1,
      name: crumb.name,
      item: absoluteUrl(crumb.href),
    })),
  };
}

export function faqSchema(faqs: FaqItem[]): JsonLdObject {
  return {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    mainEntity: faqs.map((faq) => ({
      "@type": "Question",
      name: faq.question,
      acceptedAnswer: { "@type": "Answer", text: stripInlineMarks(faq.answer) },
    })),
  };
}

export function serviceSchema(service: ServiceContent): JsonLdObject {
  return {
    "@context": "https://schema.org",
    "@type": "Service",
    "@id": `${absoluteUrl(`/${service.slug}`)}#service`,
    name: service.name,
    serviceType: service.name,
    description: service.seo.description,
    url: absoluteUrl(`/${service.slug}`),
    provider: { "@id": organizationId },
    audience: {
      "@type": "BusinessAudience",
      audienceType: "SaaS and e-commerce companies",
    },
  };
}

export function industryServiceSchema(input: { name: string; description: string; path: string }): JsonLdObject {
  return {
    "@context": "https://schema.org",
    "@type": "Service",
    "@id": `${absoluteUrl(input.path)}#service`,
    name: input.name,
    serviceType: "Growth marketing",
    description: input.description,
    url: absoluteUrl(input.path),
    provider: { "@id": organizationId },
  };
}

export function articleSchema(article: ResourceArticle): JsonLdObject {
  const url = absoluteUrl(`/resources/${article.slug}`);
  return {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: article.title,
    description: article.seo.description,
    datePublished: article.publishedAt,
    dateModified: article.updatedAt ?? article.publishedAt,
    author: { "@type": "Organization", name: siteConfig.name, url: siteConfig.url },
    publisher: { "@id": organizationId },
    mainEntityOfPage: { "@type": "WebPage", "@id": url },
    image: absoluteUrl(ogImagePath(`resource-${article.slug}`)),
    articleSection: article.category,
    inLanguage: "en",
  };
}

/** Removes **bold** and [label](href) marks for plain-text contexts such as JSON-LD. */
export function stripInlineMarks(text: string): string {
  return text.replace(/\*\*(.+?)\*\*/g, "$1").replace(/\[([^\]]+)\]\(([^)]+)\)/g, "$1");
}
