/**
 * POST /api/admin/debug/backfill-ga4-history[?brandId=xxx&months=36]
 *
 * Fetches historical GA4 data going back up to 36 months and stores
 * daily rows in MetricSnapshot (source="ga4"). Uses apiCallAuthed
 * for auth — same path the dashboard + confidence routes use.
 *
 * Fetches one month at a time to stay within GA4 API limits.
 * Upserts so it's safe to run repeatedly (fills gaps + updates
 * existing rows with fresh data).
 *
 * Superadmin-only. maxDuration=300.
 */
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireSuperadmin } from "@/lib/admin-auth";
import { getCredentials } from "@/lib/services/integration-credentials";
import { apiCallAuthed } from "@/lib/integrations/types";

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

const GA4_API = "https://analyticsdata.googleapis.com/v1beta";

function monthRanges(monthsBack: number): Array<{ start: string; end: string }> {
  const ranges: Array<{ start: string; end: string }> = [];
  const now = new Date();
  for (let m = 0; m < monthsBack; m++) {
    const s = new Date(now.getFullYear(), now.getMonth() - m, 1);
    const e = new Date(now.getFullYear(), now.getMonth() - m + 1, 0);
    if (e > now) e.setTime(now.getTime() - 86_400_000); // don't request future
    ranges.push({
      start: s.toISOString().split("T")[0],
      end: e.toISOString().split("T")[0],
    });
  }
  return ranges.reverse();
}

interface GA4Row {
  dimensionValues?: Array<{ value: string }>;
  metricValues?: Array<{ value: string }>;
}

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

  const { searchParams } = new URL(req.url);
  const targetBrandId = searchParams.get("brandId");
  const months = Math.min(parseInt(searchParams.get("months") ?? "36") || 36, 48);

  const integrations = await prisma.brandIntegration.findMany({
    where: {
      integrationId: "ga4",
      connected: true,
      ...(targetBrandId ? { brandId: targetBrandId } : {}),
    },
    select: { brandId: true, brand: { select: { name: true } } },
  });

  const ranges = monthRanges(months);
  const results: Record<string, { months: number; days: number; errors: number; error?: string }> = {};

  for (const integ of integrations) {
    const { brandId } = integ;
    const name = integ.brand.name;
    const row = { months: 0, days: 0, errors: 0 };
    results[name] = row;

    try {
      const creds = await getCredentials(brandId, "ga4");
      const propertyId = (typeof creds?.propertyId === "string" ? creds.propertyId : null);
      if (!propertyId) {
        results[name].error = "No GA4 propertyId in credentials";
        continue;
      }

      console.info(`[ga4-history] ${name}: property=${propertyId}, ${months} months, ${ranges.length} chunks`);

      for (const range of ranges) {
        try {
          const res = await apiCallAuthed(
            `${GA4_API}/properties/${propertyId}:runReport`,
            {
              method: "POST",
              body: {
                dateRanges: [{ startDate: range.start, endDate: range.end }],
                dimensions: [{ name: "date" }],
                metrics: [
                  { name: "sessions" },
                  { name: "totalUsers" },
                  { name: "newUsers" },
                  { name: "screenPageViews" },
                  { name: "conversions" },
                  { name: "eventCount" },
                ],
              },
            },
            { brandId, integrationId: "ga4" },
          );

          if (!res.ok) {
            console.warn(`[ga4-history] ${name}: ${range.start}→${range.end} failed: ${res.status}`, res.error);
            row.errors++;
            continue;
          }

          const data = res.data as { rows?: GA4Row[] };
          const rows = data.rows ?? [];
          row.months++;

          for (const r of rows) {
            const dateStr = r.dimensionValues?.[0]?.value;
            if (!dateStr) continue;
            const date = new Date(`${dateStr.slice(0, 4)}-${dateStr.slice(4, 6)}-${dateStr.slice(6, 8)}`);
            const vals = (r.metricValues ?? []).map((v) => parseInt(v.value ?? "0", 10));

            try {
              await prisma.metricSnapshot.upsert({
                where: { brandId_date_source: { brandId, date, source: "ga4" } },
                create: {
                  brandId, date, source: "ga4",
                  sessions: vals[0] ?? 0,
                  users: vals[1] ?? 0,
                  pageviews: vals[3] ?? 0,
                  conversions: vals[4] ?? 0,
                },
                update: {
                  sessions: vals[0] ?? 0,
                  users: vals[1] ?? 0,
                  pageviews: vals[3] ?? 0,
                  conversions: vals[4] ?? 0,
                },
              });
              row.days++;
            } catch { row.errors++; }
          }

          console.info(`[ga4-history] ${name}: ${range.start}→${range.end}: ${rows.length} days`);
        } catch (err) {
          console.warn(`[ga4-history] ${name}: month chunk failed`, err instanceof Error ? err.message : String(err));
          row.errors++;
        }
      }
    } catch (err) {
      results[name].error = err instanceof Error ? err.message : String(err);
    }
  }

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