/**
 * GET /api/admin/debug/conversion-audit?brandId=...&days=30
 *
 * Diagnostic that surfaces exactly what's currently stored in
 * SiteConversion + TrackedEvent for a brand, and flags duplicate
 * rows that the new resolver would have caught. Read-only.
 *
 * Returns:
 *   {
 *     scope: { brandId, days, sinceISO },
 *     siteConversion: {
 *       byType:       [{ type, canonicalType, tier, count }],
 *       bySource:     [{ source, count }],          // from formFields._source
 *       totalCount:   number,
 *       hardCount:    number,
 *       softCount:    number,
 *       unknownCount: number,
 *     },
 *     trackedEvent: {
 *       byEventType: [{ eventType, count }],
 *     },
 *     duplicates: {
 *       count: number,
 *       sample: [{ sessionId, pageUrl, conversionType, count }],
 *     },
 *     hint: human-readable summary
 *   }
 *
 * Lives under /api/admin/* so the admin-host middleware lets it
 * through. Superadmin-gated.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireSuperadmin, withAdminTiming } from "@/lib/admin-auth";
import {
  canonicalConversionType,
  getConversionTier,
  CONVERSION_TYPES,
} from "@/lib/conversion-taxonomy";

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

interface DuplicateRow {
  sessionId: string;
  pageUrl: string;
  conversionType: string;
  cnt: bigint;
}

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

  const { searchParams } = new URL(req.url);
  const brandId = searchParams.get("brandId");
  const days = Math.max(1, Math.min(365, Number(searchParams.get("days") ?? 30)));
  const since = new Date(Date.now() - days * 86_400_000);

  if (!brandId) {
    return NextResponse.json({ error: "brandId required" }, { status: 400 });
  }

  return NextResponse.json(await withAdminTiming("debug.conversion-audit", async () => {
    // ── SiteConversion: groupBy conversionType ──
    // intentionally unfiltered: admin-only endpoint; needs raw or all-time counts
    const byTypeRaw = await prisma.siteConversion.groupBy({
      by: ["conversionType"],
      where: { brandId, timestamp: { gte: since } },
      _count: true,
      orderBy: { _count: { conversionType: "desc" } },
    });

    let totalCount = 0, hardCount = 0, softCount = 0, unknownCount = 0;
    const byType = byTypeRaw.map((row) => {
      const canon = canonicalConversionType(row.conversionType);
      const tier = canon ? getConversionTier(canon) : null;
      const count = row._count;
      totalCount += count;
      if (tier === 1) hardCount += count;
      else if (tier === 2) softCount += count;
      else unknownCount += count;
      return {
        type: row.conversionType,
        canonicalType: canon,
        tier,
        label: canon ? CONVERSION_TYPES[canon].label : null,
        count,
      };
    });

    // ── SiteConversion: source breakdown from formFields._source ──
    // SiteConversion has no native source column today. The resolver +
    // collect writer now stamp formFields._source for every row, but
    // legacy rows (form-phone.js path, pre-resolver) carry the
    // detectionMethod field. Surface both.
    // intentionally unfiltered: admin-only endpoint; needs raw or all-time counts
    const sourceRows = await prisma.siteConversion.findMany({
      where: { brandId, timestamp: { gte: since } },
      select: { formFields: true, detectionMethod: true, formProvider: true },
      take: 50_000,
    });
    const sourceCounts = new Map<string, number>();
    for (const r of sourceRows) {
      const ff = (r.formFields ?? {}) as Record<string, unknown>;
      const fromFf = typeof ff._source === "string" ? ff._source : null;
      const fromDm = typeof r.detectionMethod === "string" ? r.detectionMethod : null;
      const fromFp = typeof r.formProvider === "string" ? r.formProvider : null;
      const src = fromFf ?? fromFp ?? fromDm ?? "(unknown)";
      sourceCounts.set(src, (sourceCounts.get(src) ?? 0) + 1);
    }
    const bySource = Array.from(sourceCounts.entries())
      .sort(([, a], [, b]) => b - a)
      .map(([source, count]) => ({ source, count }));

    // ── TrackedEvent: groupBy eventType for the same window ──
    const tracked = await prisma.trackedEvent.groupBy({
      by: ["eventType"],
      where: {
        trackedSite: { brandId },
        timestamp: { gte: since },
      },
      _count: true,
      orderBy: { _count: { eventType: "desc" } },
      take: 50,
    });
    const byEventType = tracked.map((r) => ({ eventType: r.eventType, count: r._count }));

    // ── Duplicate detection ──
    // The resolver in conversion-resolver.ts dedupes WITHIN a
    // 30-second window per (brand, session, pageUrl). Anything
    // beyond that window legitimately stays as separate rows. This
    // query surfaces duplicates that landed BEFORE the resolver
    // shipped (commit fa7d14a) so the operator can see whether a
    // backfill cleanup is needed.
    const duplicates = await prisma.$queryRaw<DuplicateRow[]>`
      SELECT "sessionId", "pageUrl", "conversionType", COUNT(*) as cnt
      FROM "SiteConversion"
      WHERE "brandId" = ${brandId}
        AND "timestamp" >= ${since}
      GROUP BY "sessionId", "pageUrl", "conversionType"
      HAVING COUNT(*) > 1
      ORDER BY COUNT(*) DESC
      LIMIT 20
    `.catch(() => [] as DuplicateRow[]);

    const duplicateCount = duplicates.reduce((sum, r) => sum + (Number(r.cnt) - 1), 0);

    console.info("[conversion-audit]", { brandId, days, totalCount, hardCount, softCount, byType });
    if (duplicates.length > 0) {
      console.info("[conversion-duplicates]", duplicates.map((d) => ({
        ...d, cnt: Number(d.cnt),
      })));
    }

    return {
      scope: { brandId, days, sinceISO: since.toISOString() },
      siteConversion: {
        byType,
        bySource,
        totalCount,
        hardCount,
        softCount,
        unknownCount,
      },
      trackedEvent: { byEventType },
      duplicates: {
        count: duplicateCount,
        sample: duplicates.map((d) => ({
          sessionId: d.sessionId,
          pageUrl: d.pageUrl,
          conversionType: d.conversionType,
          count: Number(d.cnt),
        })),
      },
      hint: [
        `${totalCount} SiteConversion rows in the last ${days} days.`,
        `Tier 1 (hard): ${hardCount}, Tier 2 (soft): ${softCount}, Unknown: ${unknownCount}.`,
        duplicateCount > 0
          ? `${duplicateCount} duplicate rows detected — likely written before the resolver landed (commit fa7d14a). New writes are deduped.`
          : "No duplicates detected.",
        unknownCount > 0
          ? `${unknownCount} rows have a conversionType the taxonomy doesn't recognise — add the source string to src/lib/conversion-taxonomy.ts.`
          : "All conversion types map to a canonical tier.",
      ].join(" "),
    };
  }));
}
