/**
 * POST /api/admin/backfill-channel-classification
 * Body: { brandId? } — omit to backfill all brands
 *
 * Classifies all SiteConversion rows where classifiedChannel IS NULL.
 * Processes in batches of 500 for memory efficiency.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireSuperadmin } from "@/lib/admin-auth";
import { classifyChannel, type ChannelKey } from "@/lib/attribution/channel-classifier";

export const dynamic = "force-dynamic";
export const maxDuration = 120;

export async function POST(req: Request) {
  const denied = await requireSuperadmin();
  if (denied) return denied;

  const body = await req.json().catch(() => ({})) as { brandId?: string };

  const where: Record<string, unknown> = { classifiedChannel: null };
  if (body.brandId) where.brandId = body.brandId;

  const brands = body.brandId
    ? [{ id: body.brandId, name: "single" }]
    : await prisma.brand.findMany({
        where: { status: { not: "deleted" } },
        select: { id: true, name: true },
      });

  const results: Array<{
    brand: string;
    totalProcessed: number;
    distribution: Record<string, number>;
    otherPercent: number;
  }> = [];

  for (const brand of brands) {
    let processed = 0;
    const dist: Record<string, number> = {};
    let cursor: string | undefined;

    while (true) {
      // intentionally unfiltered: admin-only endpoint; needs raw or all-time counts
      const rows = await prisma.siteConversion.findMany({
        where: { ...where, brandId: brand.id },
        select: {
          id: true,
          firstTouchChannel: true,
          firstTouchSource: true,
          lastTouchChannel: true,
          lastTouchSource: true,
          pageUrl: true,
          touchpoints: true,
        },
        orderBy: { id: "asc" },
        take: 500,
        ...(cursor ? { skip: 1, cursor: { id: cursor } } : {}),
      });

      if (rows.length === 0) break;
      cursor = rows[rows.length - 1].id;

      const updates = rows.map((row) => {
        const result = classifyChannel({
          firstTouchChannel: row.firstTouchChannel,
          firstTouchSource: row.firstTouchSource,
          lastTouchChannel: row.lastTouchChannel,
          lastTouchSource: row.lastTouchSource,
          pageUrl: row.pageUrl,
          touchpoints: row.touchpoints,
        });

        dist[result.channel] = (dist[result.channel] ?? 0) + 1;

        return prisma.siteConversion.update({
          where: { id: row.id },
          data: {
            classifiedChannel: result.channel,
            classificationReason: result.reasonCode,
            classificationEvidence: JSON.parse(JSON.stringify(result.evidence)),
          },
        });
      });

      await prisma.$transaction(updates);
      processed += rows.length;
    }

    const total = Object.values(dist).reduce((s, n) => s + n, 0);
    const otherCount = dist.other ?? 0;

    results.push({
      brand: brand.name,
      totalProcessed: processed,
      distribution: dist,
      otherPercent: total > 0 ? Math.round((otherCount / total) * 100) : 0,
    });
  }

  return NextResponse.json({ brands: results.length, results });
}
