export const dynamic = "force-dynamic";
import { NextResponse } from "next/server";
import prisma from "@/lib/prisma";

function toYmdUTC(d: Date): string {
  const yy = d.getUTCFullYear();
  const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
  const dd = String(d.getUTCDate()).padStart(2, "0");
  return `${yy}-${mm}-${dd}`;
}

export async function GET(req: Request) {
  const url = new URL(req.url);
  const only = url.searchParams.get("only");

  // 최대 연속 출석 상위 (Top 20, 전체 이력 기준)
  async function computeStreakTop() {
    // 전체 이력 기준으로 사용자별 최대 연속 출석을 계산
    const rows = await prisma.attendance.findMany({
      select: { userId: true, date: true },
      orderBy: [{ userId: "asc" }, { date: "asc" }],
    });
    const maxByUser = new Map<string, number>();
    let currentUserId: string | null = null;
    let lastDayMs: number | null = null;
    let current = 0;
    let maxStreak = 0;
    const commit = () => {
      if (currentUserId) {
        maxByUser.set(currentUserId, Math.max(maxByUser.get(currentUserId) ?? 0, maxStreak));
      }
    };
    for (const r of rows) {
      if (r.userId !== currentUserId) {
        // flush previous
        if (currentUserId !== null) commit();
        // reset for new user
        currentUserId = r.userId;
        lastDayMs = null;
        current = 0;
        maxStreak = 0;
      }
      // UTC 일 단위로 비교
      const ymd = toYmdUTC(new Date(r.date));
      const ms = Date.parse(`${ymd}T00:00:00.000Z`);
      if (lastDayMs === null) {
        current = 1;
      } else {
        const diffDays = Math.round((ms - lastDayMs) / (24 * 60 * 60 * 1000));
        if (diffDays === 1) {
          current += 1;
        } else if (diffDays > 0) {
          current = 1;
        } else {
          // 동일/역순은 이례적이지만 안전하게 스킵
          current = Math.max(current, 1);
        }
      }
      if (current > maxStreak) maxStreak = current;
      lastDayMs = ms;
    }
    // flush last
    if (currentUserId !== null) commit();

    const topStreak = Array.from(maxByUser.entries())
      .map(([userId, streak]) => ({ userId, streak }))
      .sort((a, b) => b.streak - a.streak)
      .slice(0, 20);
    const streakUserIds = topStreak.map((s) => s.userId);
    const streakUsers = await prisma.user.findMany({
      where: { userId: { in: streakUserIds } },
      select: { userId: true, nickname: true, profileImage: true, grade: true },
    });
    const streakMeta = new Map(streakUsers.map((u) => [u.userId, u]));
    const streak = topStreak.map((s) => ({
      userId: s.userId,
      nickname: streakMeta.get(s.userId)?.nickname ?? "회원",
      streak: s.streak,
      profileImage: streakMeta.get(s.userId)?.profileImage ?? null,
      grade: streakMeta.get(s.userId)?.grade ?? 0,
    }));
    return streak;
  }

  if (only === "streak") {
    const streak = await computeStreakTop();
    return NextResponse.json({ streak });
  }

  // 전체 출석 누적 상위 (Top 10)
  const overallGroups = await prisma.attendance.groupBy({
    by: ["userId"],
    _count: { date: true },
    orderBy: { _count: { date: "desc" } },
    take: 20,
  });
  const overallUserIds = overallGroups.map((g) => g.userId);
  const overallUsers = await prisma.user.findMany({
    where: { userId: { in: overallUserIds } },
    select: { userId: true, nickname: true, profileImage: true, grade: true },
  });
  const userMeta = new Map(overallUsers.map((u) => [u.userId, u]));
  const overall = overallGroups.map((g) => ({
    userId: g.userId,
    nickname: userMeta.get(g.userId)?.nickname ?? "회원",
    count: g._count.date ?? 0,
    profileImage: userMeta.get(g.userId)?.profileImage ?? null,
    grade: userMeta.get(g.userId)?.grade ?? 0,
  }));

  const streak = await computeStreakTop();

  return NextResponse.json({ overall, streak });
}


