import { NextRequest, NextResponse } from 'next/server';
import {
  listRecipientsForCampaign,
  listVariantsForCampaign,
  type RecipientStatus,
  type ListRecipientsOptions,
} from '@/lib/db/recipient-stats-repo';
import { withAuth } from '@/core/auth';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

const VALID_STATUS: RecipientStatus[] = [
  'sent',
  'delivered',
  'opened',
  'clicked',
  'converted',
  'bounced',
  'unsubscribed',
];

const VALID_SORT_BY: NonNullable<ListRecipientsOptions['sortBy']>[] = [
  'lastEventAt',
  'email',
  'firstOpenAt',
  'conversionValueTotal',
];

/**
 * Paginierte Empfänger-Liste für den Stats-Drilldown-Tab.
 *
 * Query-Params:
 *   - limit (default 50, max 200)
 *   - offset (default 0)
 *   - variantId
 *   - status (sent|delivered|opened|clicked|converted|bounced|unsubscribed)
 *   - search (email/firstName/lastName LIKE)
 *   - sortBy (lastEventAt|email|firstOpenAt|conversionValueTotal)
 *   - sortDir (asc|desc, default desc)
 *
 * Response: { ok, rows, total, limit, offset, variants }
 *   variants kommt mit für die Filter-Bar in der UI — spart einen separaten Roundtrip.
 */
export const GET = withAuth<{ params: Promise<{ id: string }> }>(async (req: NextRequest, _ctx, { params }: { params: Promise<{ id: string }> }) => {
  const { id } = await params;
  if (!id) return NextResponse.json({ error: 'Missing campaign id' }, { status: 400 });

  const url = req.nextUrl;
  const limit = Math.max(1, Math.min(200, Number(url.searchParams.get('limit')) || 50));
  const offset = Math.max(0, Number(url.searchParams.get('offset')) || 0);
  const variantId = url.searchParams.get('variantId') ?? undefined;
  const statusRaw = url.searchParams.get('status');
  const status = statusRaw && (VALID_STATUS as string[]).includes(statusRaw)
    ? (statusRaw as RecipientStatus)
    : undefined;
  const search = url.searchParams.get('search')?.trim() || undefined;
  const sortByRaw = url.searchParams.get('sortBy');
  const sortBy = sortByRaw && (VALID_SORT_BY as string[]).includes(sortByRaw)
    ? (sortByRaw as ListRecipientsOptions['sortBy'])
    : undefined;
  const sortDirRaw = url.searchParams.get('sortDir');
  const sortDir = sortDirRaw === 'asc' ? 'asc' : 'desc';

  try {
    const result = listRecipientsForCampaign(id, {
      limit,
      offset,
      variantId,
      status,
      search,
      sortBy,
      sortDir,
    });
    const variants = listVariantsForCampaign(id);

    return NextResponse.json({
      ok: true,
      rows: result.rows,
      total: result.total,
      limit: result.limit,
      offset: result.offset,
      variants,
    });
  } catch (e) {
    return NextResponse.json(
      { error: e instanceof Error ? e.message : 'Recipients lookup failed' },
      { status: 500 },
    );
  }
});
