import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireRole } from "@/lib/auth";
import { HOSTEL_TYPES } from "@/lib/constants";

/** Hostel overview: stats, hostels (with capacity/residents), rooms, members. */
export async function GET() {
  const session = await requireRole("INSTITUTION_ADMIN");
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  const institutionId = session.institutionId;
  const today = new Date(new Date().toISOString().slice(0, 10));

  const [hostels, rooms, members, todayAttendance] = await Promise.all([
    prisma.hostel.findMany({
      where: { institutionId },
      orderBy: [{ isActive: "desc" }, { id: "asc" }],
      include: {
        _count: { select: { rooms: true, members: { where: { status: "ACTIVE" } } } },
      },
    }),
    prisma.hostelRoom.findMany({
      where: { institutionId },
      orderBy: [{ hostelId: "asc" }, { floor: "asc" }, { roomNo: "asc" }],
      include: { _count: { select: { allocations: { where: { status: "ACTIVE" } } } } },
    }),
    prisma.hostelMember.findMany({
      where: { institutionId },
      orderBy: [{ status: "asc" }, { id: "asc" }],
      include: {
        student: {
          select: { roll: true, name: true, gender: true, classItem: { select: { name: true } } },
        },
        hostel: { select: { name: true, type: true } },
        room: { select: { roomNo: true } },
      },
    }),
    prisma.hostelAttendance.findMany({ where: { institutionId, date: today }, select: { status: true } }),
  ]);

  const activeMembers = members.filter((m) => m.status === "ACTIVE");
  const capacity = rooms.reduce((sum, r) => sum + r.capacity, 0);

  return NextResponse.json({
    stats: {
      hostels: hostels.length,
      activeHostels: hostels.filter((h) => h.isActive).length,
      rooms: rooms.length,
      capacity,
      residents: activeMembers.length,
      vacantBeds: Math.max(0, capacity - activeMembers.filter((m) => m.roomId).length),
      monthlyExpected: activeMembers.reduce((sum, m) => sum + Number(m.monthlyFee), 0),
      todayPresent: todayAttendance.filter((a) => a.status === "PRESENT").length,
      todayAbsent: todayAttendance.filter((a) => a.status === "ABSENT").length,
      todayLeave: todayAttendance.filter((a) => a.status === "LEAVE").length,
    },
    hostels: hostels.map((h) => ({
      id: h.id,
      name: h.name,
      nameBn: h.nameBn,
      type: h.type,
      wardenName: h.wardenName,
      wardenPhone: h.wardenPhone,
      monthlyFee: Number(h.monthlyFee),
      isActive: h.isActive,
      roomCount: h._count.rooms,
      residentCount: h._count.members,
    })),
    rooms: rooms.map((r) => ({
      id: r.id,
      hostelId: r.hostelId,
      hostelName: hostels.find((h) => h.id === r.hostelId)?.name ?? null,
      roomNo: r.roomNo,
      floor: r.floor,
      capacity: r.capacity,
      roomType: r.roomType,
      monthlyFee: Number(r.monthlyFee),
      occupied: r._count.allocations,
    })),
    members: members.map((m) => ({
      id: m.id,
      studentId: m.studentId,
      roll: m.student.roll,
      studentName: m.student.name,
      className: m.student.classItem?.name ?? null,
      hostelId: m.hostelId,
      hostelName: m.hostel.name,
      roomId: m.roomId,
      roomNo: m.room?.roomNo ?? null,
      bedNo: m.bedNo,
      monthlyFee: Number(m.monthlyFee),
      joinDate: m.joinDate.toISOString(),
      status: m.status,
    })),
  });
}

/** Add a hostel. */
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 name = String(body.name ?? "").trim();
    if (!name) return NextResponse.json({ error: "Missing fields" }, { status: 400 });

    const hostel = await prisma.hostel.create({
      data: {
        institutionId: session.institutionId,
        name,
        nameBn: String(body.nameBn ?? "").trim() || null,
        type: HOSTEL_TYPES.includes(body.type as never) ? body.type : "BOYS",
        wardenName: String(body.wardenName ?? "").trim() || null,
        wardenPhone: String(body.wardenPhone ?? "").trim() || null,
        monthlyFee: Math.max(0, Number(body.monthlyFee) || 0),
        isActive: true,
      },
    });
    return NextResponse.json({ hostel });
  } catch {
    return NextResponse.json({ error: "Could not create hostel" }, { status: 500 });
  }
}
