import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { requireCampusInstitution } from "@/lib/auth";

/** Campus students — filters: ?q= (id/name/roll), ?programId=, ?sessionYear=, ?status=. */
export async function GET(req: Request) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const sp = new URL(req.url).searchParams;
  const q = (sp.get("q") ?? "").trim();
  const programId = Number(sp.get("programId"));
  const sessionYear = (sp.get("sessionYear") ?? "").trim();
  const status = (sp.get("status") ?? "").trim();

  const students = await prisma.cuStudent.findMany({
    where: {
      institutionId: session.institutionId,
      ...(q ? { OR: [{ name: { contains: q } }, { nameBn: { contains: q } }, { studentIdNo: { contains: q } }, { registrationNo: { contains: q } }, { boardRollNo: { contains: q } }] } : {}),
      ...(Number.isFinite(programId) && programId > 0 ? { programId } : {}),
      ...(sessionYear ? { sessionYear } : {}),
      ...(status ? { status } : {}),
    },
    orderBy: [{ studentIdNo: "asc" }],
    include: {
      program: { select: { id: true, name: true, nameBn: true, gradeScale: true } },
      currentTerm: { select: { id: true, name: true, nameBn: true } },
      _count: { select: { enrollments: true } },
    },
  });
  return NextResponse.json({ students });
}

/** Create a student: { studentIdNo, name, nameBn?, gender?, dob?, guardianName?,
    guardianPhone?, phone?, email?, address?, programId, sessionYear, currentTermId?,
    boardRollNo?, registrationNo?, admissionDate?, status?, note? }. */
export async function POST(req: Request) {
  const session = await requireCampusInstitution();
  if (!session || !session.institutionId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    const body = await req.json();
    const studentIdNo = String(body.studentIdNo ?? "").trim();
    const name = String(body.name ?? "").trim();
    const programId = Number(body.programId);
    const sessionYear = String(body.sessionYear ?? "").trim();
    if (!studentIdNo || !name || !Number.isFinite(programId) || programId <= 0 || !sessionYear) {
      return NextResponse.json({ error: "Missing fields" }, { status: 400 });
    }
    const program = await prisma.cuProgram.findFirst({
      where: { id: programId, institutionId: session.institutionId },
      select: { id: true },
    });
    if (!program) return NextResponse.json({ error: "Invalid program" }, { status: 400 });

    const dup = await prisma.cuStudent.findFirst({
      where: { institutionId: session.institutionId, studentIdNo },
      select: { id: true },
    });
    if (dup) return NextResponse.json({ error: "ID_EXISTS" }, { status: 409 });

    const currentTermId = Number(body.currentTermId);
    let termId: number | null = null;
    if (Number.isFinite(currentTermId) && currentTermId > 0) {
      const term = await prisma.cuTerm.findFirst({
        where: { id: currentTermId, programId },
        select: { id: true },
      });
      if (!term) return NextResponse.json({ error: "Invalid term" }, { status: 400 });
      termId = term.id;
    }

    const date = (v: unknown) => {
      const s = String(v ?? "").slice(0, 10);
      return /^\d{4}-\d{2}-\d{2}$/.test(s) ? new Date(`${s}T00:00:00Z`) : null;
    };

    const student = await prisma.cuStudent.create({
      data: {
        institutionId: session.institutionId,
        studentIdNo,
        name,
        nameBn: String(body.nameBn ?? "").trim() || null,
        gender: body.gender === "FEMALE" ? "FEMALE" : "MALE",
        dob: date(body.dob),
        guardianName: String(body.guardianName ?? "").trim() || null,
        guardianPhone: String(body.guardianPhone ?? "").trim() || null,
        phone: String(body.phone ?? "").trim() || null,
        email: String(body.email ?? "").trim() || null,
        address: String(body.address ?? "").trim() || null,
        programId,
        sessionYear,
        currentTermId: termId,
        boardRollNo: String(body.boardRollNo ?? "").trim() || null,
        registrationNo: String(body.registrationNo ?? "").trim() || null,
        admissionDate: date(body.admissionDate),
        status: String(body.status ?? "ACTIVE"),
        note: String(body.note ?? "").trim() || null,
      },
      include: {
        program: { select: { id: true, name: true, nameBn: true, gradeScale: true } },
        currentTerm: { select: { id: true, name: true, nameBn: true } },
      },
    });
    return NextResponse.json({ student });
  } catch {
    return NextResponse.json({ error: "Could not create student" }, { status: 500 });
  }
}
