import type { Metadata } from 'next';
import Link from 'next/link';
import { notFound } from 'next/navigation';
import { getDb, isUuid, type Prisma } from '@pintrush/db';
import { ButtonLink } from '@/components/ui/Button';
import { Badge } from '@/components/ui/Badge';
import { formatNumber } from '@/components/host/format';
import { EmptyState, linkStyles, PageHeader, Panel, StatusBadge } from '@/components/host/ui';
import { cn } from '@/lib/cn';
import { requireAdmin } from '@/lib/auth/session';

export const metadata: Metadata = { title: 'Questions' };

const PAGE_SIZE = 25;

function one(v: string | string[] | undefined): string {
  return (Array.isArray(v) ? v[0] : v)?.trim() ?? '';
}

function optionsOf(json: unknown): { id: string; text: string }[] {
  return Array.isArray(json) ? json.flatMap((o) => (o && typeof o === 'object' && 'id' in o && 'text' in o ? [{ id: String(o.id), text: String(o.text) }] : [])) : [];
}

export default async function PackQuestionsPage({
  params,
  searchParams,
}: {
  params: Promise<{ id: string }>;
  searchParams: Promise<Record<string, string | string[] | undefined>>;
}) {
  const { id } = await params;
  await requireAdmin(`/admin/packs/${encodeURIComponent(id)}`);
  if (!isUuid(id)) notFound();
  const sp = await searchParams;
  const q = one(sp.q).slice(0, 100);
  const category = one(sp.category).slice(0, 64);
  const difficulty = one(sp.difficulty);
  const status = one(sp.status) === 'RETIRED' ? 'RETIRED' : 'ACTIVE';
  const page = Math.max(1, Math.min(1000, Math.floor(Number(one(sp.page)) || 1)));

  const db = getDb();
  const pack = await db.questionPack.findUnique({ where: { id }, select: { id: true, name: true, key: true, status: true, categories: true } });
  if (!pack) notFound();
  const categories = Array.isArray(pack.categories) ? (pack.categories as { key: string; label: string }[]) : [];

  const where: Prisma.QuestionWhereInput = { packId: pack.id, status };
  if (category) where.category = category;
  if (difficulty === 'STANDARD' || difficulty === 'DIFFICULT') where.difficulty = difficulty;
  if (q) where.OR = [{ prompt: { contains: q, mode: 'insensitive' } }, { contentKey: { contains: q, mode: 'insensitive' } }];
  const [total, questions] = await Promise.all([
    db.question.count({ where }),
    db.question.findMany({ where, orderBy: [{ category: 'asc' }, { contentKey: 'asc' }], skip: (page - 1) * PAGE_SIZE, take: PAGE_SIZE }),
  ]);
  const pages = Math.max(1, Math.ceil(total / PAGE_SIZE));
  const labelOf = (key: string) => categories.find((c) => c.key === key)?.label ?? key;
  const hrefFor = (overrides: Record<string, string | number>) => {
    const params = new URLSearchParams();
    const merged = { q, category, difficulty, status: status === 'RETIRED' ? 'RETIRED' : '', page: 1, ...overrides };
    for (const [k, v] of Object.entries(merged)) if (v !== '' && !(k === 'page' && v === 1)) params.set(k, String(v));
    const qs = params.toString();
    return `/admin/packs/${pack.id}${qs ? `?${qs}` : ''}`;
  };

  return (
    <div className="flex flex-col gap-6">
      <nav aria-label="Breadcrumb" className="text-sm">
        <Link href="/admin/packs" className={linkStyles}>
          ← All packs
        </Link>
      </nav>
      <PageHeader kicker={pack.key} title={pack.name} description={<StatusBadge status={pack.status} />} />
      <Panel>
        <form method="get" className="grid gap-3 md:grid-cols-[1fr_14rem_10rem_9rem_auto] md:items-end">
          <label className="flex flex-col gap-2 text-sm font-semibold">
            Search question text
            <input name="q" defaultValue={q} maxLength={100} type="search" className="min-h-12 rounded-xl border border-line-strong bg-night/70 px-4 text-base font-normal text-fg focus-visible:border-cyan" />
          </label>
          <label className="flex flex-col gap-2 text-sm font-semibold">
            Category
            <select name="category" defaultValue={category} className="min-h-12 rounded-xl border border-line-strong bg-night/70 px-3 text-base font-normal text-fg">
              <option value="">All categories</option>
              {categories.map((c) => (
                <option key={c.key} value={c.key}>
                  {c.label}
                </option>
              ))}
            </select>
          </label>
          <label className="flex flex-col gap-2 text-sm font-semibold">
            Difficulty
            <select name="difficulty" defaultValue={difficulty} className="min-h-12 rounded-xl border border-line-strong bg-night/70 px-3 text-base font-normal text-fg">
              <option value="">Any</option>
              <option value="STANDARD">Standard</option>
              <option value="DIFFICULT">Difficult</option>
            </select>
          </label>
          <label className="flex flex-col gap-2 text-sm font-semibold">
            Status
            <select name="status" defaultValue={status === 'RETIRED' ? 'RETIRED' : ''} className="min-h-12 rounded-xl border border-line-strong bg-night/70 px-3 text-base font-normal text-fg">
              <option value="">Active</option>
              <option value="RETIRED">Retired</option>
            </select>
          </label>
          <button type="submit" className="min-h-12 rounded-xl bg-violet-strong px-5 font-semibold text-white hover:bg-violet-deep">
            Filter
          </button>
        </form>
      </Panel>

      <p className="text-sm text-muted" aria-live="polite">
        {formatNumber(total)} question{total === 1 ? '' : 's'}
        {pages > 1 && ` · page ${page} of ${pages}`}
      </p>

      {questions.length === 0 ? (
        <EmptyState title="No questions match" action={<ButtonLink href={`/admin/packs/${pack.id}`} size="sm" variant="secondary">Clear filters</ButtonLink>} />
      ) : (
        <ol className="flex flex-col gap-3" start={(page - 1) * PAGE_SIZE + 1}>
          {questions.map((question) => (
            <li key={question.id} className="rounded-2xl border border-line bg-surface/85 p-5">
              <div className="flex flex-wrap items-center gap-2 text-xs">
                <Badge tone="cyan">{labelOf(question.category)}</Badge>
                <Badge tone={question.difficulty === 'DIFFICULT' ? 'amber' : 'neutral'}>{question.difficulty.toLowerCase()}</Badge>
                {question.type === 'TRUE_FALSE' && <Badge tone="neutral">true / false</Badge>}
                {question.wildcardEligible && <Badge tone="violet">wildcard</Badge>}
                <span className="text-subtle">{question.contentKey}</span>
              </div>
              <p className="mt-3 font-semibold">{question.prompt}</p>
              <ul className="mt-3 grid gap-2 sm:grid-cols-2">
                {optionsOf(question.options).map((o) => {
                  const correct = o.id === question.correctOptionId;
                  return (
                    <li key={o.id} className={cn('rounded-xl border px-3 py-2 text-sm', correct ? 'border-lime/60 bg-lime/10 text-lime-soft' : 'border-line/70 text-muted')}>
                      {o.text}
                      {correct && <span className="sr-only"> (correct answer)</span>}
                    </li>
                  );
                })}
              </ul>
              {question.explanation && <p className="mt-3 text-sm text-subtle">{question.explanation}</p>}
            </li>
          ))}
        </ol>
      )}

      {pages > 1 && (
        <nav aria-label="Pagination" className="flex items-center justify-between gap-3">
          {page > 1 ? (
            <ButtonLink href={hrefFor({ page: page - 1 })} variant="secondary" size="sm">
              ← Previous
            </ButtonLink>
          ) : (
            <span />
          )}
          {page < pages && (
            <ButtonLink href={hrefFor({ page: page + 1 })} variant="secondary" size="sm">
              Next →
            </ButtonLink>
          )}
        </nav>
      )}
    </div>
  );
}
