import type { Metadata } from 'next';
import Link from 'next/link';
import { prisma } from '@/lib/db/client';
import { buildPageMetadata } from '@/lib/seo/metadata';
import { buildItemListSchema } from '@/lib/content/schema';
import { JsonLd } from '@/components/ui/JsonLd';
import { Breadcrumb } from '@/components/games/Breadcrumb';
import { GameCard } from '@/components/games/GameCard';
import type { Prisma } from '@prisma/client';

export const revalidate = 900;

const PAGE_SIZE = 24;
const GENRES = ['Action', 'Adventure', 'RPG', 'Shooter', 'Strategy', 'Simulation', 'Sports', 'Racing', 'Puzzle', 'Battle Royale'];
const PLATFORMS = ['PC (Microsoft Windows)', 'PlayStation 5', 'Xbox Series X|S', 'Nintendo Switch', 'iOS', 'Android'];
const SORTS = [
  { key: 'trending', label: 'Trending' },
  { key: 'rating', label: 'Top Rated' },
  { key: 'newest', label: 'Newest' },
  { key: 'upcoming', label: 'Upcoming' },
  { key: 'az', label: 'A–Z' },
] as const;

interface SearchParams {
  q?: string;
  genre?: string;
  platform?: string;
  sort?: string;
  page?: string;
}

function buildOrderBy(sort?: string): Prisma.GameOrderByWithRelationInput {
  switch (sort) {
    case 'rating':
      return { igdbRating: 'desc' };
    case 'newest':
      return { releaseDate: 'desc' };
    case 'upcoming':
      return { releaseDate: 'asc' };
    case 'az':
      return { name: 'asc' };
    default:
      return { igdbRatingCount: 'desc' };
  }
}

function buildWhere(sp: SearchParams): Prisma.GameWhereInput {
  const where: Prisma.GameWhereInput = { status: 'PUBLISHED' };
  if (sp.q) where.name = { contains: sp.q, mode: 'insensitive' };
  if (sp.genre) where.genres = { has: sp.genre };
  if (sp.platform) where.platforms = { has: sp.platform };
  if (sp.sort === 'upcoming') where.releaseDate = { gte: new Date() };
  return where;
}

export async function generateMetadata({
  searchParams,
}: {
  searchParams: Promise<SearchParams>;
}): Promise<Metadata> {
  const sp = await searchParams;
  const parts = [sp.genre, sp.platform].filter(Boolean);
  const title = parts.length ? `${parts.join(' · ')} Games` : 'Full Game Directory';

  const qs = new URLSearchParams();
  if (sp.genre) qs.set('genre', sp.genre);
  if (sp.platform) qs.set('platform', sp.platform);
  const path = qs.toString() ? `/games?${qs.toString()}` : '/games';

  return buildPageMetadata({
    title,
    description: `Browse ${parts.length ? parts.join(' and ') + ' ' : ''}games with release info, guides, and FAQs — searchable and filterable, updated automatically.`,
    path,
    // Filtered/searched views are useful to users but shouldn't compete
    // with the canonical /games directory for indexing — avoids the
    // "many thin filter-combination pages" pattern Google's scaled
    // content abuse policy flags.
    noindex: Boolean(sp.genre || sp.platform || sp.q || sp.page),
  });
}

export default async function GamesDirectoryPage({ searchParams }: { searchParams: Promise<SearchParams> }) {
  const sp = await searchParams;
  const page = Math.max(1, parseInt(sp.page ?? '1', 10) || 1);
  const where = buildWhere(sp);
  const orderBy = buildOrderBy(sp.sort);

  const [games, total] = await Promise.all([
    prisma.game.findMany({
      where,
      orderBy,
      skip: (page - 1) * PAGE_SIZE,
      take: PAGE_SIZE,
      select: { slug: true, name: true, coverUrl: true, genres: true, releaseDate: true, igdbRating: true },
    }),
    prisma.game.count({ where }),
  ]);

  const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));

  function hrefFor(overrides: Partial<SearchParams>) {
    const merged = { ...sp, ...overrides };
    const params = new URLSearchParams();
    for (const [k, v] of Object.entries(merged)) if (v) params.set(k, String(v));
    const qs = params.toString();
    return `/games${qs ? `?${qs}` : ''}`;
  }

  return (
    <div className="mx-4 mt-6 sm:mx-6 lg:mx-auto lg:max-w-7xl">
      <JsonLd data={buildItemListSchema(games)} />
      <Breadcrumb items={[{ name: 'Home', href: '/' }, { name: 'Games', href: '/games' }]} />

      <h1 className="mt-4 text-3xl font-bold sm:text-4xl">Full Game Directory</h1>
      <p className="prose-content mt-2 max-w-2xl">
        {total.toLocaleString()} games and counting — sourced from official APIs and refreshed automatically.
      </p>

      <form action="/games" className="mt-6 flex gap-2">
        <input
          type="search"
          name="q"
          defaultValue={sp.q}
          placeholder="Search games…"
          className="hud-panel-sm w-full max-w-sm bg-transparent px-4 py-2.5 text-sm outline-none placeholder:text-haze"
        />
        <button type="submit" className="btn-secondary !px-4 !py-2.5 text-sm">
          Search
        </button>
      </form>

      <div className="mt-5 flex flex-wrap items-center gap-2 font-mono text-xs uppercase tracking-wide">
        {SORTS.map((s) => (
          <Link
            key={s.key}
            href={hrefFor({ sort: s.key, page: undefined })}
            className={`chip ${sp.sort === s.key || (!sp.sort && s.key === 'trending') ? '!border-signal !text-signal' : ''}`}
          >
            {s.label}
          </Link>
        ))}
      </div>

      <div className="mt-3 flex flex-wrap gap-2">
        {GENRES.map((g) => (
          <Link
            key={g}
            href={hrefFor({ genre: sp.genre === g ? undefined : g, page: undefined })}
            className={`chip ${sp.genre === g ? '!border-ember !text-ember' : ''}`}
          >
            {g}
          </Link>
        ))}
      </div>
      <div className="mt-2 flex flex-wrap gap-2">
        {PLATFORMS.map((p) => (
          <Link
            key={p}
            href={hrefFor({ platform: sp.platform === p ? undefined : p, page: undefined })}
            className={`chip ${sp.platform === p ? '!border-gold !text-gold' : ''}`}
          >
            {p}
          </Link>
        ))}
      </div>

      {games.length === 0 ? (
        <p className="prose-content mt-16 text-center text-haze">
          No games match those filters yet — the catalog grows continuously, check back soon.
        </p>
      ) : (
        <div className="mt-8 grid grid-cols-2 gap-3 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6">
          {games.map((g) => (
            <GameCard key={g.slug} game={g} />
          ))}
        </div>
      )}

      {totalPages > 1 && (
        <nav aria-label="Pagination" className="mt-10 flex justify-center gap-2 font-mono text-sm">
          {page > 1 && (
            <Link href={hrefFor({ page: String(page - 1) })} className="chip">
              ← Prev
            </Link>
          )}
          <span className="chip !border-signal !text-signal">
            Page {page} / {totalPages}
          </span>
          {page < totalPages && (
            <Link href={hrefFor({ page: String(page + 1) })} className="chip">
              Next →
            </Link>
          )}
        </nav>
      )}
    </div>
  );
}
