import { NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/db";
import { requirePageRole, resolveSchoolId, ApiError } from "@/lib/auth";
import { logAudit } from "@/lib/audit";
import { handleApiError } from "@/lib/api-helpers";
import { effectiveFee, normalizeArabicName } from "@/lib/constants";
import { isValidGradeCode } from "@/lib/grade-helpers";
import { rebuildInstallmentSchedule } from "@/lib/installments";

/** تفاصيل طالب مع كل مدفوعاته (داخل مدرسته) */
export async function GET(_req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  try {
    const viewer = await requirePageRole("students", "ADMIN", "ACCOUNTANT", "STAFF");
    const viewerSchoolId = await resolveSchoolId(viewer);
    const { id } = await ctx.params;
    const student = await db.student.findUnique({
      where: { id },
      include: {
        payments: {
          orderBy: { paidAt: "desc" },
          include: { creator: { select: { fullName: true } } },
        },
      },
    });
    if (!student || student.schoolId !== viewerSchoolId) throw new ApiError("الطالب غير موجود", 404);
    const paid = student.payments.reduce((sum, p) => sum + p.amount, 0);
    const eff = effectiveFee(student.totalFee, student.discountPercent);
    return NextResponse.json({
      student: { ...student, paid, remaining: Math.max(0, eff - paid), effectiveFee: eff },
    });
  } catch (err) {
    return handleApiError(err);
  }
}

/** تعديل بيانات طالب: الاسم، ولي الأمر، الصف، الشعبة، الخصم (لإصلاح أخطاء التسجيل) */
export async function PATCH(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  try {
    const user = await requirePageRole("students", "ADMIN", "STAFF", "SUPER_ADMIN");
    const schoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const { id } = await ctx.params;
    const existing = await db.student.findUnique({ where: { id } });
    if (!existing || existing.schoolId !== schoolId) throw new ApiError("الطالب غير موجود", 404);
    const body = await req.json();
    const allowed = [
      "nameAr", "nameEn", "grade", "classroom", "guardianName",
      "guardianPhone", "guardianAddress", "notes",
    ] as const;
    const data: Record<string, string | number | Date | null> = {};
    for (const key of allowed) {
      if (body[key] !== undefined) data[key] = String(body[key]);
    }
    // الاسم الرباعي إجباري عند تعديل الاسم العربي
    if (data.nameAr !== undefined) {
      const clean = String(data.nameAr).trim().replace(/\s+/g, " ");
      const words = clean.split(" ").filter(Boolean);
      if (words.length < 4) {
        throw new ApiError("الاسم الرباعي إجباري: الاسم + الأب + الجد + اللقب", 400);
      }
      data.nameAr = clean;
      // فحص تطابق الاسم مع طالب آخر في نفس المدرسة
      const all = await db.student.findMany({
        where: { isActive: true, id: { not: id }, schoolId: existing.schoolId },
        select: { id: true, nameAr: true },
      });
      const dup = all.find((s) => normalizeArabicName(s.nameAr) === normalizeArabicName(clean));
      if (dup && body.allowDuplicate !== true) {
        throw new ApiError(`الاسم مسجل مسبقاً للطالب: ${dup.nameAr} — فعّل خيار السماح بالتكرار إذا كان طالباً مختلفاً`, 409);
      }
    }
    if (data.grade !== undefined && !(await isValidGradeCode(String(data.grade), schoolId))) {
      throw new ApiError("الصف الدراسي غير صالح", 400);
    }
    if (data.classroom !== undefined) {
      const classroomExists = await db.classroom.findFirst({ where: { name: String(data.classroom), schoolId: existing.schoolId } });
      if (!classroomExists) throw new ApiError("الشعبة غير موجودة", 400);
    }
    if (body.discountPercent !== undefined) {
      const d = Number(body.discountPercent);
      if (isNaN(d) || d < 0 || d > 100) throw new ApiError("نسبة الخصم يجب أن تكون بين 0 و 100", 400);
      data.discountPercent = Math.round(d * 100) / 100;
    }
    if (body.totalFee !== undefined) {
      const fee = Number(body.totalFee);
      if (isNaN(fee) || fee < 0) throw new ApiError("القسط الكلي غير صالح", 400);
      data.totalFee = fee;
    }
    if (body.feeDueDate !== undefined) {
      data.feeDueDate = body.feeDueDate ? new Date(String(body.feeDueDate)) : null;
    }
    // تاريخ التسجيل الفعلي — قابل للتصحيح (مثل طالب سُجّل بالخطأ بتاريخ اليوم بينما قُصد شهر آب)
    let registrationDateChanged = false;
    if (body.registeredAt !== undefined) {
      const raw = body.registeredAt;
      if (!raw || String(raw).trim() === "") throw new ApiError("تاريخ التسجيل مطلوب", 400);
      const d = new Date(String(raw));
      if (isNaN(d.getTime())) throw new ApiError("تاريخ التسجيل غير صالح", 400);
      if (d.getTime() > Date.now() + 5 * 60 * 1000) {
        throw new ApiError("لا يمكن وضع تاريخ تسجيل مستقبلي", 400);
      }
      data.registeredAt = d;
      registrationDateChanged = existing.registeredAt.toISOString().slice(0, 10) !== d.toISOString().slice(0, 10);
    }
    const student = await db.student.update({ where: { id }, data });
    // إعادة بناء جدول الأقساط عند تغيير القسط أو الخصم أو تاريخ التسجيل (v8.1 — يحفظ المسدد سابقاً)
    if (
      data.totalFee !== undefined ||
      data.discountPercent !== undefined ||
      data.registeredAt !== undefined
    ) {
      await rebuildInstallmentSchedule(id);
    }
    await logAudit(user, {
      action: "UPDATE",
      entity: "Student",
      entityId: id,
      details: `تعديل بيانات الطالب ${student.nameAr} (${student.studentCode})` +
        (registrationDateChanged ? ` - تغيير تاريخ التسجيل إلى ${student.registeredAt.toISOString().slice(0, 10)}` : ""),
    });
    return NextResponse.json({ student });
  } catch (err) {
    return handleApiError(err);
  }
}

/** حذف (تعطيل) طالب */
export async function DELETE(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  try {
    const user = await requirePageRole("students", "ADMIN", "SUPER_ADMIN");
    const schoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const { id } = await ctx.params;
    const student = await db.student.findUnique({ where: { id } });
    if (!student || student.schoolId !== schoolId) throw new ApiError("الطالب غير موجود", 404);
    await db.student.update({ where: { id }, data: { isActive: false } });
    await logAudit(user, {
      action: "DELETE",
      entity: "Student",
      entityId: id,
      details: `حذف/تعطيل الطالب ${student.nameAr} (${student.studentCode})`,
    });
    return NextResponse.json({ ok: true });
  } catch (err) {
    return handleApiError(err);
  }
}
