/**
 * GET /api/admin/export/brand-data
 *
 * Per-brand metrics for the data room. No user PII — only brandId,
 * domain, plan, member count, event/session/conversion counts,
 * latest audit score, feature adoption, created + last-active dates.
 *
 * Always CSV.
 *
 * Superadmin-only.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireSuperadmin, withAdminTiming } from "@/lib/admin-auth";
import { toCsv } from "@/lib/csv";

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

const TOTAL_INSTRUMENTED_ACTIONS = 25;

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

  return withAdminTiming("export.brand-data", async () => {
    const brands = await prisma.brand.findMany({
      include: {
        organization: { select: { _count: { select: { memberships: true } } } },
        trackedSite: { select: { id: true } },
      },
      orderBy: { createdAt: "asc" },
    });

    const brandIds = brands.map((b) => b.id);
    const trackedSiteIds = brands.map((b) => b.trackedSite?.id).filter(Boolean) as string[];

    const [
      eventCounts, sessionCounts, conversionCounts,
      latestAudits, lastActivity, distinctActions,
    ] = await Promise.all([
      trackedSiteIds.length > 0
        ? prisma.trackedEvent.groupBy({ by: ["trackedSiteId"], where: { trackedSiteId: { in: trackedSiteIds } }, _count: true })
        : Promise.resolve([] as Array<{ trackedSiteId: string; _count: number }>),
      trackedSiteIds.length > 0
        ? prisma.trackedSession.groupBy({ by: ["trackedSiteId"], where: { trackedSiteId: { in: trackedSiteIds } }, _count: true })
        : Promise.resolve([] as Array<{ trackedSiteId: string; _count: number }>),
      brandIds.length > 0
        // intentionally unfiltered: admin-only endpoint; needs raw or all-time counts
        ? prisma.siteConversion.groupBy({ by: ["brandId"], where: { brandId: { in: brandIds } }, _count: true })
        : Promise.resolve([] as Array<{ brandId: string; _count: number }>),
      brandIds.length > 0
        ? prisma.technicalAudit.findMany({
            where: { brandId: { in: brandIds } },
            orderBy: { createdAt: "desc" },
            distinct: ["brandId"],
            select: { brandId: true, crawlHealth: true, createdAt: true },
          })
        : Promise.resolve([]),
      brandIds.length > 0
        ? prisma.platformEvent.groupBy({ by: ["brandId"], where: { brandId: { in: brandIds } }, _max: { timestamp: true } })
        : Promise.resolve([] as Array<{ brandId: string | null; _max: { timestamp: Date | null } }>),
      brandIds.length > 0
        ? prisma.platformEvent.groupBy({ by: ["brandId", "action"], where: { brandId: { in: brandIds } }, _count: true })
        : Promise.resolve([] as Array<{ brandId: string | null; action: string }>),
    ]);

    const eventByTrackedSite = new Map(eventCounts.map((e) => [e.trackedSiteId, e._count]));
    const sessionByTrackedSite = new Map(sessionCounts.map((s) => [s.trackedSiteId, s._count]));
    const conversionByBrand = new Map(conversionCounts.map((c) => [c.brandId, c._count]));
    const auditByBrand = new Map(latestAudits.map((a) => [a.brandId, a]));
    const lastActiveByBrand = new Map<string, Date>();
    for (const r of lastActivity) {
      if (r.brandId && r._max.timestamp) lastActiveByBrand.set(r.brandId, r._max.timestamp);
    }
    const actionsByBrand = new Map<string, Set<string>>();
    for (const r of distinctActions) {
      if (!r.brandId) continue;
      const set = actionsByBrand.get(r.brandId) ?? new Set<string>();
      set.add(r.action);
      actionsByBrand.set(r.brandId, set);
    }

    const headers = [
      "brandId", "domain", "plan", "billingCycle", "memberCount",
      "eventCount", "sessionCount", "conversionCount",
      "auditScore", "auditDate",
      "featureAdoptionScore",
      "createdAt", "lastActiveAt",
    ];
    const rows = brands.map((b) => {
      const audit = auditByBrand.get(b.id);
      const distinct = actionsByBrand.get(b.id)?.size ?? 0;
      const adoption = Math.min(100, Math.round((distinct / TOTAL_INSTRUMENTED_ACTIONS) * 100));
      return [
        b.id,
        b.domain,
        b.plan,
        b.billingCycle,
        b.organization._count.memberships,
        b.trackedSite ? eventByTrackedSite.get(b.trackedSite.id) ?? 0 : 0,
        b.trackedSite ? sessionByTrackedSite.get(b.trackedSite.id) ?? 0 : 0,
        conversionByBrand.get(b.id) ?? 0,
        audit?.crawlHealth ?? "",
        audit ? audit.createdAt.toISOString().slice(0, 10) : "",
        adoption,
        b.createdAt.toISOString().slice(0, 10),
        lastActiveByBrand.get(b.id)?.toISOString().slice(0, 10) ?? "",
      ];
    });

    const csv = toCsv(headers, rows);
    return new NextResponse(csv, {
      status: 200,
      headers: {
        "Content-Type": "text/csv",
        "Content-Disposition": `attachment; filename="brands-${new Date().toISOString().slice(0, 10)}.csv"`,
      },
    });
  });
}
