/**
 * GET /api/cron/integration-sync
 *
 * Daily cron that syncs GA4 and GSC data for all brands with connected
 * integrations. Writes daily MetricSnapshot rows so the dashboard
 * chart shows continuous data even when nobody loads the page.
 *
 * GA4 Data API has 24-48h processing delay — the sync function
 * fetches 28 days to backfill any gaps from prior runs.
 * GSC sync mirrors the same incremental/backfill logic.
 *
 * Vercel cron schedule: "0 5 * * *" (5 AM UTC daily)
 *
 * ── Required env vars for all crons ──────────────────────────────
 *   CRON_SECRET          — shared secret for Vercel cron auth
 *   ANTHROPIC_API_KEY    — AI features (signals-site-tag-ai, signals-competitor-regional)
 *   DATAFORSEO_LOGIN     — rank-check, compute-benchmarks
 *   DATAFORSEO_PASSWORD  — rank-check, compute-benchmarks
 *   RESEND_API_KEY       — email-reports
 *
 * ── Cron status ──────────────────────────────────────────────────
 *   All routes in vercel.json are fully functional.
 *   apiCallAuthed handles GA4/GSC token refresh with 401 retry.
 *   refresh-tokens cron proactively refreshes tokens every 45min.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { googleAnalytics } from "@/lib/integrations/google-analytics";
import { googleSearchConsole } from "@/lib/integrations/google-search-console";
import { getCredentials } from "@/lib/services/integration-credentials";
import { runAiReferralBackfill } from "@/lib/services/ai-referral-backfill";
import { logCron } from "@/lib/services/cron-logger";

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

export async function GET(req: Request) {
  const cronSecret = process.env.CRON_SECRET;
  if (!cronSecret) {
    return NextResponse.json({ error: "Server misconfigured: CRON_SECRET unset" }, { status: 500 });
  }
  const authHeader = req.headers.get("authorization");
  const querySecret = new URL(req.url).searchParams.get("secret");
  if (authHeader !== `Bearer ${cronSecret}` && querySecret !== cronSecret) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  return logCron("/api/cron/integration-sync", async () => {
  // ── GA4 sync ────────────────────────────────────────────────────
  const ga4Integrations = await prisma.brandIntegration.findMany({
    where: { integrationId: "ga4", connected: true },
    select: { brandId: true, brand: { select: { name: true } } },
  });

  console.info(`[integration-sync] Starting GA4 sync for ${ga4Integrations.length} brands`);

  const results: Record<string, { ga4?: { success: boolean; message: string }; gsc?: { success: boolean; message: string } }> = {};

  for (const integ of ga4Integrations) {
    try {
      const creds = await getCredentials(integ.brandId, "ga4");
      if (!creds?.propertyId) {
        results[integ.brandId] = { ga4: { success: false, message: "No propertyId" } };
        continue;
      }
      const result = await googleAnalytics.sync(integ.brandId, creds);
      results[integ.brandId] = { ga4: { success: result.success, message: result.message } };
      console.info(`[integration-sync] GA4 ${integ.brand.name}: ${result.message}`);
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      results[integ.brandId] = { ga4: { success: false, message: msg } };
      console.error(`[integration-sync] GA4 ${integ.brand.name} failed:`, msg);
    }
  }

  // ── GSC sync ────────────────────────────────────────────────────
  const gscIntegrations = await prisma.brandIntegration.findMany({
    where: { integrationId: "gsc", connected: true },
    select: { brandId: true, brand: { select: { name: true } } },
  });

  console.info(`[integration-sync] Starting GSC sync for ${gscIntegrations.length} brands`);

  for (const integ of gscIntegrations) {
    try {
      const creds = await getCredentials(integ.brandId, "gsc");
      if (!creds?.accessToken || (!creds?.siteUrl && !creds?.accountId)) {
        results[integ.brandId] = { ...results[integ.brandId], gsc: { success: false, message: "No siteUrl/accountId" } };
        continue;
      }
      const result = await googleSearchConsole.sync(integ.brandId, creds);
      results[integ.brandId] = { ...results[integ.brandId], gsc: { success: result.success, message: result.message } };
      console.info(`[integration-sync] GSC ${integ.brand.name}: ${result.message}`);
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      results[integ.brandId] = { ...results[integ.brandId], gsc: { success: false, message: msg } };
      console.error(`[integration-sync] GSC ${integ.brand.name} failed:`, msg);
    }
  }

  // AI referral backfill — catches AI referrals from sessions where
  // t.js hadn't been updated with AI detection yet. Idempotent; skips
  // sessions that already have AiAttribution records.
  let aiBackfill: { found: number; created: number } = { found: 0, created: 0 };
  try {
    const bf = await runAiReferralBackfill();
    aiBackfill = { found: bf.aiReferralsFound, created: bf.attributionsCreated };
  } catch (err) {
    console.error("[integration-sync] AI backfill failed:", err instanceof Error ? err.message : String(err));
  }

  const totalBrands = new Set([...ga4Integrations.map(i => i.brandId), ...gscIntegrations.map(i => i.brandId)]).size;
  const payload = { ga4Brands: ga4Integrations.length, gscBrands: gscIntegrations.length, totalBrands, results, aiBackfill, timestamp: new Date().toISOString() };
  return NextResponse.json(payload);
  });
}
