import type { Metadata } from "next";
import Link from "next/link";
import { notFound } from "next/navigation";

import { JsonLd } from "@/components/JsonLd";
import { PostBody } from "@/components/PostBody";
import { PostFeaturedImage, postFeaturedAspectClass } from "@/components/PostFeaturedMedia";
import { absoluteFromApiPath } from "@/lib/api";
import { fetchPublicPostBySlug, type PublicPostDetail } from "@/lib/posts";
import { hasVisibleHtmlContent, sanitizePostHtml } from "@/lib/sanitize-content";
import { getSiteOrigin } from "@/lib/site";

type PageProps = { params: Promise<{ slug: string }> };

function postDocumentTitle(post: PublicPostDetail): string {
  const fromMeta = post.metaTitle?.trim();
  return fromMeta || post.title.trim();
}

function postMetaDescription(post: PublicPostDetail): string | undefined {
  const fromMeta = post.metaDescription?.trim();
  if (fromMeta) return fromMeta;
  const fromExcerpt = post.excerpt?.trim();
  return fromExcerpt || undefined;
}

function postShareImageAbsolute(post: PublicPostDetail): string {
  const pathOrUrl = post.ogImage?.trim() || post.featuredImage?.trim() || "";
  return absoluteFromApiPath(pathOrUrl);
}

function openGraphImageEntry(absoluteUrl: string): [{ url: string }] | undefined {
  if (!absoluteUrl.startsWith("http://") && !absoluteUrl.startsWith("https://")) {
    return undefined;
  }
  return [{ url: absoluteUrl }];
}

function formatDate(iso: string | null) {
  if (!iso) return "";
  try {
    return new Date(iso).toLocaleDateString("vi-VN", {
      year: "numeric",
      month: "long",
      day: "numeric",
    });
  } catch {
    return "";
  }
}

function articleJsonLd(post: PublicPostDetail, slug: string): Record<string, unknown> {
  const origin = getSiteOrigin();
  const headline = postDocumentTitle(post);
  const description = postMetaDescription(post);
  const imageUrl = postShareImageAbsolute(post);
  const images =
    imageUrl.startsWith("http://") || imageUrl.startsWith("https://") ? [imageUrl] : undefined;

  const publisher: Record<string, unknown> =
    origin != null
      ? { "@id": `${origin}/#organization` }
      : { "@type": "Organization", name: "Cổ Thư Kỳ Phổ" };

  const node: Record<string, unknown> = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline,
    ...(description ? { description } : {}),
    ...(post.publishedAt ? { datePublished: post.publishedAt } : {}),
    author: { "@type": "Organization", name: "Cổ Thư Kỳ Phổ" },
    publisher,
    articleSection: post.category.name,
    ...(images ? { image: images } : {}),
  };

  if (origin) {
    const pageUrl = `${origin}/posts/${encodeURIComponent(slug)}`;
    node.url = pageUrl;
    node.mainEntityOfPage = { "@type": "WebPage", "@id": pageUrl };
    node.isPartOf = { "@id": `${origin}/#website` };
  }

  return node;
}

export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
  let slug: string;
  try {
    slug = (await params).slug;
  } catch {
    return { title: "Bài viết" };
  }

  try {
    const post = await fetchPublicPostBySlug(slug);
    if (!post) {
      return { title: "Không tìm thấy" };
    }

    const title = postDocumentTitle(post);
    const description = postMetaDescription(post);
    const shareImage = postShareImageAbsolute(post);
    const ogImages = openGraphImageEntry(shareImage);

    return {
      title,
      description,
      openGraph: {
        title,
        description,
        type: "article",
        ...(post.publishedAt ? { publishedTime: post.publishedAt } : {}),
        ...(ogImages ? { images: ogImages } : {}),
      },
    };
  } catch {
    return { title: "Bài viết", description: "Cổ Thư Kỳ Phổ" };
  }
}

export default async function PostDetailPage({ params }: PageProps) {
  const { slug } = await params;
  const post = await fetchPublicPostBySlug(slug);
  if (!post) notFound();

  const safeHtml = sanitizePostHtml(post.content);
  const showBody = hasVisibleHtmlContent(safeHtml);
  const hero = absoluteFromApiPath(post.featuredImage);

  return (
    <main className="mx-auto max-w-3xl px-4 py-16 sm:px-8 sm:py-20">
      <JsonLd data={articleJsonLd(post, slug)} />
      <p className="text-sm">
        <Link href="/posts" className="ctkp-text-link text-amber-200/60 hover:text-amber-100/90">
          ← Về sổ bài
        </Link>
      </p>

      <article className="mt-8">
        <div className="ctkp-rule mb-8 w-16" aria-hidden />

        <p className="ctkp-eyebrow tracking-[0.32em]">
          <Link
            href={`/categories/${encodeURIComponent(post.category.slug)}`}
            className="transition-colors duration-200 ease-ctkp hover:text-[#d4a89a]/90"
          >
            {post.category.name}
          </Link>
        </p>

        <h1 className="font-ctkp-display mt-4 text-pretty text-[clamp(1.65rem,5.5vw,2.35rem)] font-semibold leading-[1.15] tracking-tight text-stone-100 sm:text-[2.35rem]">
          {post.title}
        </h1>

        {post.publishedAt ? (
          <time
            className="mt-4 block text-sm tracking-wide text-amber-200/40"
            dateTime={post.publishedAt}
          >
            {formatDate(post.publishedAt)}
          </time>
        ) : null}

        {hero ? (
          <figure className="mt-10 overflow-hidden rounded-xl border border-stone-800/45 bg-black/25 ring-1 ring-[#3d3428]/35">
            <PostFeaturedImage
              src={hero}
              alt={`Ảnh bìa — ${post.title}`}
              variant="cover"
              className={postFeaturedAspectClass}
            />
          </figure>
        ) : null}

        {post.excerpt ? (
          <p className="font-ctkp-display mt-8 border-l-2 border-amber-600/45 pl-4 text-base italic leading-relaxed text-stone-400 sm:mt-10 sm:pl-5 sm:text-lg">
            {post.excerpt}
          </p>
        ) : null}

        <div className="ctkp-article-sheet mt-10 rounded-xl px-4 py-7 sm:mt-12 sm:px-10 sm:py-10">
          <p className="mb-8 text-center text-[10px] uppercase tracking-[0.45em] text-stone-500">
            Chính văn
          </p>
          {showBody ? (
            <PostBody html={safeHtml} />
          ) : (
            <p className="text-center text-sm italic text-stone-500">
              Bài chưa có phần chính văn hoặc nội dung đã được lọc an toàn.
            </p>
          )}
        </div>
      </article>
    </main>
  );
}
