import { PublicLayout } from '@/components/layout/public/public-layout';
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import OpinionGrid from '../_components/opinion-grid';
import {
  transformPostsToArticleList,
  transformPostToArticle
} from '@/features/posts/_lib/transformers';
import { PostOrderEnum, TopicsEnum } from '@/config/enums';
import { createCaller, createHelpers } from '@/lib/trpc/server';
import RelatedArticle from '@/components/shared/post-sections/related-article';
import CommentSection from '@/components/shared/comments/comment-section';
import RelatedVision from '@/components/shared/post-sections/related-vision';
import { adaptPostToContentData } from '@/lib/meta-tags';
import { buildMetadataFromContent, generateMetaTags } from '@/lib/meta-tags/server';

type Props = {
  params: Promise<{ slug: string }>;
};

const BASE_PATH = 'opinion';

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const slug = (await params).slug;

  const helper = await createHelpers();
  const post = await helper.posts.get.fetch({
    with: ['tags'],
    topic: TopicsEnum.OPINION,
    slug
  });

  if (!post) {
    return {
      title: 'Post Not Found | Magasinet KBH',
      description: 'The requested post could not be found.'
    };
  }

  const contentData = adaptPostToContentData(post, { basePath: BASE_PATH, slug });
  return await buildMetadataFromContent(contentData);
}

export default async function Page({ params }: Props) {
  const { slug } = await params;

  try {
    const helpers = await createHelpers();
    const caller = await createCaller();

    const [post, mostRead] = await Promise.all([
      helpers.posts.get.fetch({
        with: ['author', 'tags', 'primaryTag', 'postMedia', 'content'],
        topic: TopicsEnum.OPINION,
        slug
      }),
      helpers.posts.list.fetch({
        limit: 5,
        topic: TopicsEnum.OPINION,
        orderBy: PostOrderEnum.VIEWS
      })
    ]);

    if (!post) {
      notFound();
    }

    void caller.analytic.view({
      postId: post.id
    });

    const postData = transformPostToArticle(post);
    const mostReadData = transformPostsToArticleList(mostRead);

    const [lastPosts, relatedPosts, relatedVisions] = await Promise.all([
      helpers.posts.list.fetch({
        relateSlug: slug,
        with: ['author'],
        limit: 2,
        topic: TopicsEnum.CITY_SPACES,
        orderBy: PostOrderEnum.PUBLISHED_AT
      }),
      helpers.posts.list.fetch({
        relateSlug: slug,
        with: ['primaryTag'],
        limit: 5,
        topic: TopicsEnum.OPINION,
        orderBy: PostOrderEnum.PUBLISHED_AT
      }),
      helpers.posts.list.fetch({
        relateSlug: slug,
        with: ['primaryTag', 'vision'],
        limit: 5,
        topic: TopicsEnum.VISIONS,
        orderBy: PostOrderEnum.PUBLISHED_AT
      })
    ]);

    const lastPostsData = transformPostsToArticleList(lastPosts);
    const relatedArticleData = transformPostsToArticleList(relatedPosts);
    const relatedVisionData = transformPostsToArticleList(relatedVisions);

    const contentData = adaptPostToContentData(post, { basePath: BASE_PATH, slug });
    const { jsonLd } = await generateMetaTags(contentData);

    return (
      <PublicLayout>
        {jsonLd && (
          <script
            type="application/ld+json"
            dangerouslySetInnerHTML={{
              __html: JSON.stringify(jsonLd).replace(/</g, '\\u003c')
            }}
          />
        )}
        <OpinionGrid post={postData} mostRead={mostReadData} />
        <CommentSection background='green' postId={post.id} />
        <RelatedArticle title='relaterede artikler' data={relatedArticleData} />
        <RelatedVision title='relaterede visioner' data={relatedVisionData} />
        <RelatedArticle
          title='seneste byens rum'
          data={lastPostsData}
          type='large'
        />
      </PublicLayout>
    );
  } catch {
    notFound();
  }
}
