import { Article, WithContext } from "schema-dts";
import { cache } from "react";
import { notFound, redirect } from "next/navigation";

import { formatSection } from "@/utils/posts-utils";
import CaseStudySlug from "@/components/pages/client/services/sections/case-study-slug";
import { fetchPostBySlug } from "@/services/blogActions";
import { isServiceUnit, SERVICE_FEATURE_TAGS } from "@/constants/services-data";
import type { Post } from "@/types/blog/blogTypes";
import { InternalClientBlogTags } from "@/constants/blog-data";
import { jsonForScript } from "@/utils/json-for-script";

export const revalidate = 60;

type Params = Promise<{ unit: string; case: string }>;

const getPostBySlug = cache(async (slug: string) => {
  let post: Post | undefined;

  try {
    post = (await fetchPostBySlug(slug)).posts[0];
  } catch (error) {
    const status =
      (error as { status?: number; statusCode?: number }).status ??
      (error as { statusCode?: number }).statusCode;

    if (status === 404) {
      notFound();
    }

    throw error;
  }

  if (!post) {
    notFound();
  }

  return post;
});

function hasInternalTag(post: Post, tag: string) {
  return post.tags.some(
    (postTag) =>
      postTag.name === tag || postTag.slug === `hash-${tag.slice(1)}`,
  );
}

function isClientEditorialPost(post: Post) {
  return Object.values(InternalClientBlogTags).some((tag) =>
    hasInternalTag(post, `#${tag}`),
  );
}

function isServiceFeaturePost(post: Post, unit: string) {
  return (
    isServiceUnit(unit) && hasInternalTag(post, SERVICE_FEATURE_TAGS[unit])
  );
}

function getUnitFormatted(unit: string) {
  return unit
    .split("-")
    .map((word) =>
      word.toLowerCase() === "b2b"
        ? "B2B"
        : word.charAt(0).toUpperCase() + word.slice(1),
    )
    .join(" ");
}

export async function generateMetadata({ params }: { params: Params }) {
  const { case: slug, unit } = await params;
  if (!isServiceUnit(unit)) {
    notFound();
  }
  const formattedSection = formatSection(slug);
  const data = await getPostBySlug(slug);

  if (!isServiceFeaturePost(data, unit) && !isClientEditorialPost(data)) {
    notFound();
  }

  const unitFormatted = getUnitFormatted(unit);

  return {
    title: `${formattedSection} | ${unitFormatted} | Case study`,
    description: data.excerpt || "",
    openGraph: {
      title: `${formattedSection} | ${unitFormatted} | Case study`,
      description: data.excerpt || "",
      type: "website",
      images: [
        {
          url: data.feature_image || "",
          alt: data.feature_image_alt || "",
        },
      ],
    },
    twitter: {
      card: "summary_large_image",
      title: `${data.title} | Insights`,
      description: data.excerpt || "",
      images: data.feature_image || "",
    },
  };
}

export default async function ServiceUnitPage({ params }: { params: Params }) {
  const { case: caseStudy, unit } = await params;
  if (!isServiceUnit(unit)) {
    notFound();
  }

  const data = await getPostBySlug(caseStudy);

  if (!isServiceFeaturePost(data, unit)) {
    if (isClientEditorialPost(data)) {
      redirect(`/insights/${data.slug}`);
    }

    notFound();
  }

  const jsonLdArticle: WithContext<Article> = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: data.title,
    image: data.feature_image || "",
    datePublished: data.published_at,
    dateModified: data.updated_at,
    author: [
      {
        "@type": "Organization",
        name: "People for Research",
        url: "https://peopleforresearch.co.uk",
      },
    ],
  };

  return (
    <>
      <script
        dangerouslySetInnerHTML={{
          __html: jsonForScript(jsonLdArticle),
        }}
        type="application/ld+json"
      />
      <CaseStudySlug post={data} />
    </>
  );
}
