/**
 * GET /api/admin/activity — paginated PlatformEvent feed.
 *
 * Query params:
 *   page, limit (default 50, max 200)
 *   brandId, userId — scope filters
 *   category       — navigation | search | audit | report | integration |
 *                    content | ai | export | settings | auth | admin
 *   action         — substring action key match
 *   from, to       — ISO timestamps for date range
 *
 * Always sorted newest-first. Returns hydrated brand + user names so
 * the feed renders without N+1 lookups.
 *
 * Also returns "rightNow" rollup: usersOnline (distinct userId in
 * last 5 min), activeBrands (distinct brandId in last 5 min), and
 * eventsPerMinute (count over the last 60s) so the page header can
 * render a live pulse without a second request.
 *
 * 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 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;
  const brandId = searchParams.get("brandId") ?? "";
  const userId = searchParams.get("userId") ?? "";
  const category = searchParams.get("category") ?? "";
  const action = (searchParams.get("action") ?? "").trim();
  const fromISO = searchParams.get("from");
  const toISO = searchParams.get("to");

  return NextResponse.json(await withAdminTiming("activity.feed", async () => {
    const where: Prisma.PlatformEventWhereInput = {};
    if (brandId) where.brandId = brandId;
    if (userId) where.userId = userId;
    if (category) where.category = category;
    if (action) where.action = { contains: action, mode: "insensitive" };
    if (fromISO || toISO) {
      where.timestamp = {};
      if (fromISO) where.timestamp.gte = new Date(fromISO);
      if (toISO) where.timestamp.lte = new Date(toISO);
    }

    const fiveMinAgo = new Date(Date.now() - 5 * 60_000);
    const oneMinAgo = new Date(Date.now() - 60_000);

    const [rows, total, usersOnline, activeBrands, eventsLastMinute] = await Promise.all([
      prisma.platformEvent.findMany({
        where,
        orderBy: { timestamp: "desc" },
        skip,
        take: limit,
      }),
      prisma.platformEvent.count({ where }),
      // Distinct online users in the last 5 minutes — across the
      // whole platform, not the filtered set, so the "Right now"
      // numbers reflect global activity.
      prisma.platformEvent.findMany({
        where: { timestamp: { gte: fiveMinAgo }, userId: { not: null } },
        distinct: ["userId"],
        select: { userId: true },
      }),
      prisma.platformEvent.findMany({
        where: { timestamp: { gte: fiveMinAgo }, brandId: { not: null } },
        distinct: ["brandId"],
        select: { brandId: true },
      }),
      prisma.platformEvent.count({ where: { timestamp: { gte: oneMinAgo } } }),
    ]);

    // Hydrate user + brand names for the rendered page only — keeps
    // the round-trips proportional to the rendered list.
    const userIds = Array.from(new Set(rows.map((r) => r.userId).filter(Boolean) as string[]));
    const brandIds = Array.from(new Set(rows.map((r) => r.brandId).filter(Boolean) as string[]));
    const [users, brands] = await Promise.all([
      userIds.length > 0
        ? prisma.user.findMany({
            where: { id: { in: userIds } },
            select: { id: true, name: true, email: true, image: true },
          })
        : Promise.resolve([]),
      brandIds.length > 0
        ? prisma.brand.findMany({
            where: { id: { in: brandIds } },
            select: { id: true, name: true, domain: true },
          })
        : Promise.resolve([]),
    ]);
    const userMap = new Map(users.map((u) => [u.id, u]));
    const brandMap = new Map(brands.map((b) => [b.id, b]));

    return {
      rows: rows.map((r) => ({
        id: r.id,
        action: r.action,
        category: r.category,
        metadata: r.metadata,
        timestamp: r.timestamp.toISOString(),
        user: r.userId ? userMap.get(r.userId) ?? { id: r.userId, name: null, email: null, image: null } : null,
        brand: r.brandId ? brandMap.get(r.brandId) ?? { id: r.brandId, name: null, domain: null } : null,
      })),
      total,
      page,
      limit,
      hasMore: skip + rows.length < total,
      rightNow: {
        usersOnline: usersOnline.length,
        activeBrands: activeBrands.length,
        eventsPerMinute: eventsLastMinute,
      },
    };
  }));
}
