import { notFound } from 'next/navigation';
import type { Metadata } from 'next';
import { prisma } from '@/lib/db/client';
import { buildPageMetadata, truncateForMeta } from '@/lib/seo/metadata';
import { buildVideoGameSchema, buildFaqSchema, buildBreadcrumbSchema } from '@/lib/content/schema';
import { JsonLd } from '@/components/ui/JsonLd';
import { Breadcrumb } from '@/components/games/Breadcrumb';
import { GameHero } from '@/components/games/GameHero';
import { GameInfoPanel } from '@/components/games/GameInfoPanel';
import { GameGallery } from '@/components/games/GameGallery';
import { GameFAQ } from '@/components/games/GameFAQ';
import { ProsCons } from '@/components/games/ProsCons';
import { RelatedGames } from '@/components/games/RelatedGames';
import { LatestUpdates } from '@/components/games/LatestUpdates';
import { CTA } from '@/components/games/CTA';
import { SourceCredit } from '@/components/games/SourceCredit';
import type { FaqItem } from '@/lib/content/types';

export const revalidate = 3600; // ISR: pages refresh at most hourly; refresh-stale/generate-content jobs drive real updates
export const dynamicParams = true;

const PLAY_URL = process.env.GAMESJI_PLAY_URL ?? 'https://gamesji.com/games';

async function getPublishedGame(slug: string) {
  const game = await prisma.game.findUnique({
    where: { slug },
    include: { content: true },
  });
  // Visibility is based on "has this game ever cleared the quality gate
  // and still has content", not on the current status string. That's
  // deliberate: while a NEEDS_REFRESH/GENERATING regeneration is in
  // flight (or fails), the page keeps serving its last known-good
  // content instead of 404ing — see generate-content/route.ts, which
  // only overwrites content on a passing regeneration. EXCLUDED and
  // never-published (DISCOVERED/PENDING_REVIEW-only) games stay hidden.
  if (!game || !game.content || game.publishedAt === null || game.status === 'EXCLUDED') return null;
  return game;
}

// Pre-render only the most-established pages at build time; everything
// else is generated on first request and cached (ISR), which is the right
// tradeoff for a catalog that grows continuously instead of all at once.
export async function generateStaticParams() {
  const top = await prisma.game.findMany({
    where: { status: 'PUBLISHED' },
    orderBy: { igdbRatingCount: 'desc' },
    take: 500,
    select: { slug: true },
  });
  return top.map((g) => ({ slug: g.slug }));
}

export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
  const { slug } = await params;
  const game = await getPublishedGame(slug);
  if (!game || !game.content) {
    return buildPageMetadata({
      title: 'Game not found',
      description: 'This page is not available.',
      path: `/games/${slug}`,
      noindex: true,
    });
  }

  return buildPageMetadata({
    title: game.content.metaTitle,
    description: truncateForMeta(game.content.metaDescription, 155),
    path: `/games/${game.slug}`,
    image: game.coverUrl,
    type: 'article',
  });
}

export default async function GamePage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const game = await getPublishedGame(slug);

  // DISCOVERED / GENERATING / PENDING_REVIEW / EXCLUDED games all 404 here
  // — this is the hard backstop that keeps anything short of PUBLISHED
  // off the public internet even if a slug is guessed or linked early.
  if (!game || !game.content) notFound();

  const [related, news] = await Promise.all([
    prisma.game.findMany({
      where: {
        status: 'PUBLISHED',
        slug: { not: game.slug },
        genres: { hasSome: game.genres },
      },
      orderBy: { igdbRatingCount: 'desc' },
      take: 6,
      select: { slug: true, name: true, coverUrl: true, genres: true, releaseDate: true, igdbRating: true },
    }),
    prisma.gameNewsItem.findMany({
      where: { gameId: game.id },
      include: { newsItem: true },
      orderBy: { newsItem: { publishedAt: 'desc' } },
      take: 5,
    }),
  ]);

  const breadcrumbItems = [
    { name: 'Home', href: '/' },
    { name: 'Games', href: '/games' },
    { name: game.name, href: `/games/${game.slug}` },
  ];
  const faqs = game.content.faqs as unknown as FaqItem[];

  return (
    <>
      <JsonLd data={buildVideoGameSchema(game)} />
      <JsonLd data={buildFaqSchema(faqs)} />
      <JsonLd data={buildBreadcrumbSchema(breadcrumbItems.map((b) => ({ name: b.name, url: b.href })))} />

      <div className="mx-4 mt-4 sm:mx-6 lg:mx-auto lg:max-w-7xl">
        <Breadcrumb items={breadcrumbItems} />
      </div>

      <GameHero
        name={game.name}
        tagline={game.content.overview.split('\n')[0]?.slice(0, 220) ?? game.summary ?? ''}
        coverUrl={game.coverUrl}
        releaseDate={game.releaseDate}
        genres={game.genres}
        platforms={game.platforms}
        rating={game.igdbRating}
        ratingCount={game.igdbRatingCount}
        playUrl={PLAY_URL}
      />

      <div className="mx-4 my-10 grid gap-8 sm:mx-6 lg:mx-auto lg:max-w-7xl lg:grid-cols-[minmax(0,1fr)_320px]">
        <div className="space-y-10">
          <section aria-labelledby="overview-heading">
            <h2 id="overview-heading" className="stat-label mb-3 !text-signal">
              Overview
            </h2>
            <div className="prose-content whitespace-pre-line">{game.content.overview}</div>
          </section>

          <section aria-labelledby="gameplay-heading">
            <h2 id="gameplay-heading" className="stat-label mb-3 !text-signal">
              Gameplay
            </h2>
            <div className="prose-content whitespace-pre-line">{game.content.gameplay}</div>
          </section>

          <section aria-labelledby="features-heading">
            <h2 id="features-heading" className="stat-label mb-3 !text-signal">
              Features
            </h2>
            <div className="prose-content whitespace-pre-line">{game.content.features}</div>
          </section>

          <GameGallery name={game.name} screenshots={game.screenshots} videoIds={game.videoIds} />

          <section aria-labelledby="guide-heading" className="space-y-6">
            <h2 id="guide-heading" className="stat-label !text-signal">
              Guides &amp; Tips
            </h2>
            <div className="hud-panel-sm p-5">
              <h3 className="mb-2 font-display font-semibold">Beginner Guide</h3>
              <p className="prose-content whitespace-pre-line">{game.content.beginnerGuide}</p>
            </div>
            <div className="hud-panel-sm p-5">
              <h3 className="mb-2 font-display font-semibold">How to Play</h3>
              <p className="prose-content whitespace-pre-line">{game.content.howToPlay}</p>
            </div>
            <div className="hud-panel-sm p-5">
              <h3 className="mb-2 font-display font-semibold">Tips &amp; Tricks</h3>
              <p className="prose-content whitespace-pre-line">{game.content.tipsAndTricks}</p>
            </div>
          </section>

          <ProsCons pros={game.content.pros} cons={game.content.cons} />

          <section aria-labelledby="alternatives-heading">
            <h2 id="alternatives-heading" className="stat-label mb-3 !text-signal">
              Games Like This
            </h2>
            <p className="prose-content whitespace-pre-line">{game.content.alternatives}</p>
          </section>

          <GameFAQ faqs={faqs} />

          <LatestUpdates
            items={news.map((n) => ({
              id: n.newsItem.id,
              title: n.newsItem.title,
              rewrittenSummary: n.newsItem.rewrittenSummary,
              sourceName: n.newsItem.sourceName,
              sourceUrl: n.newsItem.sourceUrl,
              publishedAt: n.newsItem.publishedAt,
            }))}
          />

          <RelatedGames games={related} />

          <SourceCredit />
        </div>

        <div className="lg:sticky lg:top-20 lg:h-fit">
          <GameInfoPanel
            developers={game.developers}
            publishers={game.publishers}
            platforms={game.platforms}
            genres={game.genres}
            gameModes={game.gameModes}
            ageRating={game.ageRating}
            releaseDate={game.releaseDate}
            officialUrl={game.officialUrl}
          />
        </div>
      </div>

      <div className="mx-4 mb-16 sm:mx-6 lg:mx-auto lg:max-w-7xl">
        <CTA gameName={game.name} playUrl={PLAY_URL} />
      </div>
    </>
  );
}
