import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import { PATTERN_BY_ID, PRICING_CATEGORY_BY_CODE, patternsForInstitution, pricingCategoriesForInstitution } from "@/lib/pricing";

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

  const requests = await prisma.packageRequest.findMany({
    where: { institutionId: session.institutionId },
    orderBy: { createdAt: "desc" },
    include: {
      packagePlan: { select: { name: true, nameBn: true, price: true } },
      pricingTier: true,
    },
  });

  return NextResponse.json({ requests });
}

/** Create a package purchase request — either pattern/plan-based or
    slab-based (a landing-pricing student range). */
export async function POST(req: Request) {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const packagePlanId = body.packagePlanId ? Number(body.packagePlanId) : null;
    const pricingTierId = body.pricingTierId ? Number(body.pricingTierId) : null;
    const note = String(body.note ?? "").trim() || null;
    const billingCycle = body.billingCycle === "YEARLY" ? "YEARLY" : "MONTHLY";
    if (!packagePlanId && !pricingTierId) {
      return NextResponse.json({ error: "Plan not available" }, { status: 400 });
    }

    const institution = await prisma.institution.findUnique({
      where: { id: session.institutionId },
      select: { status: true, type: true, isGovernment: true },
    });
    if (!institution) return NextResponse.json({ error: "Institution not found" }, { status: 404 });
    if (institution.status !== "ACTIVE") {
      return NextResponse.json({ error: "INSTITUTION_NOT_ACTIVE" }, { status: 403 });
    }

    let studentCount: number | null = null;

    if (pricingTierId) {
      // slab request: the chosen student range must be eligible for this
      // institution and must cover its current active student count
      const tier = await prisma.pricingTier.findUnique({ where: { id: pricingTierId } });
      if (!tier || !tier.active) {
        return NextResponse.json({ error: "Plan not available" }, { status: 400 });
      }
      const category = PRICING_CATEGORY_BY_CODE[tier.category];
      if (
        !category ||
        !pricingCategoriesForInstitution(institution.type, institution.isGovernment).some(
          (c) => c.code === category.code
        )
      ) {
        return NextResponse.json({ error: "Plan not available" }, { status: 400 });
      }
      studentCount = await prisma.student.count({
        where: { institutionId: session.institutionId, status: "ACTIVE" },
      });
      if (tier.maxStudents !== null && studentCount > tier.maxStudents) {
        return NextResponse.json({ error: "RANGE_MISMATCH" }, { status: 400 });
      }
      const duplicate = await prisma.packageRequest.findFirst({
        where: { institutionId: session.institutionId, pricingTierId, status: "PENDING" },
      });
      if (duplicate) {
        return NextResponse.json({ error: "ALREADY_REQUESTED" }, { status: 409 });
      }
      const request = await prisma.packageRequest.create({
        data: {
          institutionId: session.institutionId,
          pricingTierId,
          note,
          billingCycle,
          studentCount,
        },
      });
      return NextResponse.json({ request });
    }

    const packagePlanIdNum = packagePlanId as number;
    const plan = await prisma.packagePlan.findUnique({ where: { id: packagePlanIdNum } });
    if (!plan || !plan.isActive) {
      return NextResponse.json({ error: "Plan not available" }, { status: 400 });
    }

    // education-pattern plans: eligibility by pattern + allowed billing cycle
    const pattern = plan.educationPattern ? PATTERN_BY_ID[plan.educationPattern] : null;
    if (pattern) {
      const eligible = patternsForInstitution(institution.type, institution.isGovernment);
      if (!eligible.some((p) => p.id === pattern.id)) {
        return NextResponse.json({ error: "Plan not available" }, { status: 400 });
      }
      if (!pattern.cycles.includes(billingCycle)) {
        return NextResponse.json({ error: "Invalid billing cycle" }, { status: 400 });
      }
      studentCount = await prisma.student.count({
        where: { institutionId: session.institutionId, status: "ACTIVE" },
      });
    } else if (plan.institutionType !== institution.type) {
      // legacy per-type plan
      return NextResponse.json({ error: "Plan not available" }, { status: 400 });
    }

    const duplicate = await prisma.packageRequest.findFirst({
      where: { institutionId: session.institutionId, packagePlanId: packagePlanIdNum, status: "PENDING" },
    });
    if (duplicate) {
      return NextResponse.json({ error: "ALREADY_REQUESTED" }, { status: 409 });
    }

    const request = await prisma.packageRequest.create({
      data: {
        institutionId: session.institutionId,
        packagePlanId: packagePlanIdNum,
        note,
        billingCycle: pattern ? billingCycle : null,
        studentCount,
      },
      include: { packagePlan: { select: { name: true, nameBn: true, price: true } } },
    });

    return NextResponse.json({ request });
  } catch {
    return NextResponse.json({ error: "Could not create request" }, { status: 500 });
  }
}
