/**
 * GET /api/admin/ai-monitor — feed of AiInteraction records for the
 * admin AI monitor dashboard.
 *
 * Query params:
 *   severity  — none | warning | critical (default: all)
 *   feature   — specific feature key to filter by
 *   brandId   — "all" or specific brand cuid (default: all). Filters
 *               BOTH the rows feed AND the 24h/7d/30d stat windows so
 *               the headline numbers reflect the chosen scope.
 *   q         — substring match in userPrompt / aiResponse
 *   page      — 1-indexed, default 1
 *   limit     — default 50, max 200
 *
 * Returns rolled-up stats (24h / 7d / 30d), a per-feature breakdown,
 * a per-brand cost table for the last 30 days (always returned
 * unfiltered so the dashboard can show "who is driving spend?" while
 * the user has a single brand selected), and the brand list for the
 * dropdown.
 *
 * Superadmin-only.
 */

import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireSuperadmin, withAdminTiming } from "@/lib/admin-auth";
import type { Prisma } from "@prisma/client";

export const dynamic = "force-dynamic";

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

  const { searchParams } = new URL(req.url);
  const severity = searchParams.get("severity") ?? "";
  const feature = searchParams.get("feature") ?? "";
  const brandIdRaw = searchParams.get("brandId") ?? "";
  // Treat empty / "all" identically — the UI sends "all" explicitly,
  // but legacy callers omit the param; both mean "no brand filter".
  const brandId = brandIdRaw && brandIdRaw !== "all" ? brandIdRaw : "";
  const q = (searchParams.get("q") ?? "").trim();
  const page = Math.max(1, Number(searchParams.get("page") ?? 1));
  const limit = Math.max(1, Math.min(200, Number(searchParams.get("limit") ?? 50)));
  const skip = (page - 1) * limit;

  return NextResponse.json(await withAdminTiming("ai-monitor.feed", async () => {
    const where: Prisma.AiInteractionWhereInput = {};
    if (severity) where.flagSeverity = severity;
    if (feature) where.feature = feature;
    if (brandId) where.brandId = brandId;
    if (q) {
      where.OR = [
        { userPrompt: { contains: q, mode: "insensitive" } },
        { aiResponse: { contains: q, mode: "insensitive" } },
      ];
    }

    const now = Date.now();
    const d1 = new Date(now - 86_400_000);
    const d7 = new Date(now - 7 * 86_400_000);
    const d30 = new Date(now - 30 * 86_400_000);

    const [rows, total, stats24, stats7, stats30, topFeatures, costByBrandRaw, selectedBrand] = await Promise.all([
      prisma.aiInteraction.findMany({
        where,
        orderBy: { timestamp: "desc" },
        skip,
        take: limit,
      }),
      prisma.aiInteraction.count({ where }),
      // Stat windows respect the brand filter so 24h / 7d / 30d match
      // whatever scope the user selected.
      aggregateStats(d1, brandId),
      aggregateStats(d7, brandId),
      aggregateStats(d30, brandId),
      // Per-feature breakdown — also brand-scoped so the feature
      // dropdown shows what THIS brand is using.
      prisma.aiInteraction.groupBy({
        by: ["feature"],
        where: { timestamp: { gte: d7 }, ...(brandId ? { brandId } : {}) },
        _count: true,
        _sum: { costEstimate: true, tokensUsed: true },
        orderBy: { _count: { feature: "desc" } },
        take: 10,
      }),
      // Per-brand cost breakdown for the last 30d. Deliberately NOT
      // brand-filtered — this table answers "which brands are driving
      // platform AI spend" and is most useful precisely when the user
      // is investigating a single brand.
      prisma.aiInteraction.groupBy({
        by: ["brandId"],
        where: { timestamp: { gte: d30 }, brandId: { not: null } },
        _count: true,
        _sum: { costEstimate: true, tokensUsed: true },
        orderBy: { _sum: { costEstimate: "desc" } },
        take: 25,
      }),
      // Resolve the currently-selected brand's name so the stat-card
      // labels ("LAST 24H — Modern Heart and Vascular") render without
      // a second client-side lookup.
      brandId
        ? prisma.brand.findUnique({ where: { id: brandId }, select: { id: true, name: true } })
        : Promise.resolve(null),
    ]);

    // Hydrate brand names for the cost-by-brand table.
    const brandIds = costByBrandRaw.map((r) => r.brandId).filter((id): id is string => Boolean(id));
    const brandNames = brandIds.length
      ? await prisma.brand.findMany({ where: { id: { in: brandIds } }, select: { id: true, name: true } })
      : [];
    const nameById = new Map(brandNames.map((b) => [b.id, b.name]));

    const costByBrand = costByBrandRaw.map((r) => {
      const calls = r._count;
      const totalCost = r._sum.costEstimate ?? 0;
      const totalTokens = r._sum.tokensUsed ?? 0;
      return {
        brandId: r.brandId!,
        brandName: nameById.get(r.brandId!) ?? "(unknown)",
        calls,
        totalCost,
        totalTokens,
        avgCostPerCall: calls > 0 ? totalCost / calls : 0,
      };
    });

    return {
      rows: rows.map((r) => ({
        ...r,
        userPrompt: r.userPrompt.slice(0, 500),
        aiResponse: r.aiResponse.slice(0, 1000),
        systemPrompt: null,
        timestamp: r.timestamp.toISOString(),
      })),
      total,
      page,
      limit,
      hasMore: skip + rows.length < total,
      stats: { d1: stats24, d7: stats7, d30: stats30 },
      topFeatures: topFeatures.map((f) => ({
        feature: f.feature,
        count: f._count,
        totalCost: f._sum.costEstimate ?? 0,
        totalTokens: f._sum.tokensUsed ?? 0,
      })),
      costByBrand,
      // Echo the resolved scope so the client can render labels +
      // verify it asked for what it got.
      scope: {
        brandId: brandId || "all",
        brandName: selectedBrand?.name ?? null,
      },
    };
  }));
}

async function aggregateStats(since: Date, brandId: string) {
  const baseWhere: Prisma.AiInteractionWhereInput = { timestamp: { gte: since } };
  if (brandId) baseWhere.brandId = brandId;

  const [total, warning, critical, totals] = await Promise.all([
    prisma.aiInteraction.count({ where: baseWhere }),
    prisma.aiInteraction.count({ where: { ...baseWhere, flagSeverity: "warning" } }),
    prisma.aiInteraction.count({ where: { ...baseWhere, flagSeverity: { in: ["critical", "blocked"] } } }),
    prisma.aiInteraction.aggregate({
      where: baseWhere,
      _sum: { costEstimate: true, tokensUsed: true },
    }),
  ]);
  return {
    total,
    warning,
    critical,
    flagRate: total > 0 ? Math.round(((warning + critical) / total) * 1000) / 10 : 0,
    totalCost: totals._sum.costEstimate ?? 0,
    totalTokens: totals._sum.tokensUsed ?? 0,
  };
}
