/**
 * GET /api/admin/historical/export?brandId=X&source=gsc|ga4|site_tag|all
 *
 * Exports raw archive data as CSV. The ultimate insurance — even if
 * the database goes down, the client has their data in a file.
 *
 * Superadmin-only. Streams the response to avoid OOM on large exports.
 */
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireSuperadmin } from "@/lib/admin-auth";

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

function csvRow(fields: (string | number | null | undefined)[]): string {
  return fields.map((f) => {
    if (f == null) return "";
    const s = String(f);
    return s.includes(",") || s.includes('"') || s.includes("\n")
      ? `"${s.replace(/"/g, '""')}"`
      : s;
  }).join(",") + "\n";
}

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 source = searchParams.get("source") ?? "all";
  if (!brandId) return NextResponse.json({ error: "brandId required" }, { status: 400 });

  const brand = await prisma.brand.findUnique({ where: { id: brandId }, select: { name: true, domain: true } });
  if (!brand) return NextResponse.json({ error: "Brand not found" }, { status: 404 });

  const parts: string[] = [];
  const slug = brand.domain.replace(/\./g, "_");

  if (source === "gsc" || source === "all") {
    parts.push("# GSC Pages Archive\n");
    parts.push(csvRow(["date", "pageUrl", "clicks", "impressions", "ctr", "position"]));
    const rows = await prisma.gscPage.findMany({
      where: { brandId },
      orderBy: { date: "asc" },
      select: { date: true, pageUrl: true, clicks: true, impressions: true, ctr: true, position: true },
      take: 100_000,
    }).catch(() => []);
    for (const r of rows) {
      parts.push(csvRow([r.date.toISOString().split("T")[0], r.pageUrl, r.clicks, r.impressions, r.ctr, r.position]));
    }
    parts.push("\n# GSC Queries Archive\n");
    parts.push(csvRow(["date", "query", "clicks", "impressions", "ctr", "position"]));
    const qRows = await prisma.gscQuery.findMany({
      where: { brandId },
      orderBy: { date: "asc" },
      select: { date: true, query: true, clicks: true, impressions: true, ctr: true, position: true },
      take: 100_000,
    }).catch(() => []);
    for (const r of qRows) {
      parts.push(csvRow([r.date.toISOString().split("T")[0], r.query, r.clicks, r.impressions, r.ctr, r.position]));
    }
  }

  if (source === "site_tag" || source === "all") {
    parts.push("\n# Site Tag Conversions Archive\n");
    parts.push(csvRow(["timestamp", "conversionType", "pageUrl", "sessionId", "detectionMethod", "conversionValue"]));
    // intentionally unfiltered: admin-only endpoint; needs raw or all-time counts
    const cRows = await prisma.siteConversion.findMany({
      where: { brandId },
      orderBy: { timestamp: "asc" },
      select: { timestamp: true, conversionType: true, pageUrl: true, sessionId: true, detectionMethod: true, conversionValue: true },
      take: 100_000,
    }).catch(() => []);
    for (const r of cRows) {
      parts.push(csvRow([r.timestamp.toISOString(), r.conversionType, r.pageUrl, r.sessionId, r.detectionMethod, r.conversionValue]));
    }
  }

  if (source === "ga4" || source === "all") {
    parts.push("\n# MetricSnapshot Archive (GA4 + GSC + Site Tag daily)\n");
    parts.push(csvRow(["date", "source", "sessions", "users", "conversions", "revenue", "organicClicks", "impressions", "siteTagSessions", "siteTagConversions", "siteTagEvents"]));
    const mRows = await prisma.metricSnapshot.findMany({
      where: { brandId },
      orderBy: { date: "asc" },
      select: {
        date: true, source: true, sessions: true, users: true, conversions: true, revenue: true,
        organicClicks: true, impressions: true, siteTagSessions: true, siteTagConversions: true, siteTagEvents: true,
      },
      take: 100_000,
    }).catch(() => []);
    for (const r of mRows) {
      parts.push(csvRow([
        r.date.toISOString().split("T")[0], r.source, r.sessions, r.users, r.conversions, r.revenue,
        r.organicClicks, r.impressions, r.siteTagSessions, r.siteTagConversions, r.siteTagEvents,
      ]));
    }
  }

  const filename = `${slug}_archive_${source}_${new Date().toISOString().split("T")[0]}.csv`;
  return new NextResponse(parts.join(""), {
    headers: {
      "Content-Type": "text/csv; charset=utf-8",
      "Content-Disposition": `attachment; filename="${filename}"`,
    },
  });
}
