import type { Metadata } from "next";
import Image from "next/image";
import Link from "next/link";
import { notFound } from "next/navigation";
import { ArrowLeft, ArrowUpRight, CalendarDays, Clock } from "lucide-react";

import { BlogBodyRenderer } from "@/components/BlogBodyRenderer";
import { serverApiBaseUrl } from "@/lib/api-url";
import type { BlogPost } from "@/lib/blogs";
import { normalizeBlogPost } from "@/lib/normalize-blog";
import { routePath } from "@/lib/route-url";
import { JsonLd, absoluteSiteUrl, breadcrumbJsonLd, siteUrl } from "@/lib/seo";

type SeoBlogPost = BlogPost & {
  metaDescription?: string;
  ogDescription?: string;
  metaImage?: string;
  ogImage?: string;
  createdAt?: string;
};

type BlogDetailPageProps = {
  params: Promise<{
    slug: string;
  }>;
  searchParams?: Promise<{
    debug?: string;
  }>;
};

export const dynamic = "force-dynamic";

type BlogLoadError = {
  debugId: string;
  slug: string;
  apiUrl: string;
  status?: number;
  statusText?: string;
  responseBody?: string;
  message?: string;
};

type BlogLoadResult = {
  post: SeoBlogPost | null;
  error: BlogLoadError | null;
};

function createBlogDebugId() {
  return `blog-page-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
}

function getErrorMessage(error: unknown) {
  if (error instanceof Error) {
    return error.message;
  }

  return String(error);
}

function blogPostingJsonLd(post: SeoBlogPost) {
  const image = post.ogImage ?? post.metaImage ?? post.image;

  return {
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "@id": `${absoluteSiteUrl(`/blog/${post.slug}/`)}#blogposting`,
    headline: post.title,
    description: post.metaDescription ?? post.excerpt,
    image: absoluteSiteUrl(image),
    datePublished: post.createdAt ?? post.date,
    dateModified: post.createdAt ?? post.date,
    mainEntityOfPage: absoluteSiteUrl(`/blog/${post.slug}/`),
    author: {
      "@type": "Organization",
      name: "Ride N Revive",
      url: `${siteUrl}/`,
    },
    publisher: {
      "@id": `${siteUrl}/#organization`,
    },
  };
}

async function getDatabaseBlogPost(slug: string, debug = false): Promise<BlogLoadResult> {
  const debugId = createBlogDebugId();

  const apiUrl = `${serverApiBaseUrl}/api/blogs/${slug}${debug ? "?debug=1" : ""}`;

  try {
    const response = await fetch(apiUrl, {
      cache: "no-store",
    });

    if (!response.ok) {
      const responseBody = await response.text();

      const error = {
        debugId,
        slug,
        apiUrl,
        status: response.status,
        statusText: response.statusText,
        responseBody,
      };

      console.error(`[${debugId}] Blog detail API returned an error`, error);

      return { post: null, error };
    }

    const data = (await response.json()) as {
      blog?: SeoBlogPost;
    };

    const post = normalizeBlogPost(data.blog);

    if (!post) {
      const error = {
        debugId,
        slug,
        apiUrl,
        message: "Blog API returned a response, but the blog payload was missing required fields.",
        responseBody: JSON.stringify(data),
      };

      console.error(`[${debugId}] Blog detail payload could not be normalized`, error);

      return { post: null, error };
    }

    return {
      post,
      error: null,
    };
  } catch (error: unknown) {
    const loadError = {
      debugId,
      slug,
      apiUrl,
      message: getErrorMessage(error),
    };

    console.error(`[${debugId}] Blog detail API request failed`, loadError);

    return {
      post: null,
      error: loadError,
    };
  }
}

async function getDatabaseBlogPosts(): Promise<SeoBlogPost[]> {
  try {
    const response = await fetch(`${serverApiBaseUrl}/api/blogs`, {
      cache: "no-store",
    });

    if (!response.ok) {
      return [];
    }

    const data = (await response.json()) as {
      blogs?: SeoBlogPost[];
    };

    return (data.blogs ?? [])
      .map((blog) => normalizeBlogPost(blog))
      .filter((blog): blog is SeoBlogPost => blog !== null);
  } catch {
    return [];
  }
}

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

  const { post } = await getDatabaseBlogPost(slug);

  if (!post) {
    return {
      title: "Vehicle Care Blog",
      description:
        "Read Ride N Revive vehicle care guides for car service, bike maintenance, repairs, and doorstep support.",
      alternates: {
        canonical: "/blog",
      },
    };
  }

  return {
    title: post.title,
    description: post.metaDescription ?? post.excerpt,
    alternates: {
      canonical: `/blog/${post.slug}`,
    },
    openGraph: {
      title: `${post.title} | Ride N Revive`,
      description: post.ogDescription ?? post.metaDescription ?? post.excerpt,
      url: `/blog/${post.slug}`,
      type: "article",
      images: [post.ogImage ?? post.metaImage ?? post.image],
    },
    twitter: {
      card: "summary_large_image",
      title: `${post.title} | Ride N Revive`,
      description: post.ogDescription ?? post.metaDescription ?? post.excerpt,
      images: [post.ogImage ?? post.metaImage ?? post.image],
    },
  };
}

export default async function BlogDetailPage({ params, searchParams }: BlogDetailPageProps) {
  const { slug } = await params;

  const resolvedSearchParams = searchParams ? await searchParams : {};

  const debug = resolvedSearchParams.debug === "1";

  const { post, error } = await getDatabaseBlogPost(slug, debug);

  if (!post) {
    if (debug && error) {
      return <BlogDebugError error={error} />;
    }

    notFound();
  }

  const relatedPosts = (await getDatabaseBlogPosts())
    .filter((item) => item.slug !== post.slug)
    .slice(0, 2);

  return (
    <main className="bg-white font-['Space_Grotesk']">
      <JsonLd
        data={[
          blogPostingJsonLd(post),
          breadcrumbJsonLd([
            { name: "Home", path: "/" },
            { name: "Blog", path: "/blog/" },
            { name: post.title, path: `/blog/${post.slug}/` },
          ]),
        ]}
      />
      <section className="bg-white">
        <div className="mx-auto grid max-w-7xl gap-8 px-4 pb-12 pt-28 lg:grid-cols-[0.9fr_1.1fr] lg:items-center 2xl:pb-16 2xl:pt-32">
          <div className="max-w-3xl">
            <p className="inline-flex rounded-full bg-primary/10 px-4 py-2 text-[10px] font-black uppercase tracking-[0.18em] text-primary">
              {post.category}
            </p>

            <h1 className="mt-5 text-3xl font-black leading-tight tracking-tight text-foreground sm:text-4xl lg:text-5xl">
              {post.title}
            </h1>

            <p className="mt-5 max-w-xl text-base font-semibold leading-relaxed text-muted-foreground sm:text-lg">
              {post.excerpt}
            </p>

            <div className="mt-7 flex flex-wrap gap-4 text-sm font-bold text-muted-foreground">
              <span className="inline-flex items-center gap-2">
                <CalendarDays className="h-4 w-4 text-primary" />
                {post.date}
              </span>

              <span className="inline-flex items-center gap-2">
                <Clock className="h-4 w-4 text-primary" />
                {post.readTime}
              </span>
            </div>
          </div>

          <div className="relative aspect-[4/3] w-full overflow-hidden rounded-3xl border border-border bg-slate-100 p-4">
            <Image
              src={post.image}
              alt={post.imageAlt}
              fill
              priority
              sizes="(min-width: 1024px) 620px, 100vw"
              className="object-contain"
            />
          </div>
        </div>
      </section>

      <section className="border-y border-border bg-slate-50">
        <div className="mx-auto max-w-7xl px-4 py-5">
          <Link
            href={routePath("/")}
            className="inline-flex items-center gap-2 text-sm font-bold text-muted-foreground transition-colors hover:text-primary"
          >
            <ArrowLeft className="h-4 w-4" />
            Back to home
          </Link>
        </div>
      </section>

      <section className="mx-auto grid max-w-7xl gap-10 px-4 py-14 lg:grid-cols-[minmax(0,1fr)_320px] 2xl:py-20">
        <article className="rounded-3xl border border-border bg-white p-6 sm:p-8 lg:p-10">
          <div className="space-y-10">
            {post.sections.map((section) => (
              <section key={section.heading}>
                <h2 className="text-3xl font-black tracking-tight text-foreground">
                  {section.heading}
                </h2>

                <div className="mt-5">
                  <BlogBodyRenderer blocks={section.body} />
                </div>
              </section>
            ))}
          </div>

          <div className="mt-12 rounded-3xl bg-primary p-6 text-primary-foreground sm:p-8">
            <h3 className="text-xl font-black tracking-tight text-primary-foreground">
              Need help with your vehicle?
            </h3>

            <p className="mt-2 text-sm leading-relaxed text-primary-foreground/82">
              Ride N Revive can help with doorstep inspection, servicing, and repair support for
              cars and bikes wherever service is available.
            </p>

            <Link
              href={routePath("/contact")}
              className="mt-5 inline-flex rounded-full bg-white px-5 py-3 text-sm font-bold text-primary transition hover:brightness-95"
            >
              Contact Ride N Revive
            </Link>
          </div>
        </article>

        <aside className="space-y-5 lg:sticky lg:top-32 lg:self-start">
          <div className="rounded-3xl border border-border bg-white p-6">
            <p className="text-xs font-black uppercase tracking-[0.18em] text-primary">
              More guides
            </p>

            <div className="mt-5 space-y-5">
              {relatedPosts.map((item) => (
                <Link
                  key={item.slug}
                  href={routePath(`/blog/${item.slug}`)}
                  className="group block border-t border-border pt-5 first:border-t-0 first:pt-0"
                >
                  <p className="text-xs font-bold uppercase tracking-[0.16em] text-muted-foreground">
                    {item.category}
                  </p>

                  <h3 className="mt-2 text-base font-black leading-snug text-foreground group-hover:text-primary">
                    {item.title}
                  </h3>

                  <span className="mt-3 inline-flex items-center gap-1 text-sm font-bold text-primary">
                    Read next
                    <ArrowUpRight className="h-4 w-4" />
                  </span>
                </Link>
              ))}
            </div>
          </div>
        </aside>
      </section>
    </main>
  );
}

function BlogDebugError({ error }: { error: BlogLoadError }) {
  return (
    <main className="min-h-screen bg-slate-950 px-4 py-24 font-['Space_Grotesk'] text-slate-100">
      <section className="mx-auto max-w-4xl rounded-lg border border-red-400/40 bg-red-950/20 p-6">
        <p className="text-xs font-black uppercase tracking-[0.18em] text-red-300">
          Blog detail debug
        </p>

        <h1 className="mt-3 text-3xl font-black tracking-tight">Blog failed to load</h1>

        <p className="mt-3 text-sm font-semibold text-slate-300">
          Match this debug ID with the server logs to see the full backend trace.
        </p>

        <dl className="mt-6 grid gap-4 text-sm md:grid-cols-2">
          <DebugRow label="Debug ID" value={error.debugId} />

          <DebugRow label="Slug" value={error.slug} />

          <DebugRow label="Status" value={error.status ? String(error.status) : "Request failed"} />

          <DebugRow label="Status text" value={error.statusText ?? error.message ?? "-"} />
        </dl>

        <div className="mt-6">
          <p className="text-xs font-black uppercase tracking-[0.16em] text-slate-400">API URL</p>

          <pre className="mt-2 overflow-auto rounded-md bg-slate-900 p-3 text-xs text-slate-200">
            {error.apiUrl}
          </pre>
        </div>

        {error.responseBody ? (
          <div className="mt-6">
            <p className="text-xs font-black uppercase tracking-[0.16em] text-slate-400">
              API response
            </p>

            <pre className="mt-2 max-h-80 overflow-auto whitespace-pre-wrap rounded-md bg-slate-900 p-3 text-xs text-slate-200">
              {error.responseBody}
            </pre>
          </div>
        ) : null}
      </section>
    </main>
  );
}

function DebugRow({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded-md bg-slate-900 p-3">
      <dt className="text-xs font-black uppercase tracking-[0.14em] text-slate-500">{label}</dt>

      <dd className="mt-1 break-words font-semibold text-slate-100">{value}</dd>
    </div>
  );
}
