import prisma from "@/lib/prisma";
import Link from "next/link";
import { notFound } from "next/navigation";
import type { Metadata } from "next";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { auth } from "@/lib/auth";
import { getModelTypeString } from "@/lib/polymorphic";

// Per-user paywall state cannot be cached.
export const dynamic = "force-dynamic";

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

const baseUrl = process.env.NEXT_PUBLIC_APP_URL || "https://www.adultworld.ai";

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { id } = await params;
  const story = await prisma.erotica.findUnique({
    where: { id: Number(id) },
    select: { title: true, content: true, created_at: true, updated_at: true },
  });
  if (!story) return { title: "Story Not Found" };
  const description = story.content?.slice(0, 160) || "";
  const url = `${baseUrl}/erotica/show/${id}`;
  return {
    title: story.title || "Erotica",
    description,
    alternates: { canonical: url },
    openGraph: {
      type: "article",
      title: story.title || "Erotica",
      description,
      url,
      publishedTime: story.created_at?.toISOString(),
      modifiedTime: story.updated_at?.toISOString(),
    },
    twitter: {
      card: "summary",
      title: story.title || "Erotica",
      description,
    },
  };
}

export default async function EroticaShowPage({ params }: Props) {
  const { id } = await params;
  const story = await prisma.erotica.findUnique({
    where: { id: Number(id) },
    include: {
      user: { select: { id: true, id_aw: true, username: true } },
    },
  });

  if (!story) notFound();

  // Paywall — owner + free stories stay open; paid stories require purchase.
  const session = await auth();
  const viewerId = session?.user?.id ? Number(session.user.id) : null;
  const isOwner = viewerId !== null && story.user && viewerId === story.user.id;
  const isPaid = story.credits > 0;
  let hasAccess = !isPaid || isOwner;
  if (isPaid && !isOwner && viewerId !== null) {
    const purchase = await prisma.purchase.findFirst({
      where: {
        user_id: viewerId,
        purchasable_type: getModelTypeString("Erotica"),
        purchasable_id: story.id,
      },
      select: { id: true },
    });
    if (purchase) hasAccess = true;
  }

  const fullContent = story.content || "";
  const teaser = fullContent.slice(0, 200);

  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "CreativeWork",
    name: story.title,
    url: `${baseUrl}/erotica/show/${id}`,
    inLanguage: "en",
    isAccessibleForFree: !story.credits || story.credits === 0,
    datePublished: story.created_at?.toISOString(),
    dateModified: story.updated_at?.toISOString(),
    ...(story.user && {
      author: { "@type": "Person", name: story.user.username, url: `${baseUrl}/view/${story.user.id_aw}` },
    }),
    // Crawlers should only see the body for free stories. Premium stories
    // expose the teaser only — same content the unauthenticated UI shows.
    ...(fullContent && { text: hasAccess ? fullContent.slice(0, 500) : teaser }),
  };

  return (
    <div className="max-w-3xl mx-auto">
      <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
      <nav className="text-sm text-text-muted mb-6">
        <Link href="/erotica" className="hover:text-gold">Erotica</Link>
        <span className="mx-2">›</span>
        <span className="text-text">{story.title}</span>
      </nav>

      <h1 className="text-3xl font-heading font-bold text-text mb-4">{story.title}</h1>

      <div className="flex items-center gap-4 text-sm text-text-muted mb-8">
        {story.user && (
          <Link href={`/view/${story.user.id_aw}`} className="hover:text-gold">
            by {story.user.username}
          </Link>
        )}
        <span>{new Date(story.created_at).toLocaleDateString("en-US", { dateStyle: "long" })}</span>
        {story.credits > 0 ? (
          <span className="bg-gold/20 text-gold text-xs px-2 py-0.5 rounded">{story.credits} credits</span>
        ) : (
          <span className="text-green-400 text-xs">Free</span>
        )}
      </div>

      <div className="prose prose-lg prose-invert max-w-none
        prose-headings:text-text prose-headings:font-bold
        prose-h2:mt-10 prose-h2:mb-4 prose-h3:mt-8 prose-h3:mb-3
        prose-p:text-text-muted prose-p:leading-relaxed prose-p:mb-5
        prose-a:text-gold prose-a:no-underline hover:prose-a:underline
        prose-strong:text-text
        prose-blockquote:border-gold prose-blockquote:text-text-muted prose-blockquote:my-6
        prose-hr:my-8 prose-hr:border-surface-light">
        <ReactMarkdown remarkPlugins={[remarkGfm]}>
          {hasAccess ? fullContent : `${teaser}${fullContent.length > 200 ? "…" : ""}`}
        </ReactMarkdown>
      </div>

      {!hasAccess && (
        <div className="mt-8 bg-surface rounded-lg p-6 text-center space-y-3">
          <p className="text-text-muted">
            Continue reading — this story unlocks for <strong>{story.credits} credits</strong>.
          </p>
          <Link
            href={viewerId ? `/credits/buy?return=${encodeURIComponent(`/erotica/show/${id}`)}` : "/login"}
            className="inline-block bg-primary text-white px-6 py-2 rounded-lg hover:bg-primary-dark transition-colors"
          >
            Unlock for {story.credits} credits
          </Link>
        </div>
      )}

      <div className="mt-12 pt-6 border-t border-surface-light flex items-center justify-between">
        <Link href="/erotica" className="text-text-muted hover:text-gold transition-colors">
          ← Back to Erotica
        </Link>
        {story.user && (
          <Link href={`/view/${story.user.id_aw}`} className="text-gold hover:text-gold-light transition-colors">
            View {story.user.username}&apos;s Profile
          </Link>
        )}
      </div>
    </div>
  );
}
