import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import { PATTERN_BY_ID, estimateCost, tierRangeLabel, yearlyEffectiveMonthly } from "@/lib/pricing";

export async function GET() {
  const session = await requireRole("SUPER_ADMIN");
  if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const requests = await prisma.packageRequest.findMany({
    orderBy: { createdAt: "desc" },
    include: {
      institution: { select: { id: true, name: true, type: true, status: true, isGovernment: true } },
      packagePlan: {
        select: {
          id: true,
          name: true,
          nameBn: true,
          price: true,
          durationMonths: true,
          institutionType: true,
          educationPattern: true,
          billingBasis: true,
          ratePerStudent: true,
          yearlyDiscountPct: true,
        },
      },
      pricingTier: true,
    },
  });

  // estimated subscription total per pattern request (rate × students × cycle,
  // with the one-time setup fee when the institution has no subscription yet)
  const ids = [...new Set(requests.map((r) => r.institutionId))];
  const [studentCounts, subCounts] = await Promise.all([
    prisma.student.groupBy({
      by: ["institutionId"],
      where: { institutionId: { in: ids }, status: "ACTIVE" },
      _count: { _all: true },
    }),
    prisma.subscription.groupBy({
      by: ["institutionId"],
      where: { institutionId: { in: ids } },
      _count: { _all: true },
    }),
  ]);
  const studentsBy = new Map(studentCounts.map((s) => [s.institutionId, s._count._all]));
  const subsBy = new Map(subCounts.map((s) => [s.institutionId, s._count._all]));

  return NextResponse.json({
    requests: requests.map((r) => {
      const pattern = r.packagePlan?.educationPattern
        ? PATTERN_BY_ID[r.packagePlan.educationPattern]
        : null;
      const students = r.studentCount ?? studentsBy.get(r.institutionId) ?? 0;

      // slab request: flat tier price (+ one-time setup fee on the first subscription)
      let slab: {
        rangeLabel: string;
        category: string;
        cycle: string;
        total: number;
        setupFee: number;
      } | null = null;
      const tier = r.pricingTier;
      if (tier) {
        const cycle = r.billingCycle === "YEARLY" ? "YEARLY" : "MONTHLY";
        const isFirst = (subsBy.get(r.institutionId) ?? 0) === 0;
        const setupFee = r.status === "PENDING" && isFirst ? 5000 : 0;
        const monthly = Number(tier.monthlyPrice);
        const total =
          (cycle === "YEARLY"
            ? yearlyEffectiveMonthly(monthly, Number(tier.yearlyDiscount)) * 12
            : monthly) + setupFee;
        slab = {
          rangeLabel: tierRangeLabel(tier.minStudents, tier.maxStudents),
          category: tier.category,
          cycle,
          total: Math.round(total * 100) / 100,
          setupFee,
        };
      }
      const estimate =
        pattern && r.status === "PENDING"
          ? estimateCost({
              pattern: {
                ...pattern,
                rate:
                  r.packagePlan?.ratePerStudent !== null && r.packagePlan?.ratePerStudent !== undefined
                    ? Number(r.packagePlan.ratePerStudent)
                    : pattern.rate,
              },
              students,
              cycle: r.billingCycle === "YEARLY" ? "YEARLY" : "MONTHLY",
              withSetup: (subsBy.get(r.institutionId) ?? 0) === 0,
            })
          : null;
      return { ...r, students, estimate, slab };
    }),
  });
}
