import { notFound } from "next/navigation";
import prisma from "@/lib/prisma";
import Link from "next/link";
import type { Metadata } from "next";
import { auth } from "@/lib/auth";
import { photoUrl } from "@/lib/media";
import { getModelTypeString } from "@/lib/polymorphic";
import { PhotoLightbox } from "@/components/shared/photo-lightbox";

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

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

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

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { id } = await params;
  const gallery = await prisma.gallery.findUnique({
    where: { id: Number(id) },
    include: {
      user: { select: { id_aw: true, username: true } },
      photos: { orderBy: { sort_order: "asc" }, take: 1, select: { photo: true } },
    },
  });
  if (!gallery) return { title: "Gallery Not Found" };
  const title = `${gallery.name} — Gallery by ${gallery.user.username} | AdultWorld`;
  const description = gallery.description?.slice(0, 160) || `Photo gallery from ${gallery.user.username}`;
  const url = `${baseUrl}/gallery/show/${id}`;
  const cover = gallery.photos[0]?.photo
    ? [{ url: photoUrl(gallery.photos[0].photo, gallery.user.id_aw) }]
    : [];
  return {
    title,
    description,
    alternates: { canonical: url },
    openGraph: { title, description, url, images: cover, type: "website" },
    twitter: { card: "summary_large_image", title, description, images: cover.map((i) => i.url) },
  };
}

export default async function ShowGalleryPage({ params }: Props) {
  const { id } = await params;
  const galleryId = Number(id);
  const gallery = await prisma.gallery.findUnique({
    where: { id: galleryId, user: { is: {} } },
    include: {
      photos: { orderBy: { sort_order: "asc" } },
      user: { select: { id: true, id_aw: true, username: true } },
    },
  });

  if (!gallery) notFound();

  // Paywall: anyone seeing the URL used to get every full-size photo regardless
  // of credit price. Owner + free galleries stay open; everyone else needs a
  // matching purchase row.
  const session = await auth();
  const viewerId = session?.user?.id ? Number(session.user.id) : null;
  const isOwner = viewerId !== null && viewerId === gallery.user.id;
  const isPaid = gallery.credits > 0;
  let hasAccess = !isPaid || isOwner;
  if (isPaid && !isOwner && viewerId !== null) {
    const purchase = await prisma.purchase.findFirst({
      where: {
        user_id: viewerId,
        purchasable_type: getModelTypeString("Gallery"),
        purchasable_id: gallery.id,
      },
      select: { id: true },
    });
    if (purchase) hasAccess = true;
  }

  const visiblePhotos = hasAccess ? gallery.photos : [];

  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "ImageGallery",
    name: gallery.name,
    url: `${baseUrl}/gallery/show/${id}`,
    ...(gallery.description && { description: gallery.description }),
    author: {
      "@type": "Person",
      name: gallery.user.username,
      url: `${baseUrl}/view/${gallery.user.id_aw}`,
    },
    image: visiblePhotos.map((p) => ({
      "@type": "ImageObject",
      url: photoUrl(p.photo, gallery.user.id_aw),
    })),
  };

  const breadcrumbsLd = {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    itemListElement: [
      { "@type": "ListItem", position: 1, name: "Home", item: baseUrl },
      { "@type": "ListItem", position: 2, name: "Galleries", item: `${baseUrl}/galleries` },
      { "@type": "ListItem", position: 3, name: gallery.name, item: `${baseUrl}/gallery/show/${id}` },
    ],
  };

  return (
    <div className="max-w-4xl mx-auto">
      <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
      <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbsLd) }} />
      <div className="mb-6">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-3xl font-bold text-text">{gallery.name}</h1>
            <p className="text-text-muted mt-1">
              By{" "}
              <Link href={`/view/${gallery.user.id_aw}`} className="text-primary hover:text-primary-dark">
                {gallery.user.username}
              </Link>
              {gallery.credits > 0 && (
                <span className="ml-2 bg-primary/20 text-primary text-xs px-2 py-0.5 rounded-full">Premium</span>
              )}
            </p>
          </div>
          <Link href="/manage/galleries" className="text-text-muted hover:text-text text-sm">
            Back to galleries
          </Link>
        </div>
        {gallery.description && (
          <p className="text-text-muted mt-3">{gallery.description}</p>
        )}
      </div>

      {gallery.photos.length === 0 ? (
        <div className="bg-surface rounded-lg p-12 text-center text-text-muted">
          This gallery has no photos yet.
        </div>
      ) : !hasAccess ? (
        <div className="bg-surface rounded-lg p-12 text-center space-y-4">
          {gallery.cover && (
            <img
              src={photoUrl(gallery.cover, gallery.user.id_aw)}
              alt={`${gallery.name} preview`}
              className="mx-auto max-h-72 rounded-md object-cover blur-sm"
            />
          )}
          <p className="text-text-muted">
            This gallery contains <strong>{gallery.photos.length}</strong> premium photos.
          </p>
          <Link
            href={viewerId ? `/credits/buy?return=${encodeURIComponent(`/gallery/show/${id}`)}` : "/login"}
            className="inline-block bg-primary text-white px-6 py-2 rounded-lg hover:bg-primary-dark transition-colors"
          >
            Unlock for {gallery.credits} credits
          </Link>
        </div>
      ) : (
        <PhotoLightbox
          photos={visiblePhotos.map((p) => ({
            id: p.id,
            src: photoUrl(p.photo, gallery.user.id_aw) ?? "",
          }))}
          alt={`${gallery.name} — photo by ${gallery.user.username}`}
        />
      )}
    </div>
  );
}
