/**
 * GET /api/admin/debug/install-date?brandId=<id>
 *
 * Diagnostic endpoint for Bug 1 — "Site Tag capturing data since Apr 16"
 * banner shows an incorrect date.
 *
 * Queries production directly to surface:
 *   - TrackedSite row: id, createdAt, firstEventAt, lastEventAt
 *   - Actual earliest TrackedEvent (MIN timestamp via findFirst asc)
 *   - Actual earliest SiteEvent (MIN timestamp via findFirst asc)
 *   - Total TrackedEvent count for the site
 *   - TrackedEvent count by day for the past 60 days (to see where events land)
 *   - Brand.createdAt for reference
 *
 * Superadmin-only.
 */

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

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

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

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

  const site = await prisma.trackedSite.findUnique({
    where: { brandId },
    select: {
      id: true,
      siteId: true,
      status: true,
      createdAt: true,
      firstEventAt: true,
      lastEventAt: true,
    },
  });
  if (!site) {
    return NextResponse.json({
      brand: { id: brand.id, name: brand.name, createdAt: brand.createdAt.toISOString() },
      trackedSite: null,
      diagnosis: "No TrackedSite row — Site Tag not installed for this brand",
    });
  }

  // Actual minimum timestamp in TrackedEvent (the ground truth)
  const [actualFirstTrackedEvent, actualLastTrackedEvent, totalEventCount] = await Promise.all([
    prisma.trackedEvent.findFirst({
      where: { trackedSiteId: site.id },
      orderBy: { timestamp: "asc" },
      select: { id: true, timestamp: true, eventType: true, pageUrl: true },
    }),
    prisma.trackedEvent.findFirst({
      where: { trackedSiteId: site.id },
      orderBy: { timestamp: "desc" },
      select: { id: true, timestamp: true, eventType: true },
    }),
    prisma.trackedEvent.count({ where: { trackedSiteId: site.id } }),
  ]);

  // Actual minimum timestamp in SiteEvent
  const actualFirstSiteEvent = await prisma.siteEvent.findFirst({
    where: { brandId },
    orderBy: { timestamp: "asc" },
    select: { id: true, timestamp: true, eventType: true },
  }).catch(() => null);

  // Per-day event counts for the past 60 days to see where events actually land
  const since60d = new Date(Date.now() - 60 * 86_400_000);
  const recentEvents = await prisma.trackedEvent.findMany({
    where: { trackedSiteId: site.id, timestamp: { gte: since60d } },
    select: { timestamp: true },
    orderBy: { timestamp: "asc" },
  });

  // Bucket by day
  const byDay: Record<string, number> = {};
  for (const e of recentEvents) {
    const day = e.timestamp.toISOString().slice(0, 10);
    byDay[day] = (byDay[day] ?? 0) + 1;
  }

  // Also look for events between TrackedSite.createdAt and 3 days before it
  // (to see if the firstEventAt was written incorrectly at schema migration time)
  const firstEventAtForQuery = site.firstEventAt;
  let eventsOnFirstEventAtDay: number | null = null;
  if (firstEventAtForQuery) {
    const dayStart = new Date(firstEventAtForQuery);
    dayStart.setUTCHours(0, 0, 0, 0);
    const dayEnd = new Date(dayStart);
    dayEnd.setUTCDate(dayEnd.getUTCDate() + 1);
    eventsOnFirstEventAtDay = await prisma.trackedEvent.count({
      where: {
        trackedSiteId: site.id,
        timestamp: { gte: dayStart, lt: dayEnd },
      },
    });
  }

  // Assess the discrepancy
  const cachedDate = site.firstEventAt;
  const actualDate = actualFirstTrackedEvent?.timestamp ?? null;
  let discrepancyMs: number | null = null;
  let discrepancyDays: number | null = null;
  if (cachedDate && actualDate) {
    discrepancyMs = actualDate.getTime() - cachedDate.getTime();
    discrepancyDays = Math.round(discrepancyMs / 86_400_000);
  }

  const diagnosis = (() => {
    if (!actualFirstTrackedEvent) {
      if (cachedDate) return "BUG: firstEventAt is set but NO TrackedEvent rows exist. firstEventAt is stale — was written by old recordEvent() code when column was first added. The verify step in getSiteTagInstalledAt() doesn't catch this because it only looks for events BEFORE firstEventAt (finds none = incorrectly returns firstEventAt as valid).";
      return "No events exist and firstEventAt is null — correct state for a newly-installed tag.";
    }
    if (!cachedDate) return "firstEventAt is null but events exist — getSiteTagInstalledAt() will compute it correctly on next read.";
    if (discrepancyDays === 0) return "firstEventAt matches actual first TrackedEvent — correct.";
    if (discrepancyDays !== null && discrepancyDays < 0) return `BUG: firstEventAt (${cachedDate.toISOString()}) is ${Math.abs(discrepancyDays)} days BEFORE actual first TrackedEvent (${actualDate!.toISOString()}). Stale cache — getSiteTagInstalledAt() should have corrected this via its verify step, but hasn't. Investigate why.`;
    if (discrepancyDays !== null && discrepancyDays > 0) return `BUG: firstEventAt (${cachedDate.toISOString()}) is ${discrepancyDays} days BEFORE actual first TrackedEvent (${actualDate!.toISOString()}). The verify step only looks for events BEFORE firstEventAt — finds none — returns firstEventAt as "correct" even though no events exist at that date. This is the root bug.`;
    return "Unknown state.";
  })();

  return NextResponse.json({
    brand: {
      id: brand.id,
      name: brand.name,
      createdAt: brand.createdAt.toISOString(),
    },
    trackedSite: {
      id: site.id,
      siteId: site.siteId,
      status: site.status,
      createdAt: site.createdAt.toISOString(),
      firstEventAt: site.firstEventAt?.toISOString() ?? null,
      lastEventAt: site.lastEventAt?.toISOString() ?? null,
    },
    groundTruth: {
      actualFirstTrackedEvent: actualFirstTrackedEvent
        ? { id: actualFirstTrackedEvent.id, timestamp: actualFirstTrackedEvent.timestamp.toISOString(), eventType: actualFirstTrackedEvent.eventType, pageUrl: actualFirstTrackedEvent.pageUrl }
        : null,
      actualLastTrackedEvent: actualLastTrackedEvent
        ? { id: actualLastTrackedEvent.id, timestamp: actualLastTrackedEvent.timestamp.toISOString(), eventType: actualLastTrackedEvent.eventType }
        : null,
      actualFirstSiteEvent: actualFirstSiteEvent
        ? { id: actualFirstSiteEvent.id, timestamp: actualFirstSiteEvent.timestamp.toISOString(), eventType: actualFirstSiteEvent.eventType }
        : null,
      totalTrackedEventCount: totalEventCount,
    },
    discrepancy: {
      cachedFirstEventAt: cachedDate?.toISOString() ?? null,
      actualFirstEventAt: actualDate?.toISOString() ?? null,
      differenceMs: discrepancyMs,
      differenceDays: discrepancyDays,
      eventsOnCachedDate: eventsOnFirstEventAtDay,
    },
    recentEventsByDay: Object.entries(byDay).sort(([a], [b]) => a.localeCompare(b)).map(([date, count]) => ({ date, count })),
    diagnosis,
  });
}
