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

function currentMonth(): string {
  return new Date().toISOString().slice(0, 7);
}

/** Transport overview: stats, vehicles, routes (with stops), 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 month = currentMonth();

  const [vehicles, routes, members, monthPayments] = await Promise.all([
    prisma.transportVehicle.findMany({
      where: { institutionId },
      orderBy: [{ status: "asc" }, { id: "asc" }],
      include: { _count: { select: { routes: true } } },
    }),
    prisma.transportRoute.findMany({
      where: { institutionId },
      orderBy: { id: "asc" },
      include: {
        vehicle: { select: { name: true } },
        stops: { orderBy: { sortOrder: "asc" } },
        _count: { select: { members: { where: { status: "ACTIVE" } } } },
      },
    }),
    prisma.transportMember.findMany({
      where: { institutionId },
      orderBy: [{ status: "asc" }, { id: "asc" }],
      include: {
        student: {
          select: { roll: true, name: true, classItem: { select: { name: true } } },
        },
        route: { select: { name: true } },
        stop: { select: { name: true } },
      },
    }),
    prisma.transportPayment.aggregate({
      where: { institutionId, month },
      _sum: { amount: true },
    }),
  ]);

  const activeMembers = members.filter((m) => m.status === "ACTIVE");
  const monthlyExpected = activeMembers.reduce(
    (sum, m) => sum + Number(m.monthlyFare),
    0
  );
  const monthCollected = Number(monthPayments._sum.amount ?? 0);

  return NextResponse.json({
    stats: {
      vehicles: vehicles.length,
      activeVehicles: vehicles.filter((v) => v.status === "ACTIVE").length,
      routes: routes.filter((r) => r.isActive).length,
      members: activeMembers.length,
      monthlyExpected,
      monthCollected,
      monthDue: Math.max(0, monthlyExpected - monthCollected),
      month,
    },
    vehicles: vehicles.map((v) => ({
      id: v.id,
      name: v.name,
      registrationNo: v.registrationNo,
      type: v.type,
      capacity: v.capacity,
      driverName: v.driverName,
      driverPhone: v.driverPhone,
      status: v.status,
      routeCount: v._count.routes,
    })),
    routes: routes.map((r) => ({
      id: r.id,
      name: r.name,
      nameBn: r.nameBn,
      baseFare: Number(r.baseFare),
      isActive: r.isActive,
      vehicleName: r.vehicle?.name ?? null,
      memberCount: r._count.members,
      stops: r.stops.map((s) => ({
        id: s.id,
        name: s.name,
        nameBn: s.nameBn,
        extraFare: Number(s.extraFare),
        sortOrder: s.sortOrder,
      })),
    })),
    members: members.map((m) => ({
      id: m.id,
      studentId: m.studentId,
      roll: m.student.roll,
      studentName: m.student.name,
      className: m.student.classItem?.name ?? null,
      routeId: m.routeId,
      routeName: m.route.name,
      stopName: m.stop?.name ?? null,
      monthlyFare: Number(m.monthlyFare),
      status: m.status,
    })),
  });
}

/** Add a vehicle. */
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 vehicle = await prisma.transportVehicle.create({
      data: {
        institutionId: session.institutionId,
        name,
        registrationNo: String(body.registrationNo ?? "").trim() || null,
        type: VEHICLE_TYPES.includes(body.type as never) ? body.type : "BUS",
        capacity: Math.max(0, Number(body.capacity) || 0),
        driverName: String(body.driverName ?? "").trim() || null,
        driverPhone: String(body.driverPhone ?? "").trim() || null,
        status: "ACTIVE",
      },
    });
    return NextResponse.json({ vehicle });
  } catch {
    return NextResponse.json({ error: "Could not create vehicle" }, { status: 500 });
  }
}
