import { ArticleJsonLd, BreadcrumbJsonLd, OrganizationJsonLd } from "next-seo";
import {
  DEFAULT_DESCRIPTION,
  DEFAULT_OG_IMAGE,
  SITE_NAME,
  SITE_URL,
  absoluteUrl,
  siteNavigationItems,
} from "@/app/lib/seo";

/**
 * Structured data, rendered with next-seo's JSON-LD components. next-seo v7
 * covers JSON-LD only in the App Router - plain meta tags come from the
 * Metadata API in app/lib/seo.ts instead.
 *
 * These are server components emitting <script type="application/ld+json">,
 * which replaces the legacy app's hand-written dangerouslySetInnerHTML blocks.
 */

/** Site-wide identity. Rendered once, in the root layout. */
export function SiteOrganizationJsonLd() {
  return (
    <OrganizationJsonLd
      scriptId="organization-jsonld"
      name={SITE_NAME}
      url={SITE_URL}
      logo={absoluteUrl("/oxyfinz-logo.png")}
      description={DEFAULT_DESCRIPTION}
      sameAs={["https://www.linkedin.com/company/oxyfinz"]}
    />
  );
}

/**
 * The legacy build emitted an ItemList of SiteNavigationElements to nominate
 * sitelink candidates. next-seo has no component for that shape, so it stays
 * a plain script - still driven off the same PUBLIC_PAGES list.
 */
export function SiteNavigationJsonLd() {
  const payload = {
    "@context": "https://schema.org",
    "@type": "ItemList",
    "@id": `${SITE_URL}/#sitenavigation`,
    name: "Main navigation",
    itemListElement: siteNavigationItems().map((item, index) => ({
      "@type": "SiteNavigationElement",
      position: index + 1,
      name: item.title.replace(` | ${SITE_NAME}`, ""),
      url: absoluteUrl(item.path),
      description: item.description,
    })),
  };

  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: JSON.stringify(payload) }}
    />
  );
}

/** Home > {name} trail for any page below the root. */
export function PageBreadcrumbJsonLd({ path, name }: { path: string; name: string }) {
  return (
    <BreadcrumbJsonLd
      scriptId={`breadcrumb-jsonld-${path.replace(/[^a-z0-9]+/gi, "-")}`}
      items={[
        { name: "Home", item: SITE_URL },
        { name, item: absoluteUrl(path) },
      ]}
    />
  );
}

/** Article/blog posting metadata for a single post. */
export function PostArticleJsonLd({
  path,
  headline,
  description,
  image,
  datePublished,
  dateModified,
  isBlogPost,
}: {
  path: string;
  headline: string;
  description: string;
  image?: string | null;
  datePublished?: string | null;
  dateModified?: string | null;
  isBlogPost?: boolean;
}) {
  const url = absoluteUrl(path);
  const resolvedImage = image?.startsWith("http")
    ? image
    : absoluteUrl(image || DEFAULT_OG_IMAGE);

  return (
    <ArticleJsonLd
      scriptId="article-jsonld"
      type={isBlogPost ? "BlogPosting" : "Article"}
      url={url}
      mainEntityOfPage={url}
      headline={headline}
      description={description}
      image={resolvedImage}
      // The CMS records carry no per-article byline, so the organisation is
      // both author and publisher.
      author={{ "@type": "Organization", name: SITE_NAME, url: SITE_URL }}
      publisher={{
        "@type": "Organization",
        name: SITE_NAME,
        logo: { "@type": "ImageObject", url: absoluteUrl("/oxyfinz-logo.png") },
      }}
      {...(datePublished ? { datePublished: toIso(datePublished) } : {})}
      {...(dateModified || datePublished
        ? { dateModified: toIso((dateModified || datePublished)!) }
        : {})}
    />
  );
}

/** CMS dates arrive as "YYYY-MM-DD HH:MM:SS"; schema.org wants ISO 8601. */
function toIso(value: string): string {
  const date = new Date(value.replace(" ", "T"));
  return Number.isNaN(date.getTime()) ? value : date.toISOString();
}
