import { NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/db";
import { requirePageRole, resolveSchoolId, isAdminLike } from "@/lib/auth";
import { handleApiError } from "@/lib/api-helpers";
import { effectiveFee } from "@/lib/constants";

/** بيانات لوحة المعلومات: إحصائيات، أقساط متأخرة، آخر العمليات، تنبيهات الإدارة (نطاق المدرسة) */
export async function GET(req: NextRequest) {
  try {
    const viewer = await requirePageRole("dashboard", "ADMIN", "ACCOUNTANT", "STAFF");
    const schoolId = await resolveSchoolId(viewer, req.nextUrl.searchParams.get("schoolId"));
    const now = new Date();
    const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
    const yearStart = new Date(now.getFullYear(), 0, 1);

    const [studentsCount, allPayments, allExpenses, allOtherIncomes, monthPayments, monthExpenses, monthOtherIncomes, todayPayments, todayOtherIncomes, announcements, activeStudents] =
      await Promise.all([
        db.student.count({ where: { isActive: true, schoolId } }),
        db.payment.findMany({ where: { schoolId }, select: { amount: true, paidAt: true } }),
        db.expense.aggregate({ where: { schoolId }, _sum: { amount: true } }),
        db.otherIncome.findMany({ where: { schoolId }, select: { amount: true, receivedAt: true } }),
        db.payment.aggregate({ where: { paidAt: { gte: startOfMonth }, schoolId }, _sum: { amount: true } }),
        db.expense.aggregate({ where: { spentAt: { gte: startOfMonth }, schoolId }, _sum: { amount: true } }),
        db.otherIncome.aggregate({ where: { receivedAt: { gte: startOfMonth }, schoolId }, _sum: { amount: true } }),
        db.payment.aggregate({ where: { paidAt: { gte: startOfToday }, schoolId }, _sum: { amount: true } }),
        db.otherIncome.aggregate({ where: { receivedAt: { gte: startOfToday }, schoolId }, _sum: { amount: true } }),
        db.announcement.findMany({
          where: { isActive: true, schoolId },
          orderBy: { createdAt: "desc" },
          take: 5,
          include: { creator: { select: { fullName: true } } },
        }),
        db.student.findMany({
          where: { isActive: true, schoolId },
          select: { id: true, nameAr: true, studentCode: true, grade: true, totalFee: true, discountPercent: true, feeDueDate: true, createdAt: true },
        }),
      ]);

    // الإيرادات: أقساط الطلبة + الإيرادات الأخرى (v8: الإيرادات الأخرى تدخل كل الحسابات)
    const installmentIncome = allPayments.reduce((s, p) => s + p.amount, 0);
    const otherIncomeTotal = allOtherIncomes.reduce((s, o) => s + o.amount, 0);
    const totalIncome = installmentIncome + otherIncomeTotal;
    const totalExpenses = allExpenses._sum.amount ?? 0;
    // القسط الصافي بعد الخصم لكل طالب
    const totalFeeSum = activeStudents.reduce((s, st) => s + effectiveFee(st.totalFee, st.discountPercent), 0);

    // الأقساط المتأخرة: طلاب تجاوزوا تاريخ الاستحقاق ولا يزال لديهم مبلغ متبقٍ
    const paidByStudent = new Map<string, number>();
    const paymentRows = await db.payment.findMany({ where: { schoolId }, select: { studentId: true, amount: true } });
    paymentRows.forEach((p) => {
      paidByStudent.set(p.studentId, (paidByStudent.get(p.studentId) ?? 0) + p.amount);
    });
    const lateStudents = activeStudents
      .filter((st) => {
        const paid = paidByStudent.get(st.id) ?? 0;
        const remaining = effectiveFee(st.totalFee, st.discountPercent) - paid;
        if (remaining <= 0) return false;
        if (st.feeDueDate) return new Date(st.feeDueDate) < now;
        // بدون تاريخ استحقاق: يعتبر متأخراً إذا مضى 60 يوماً على التسجيل دون سداد كامل
        return (now.getTime() - new Date(st.createdAt).getTime()) > 60 * 24 * 60 * 60 * 1000;
      })
      .map((st) => ({
        id: st.id,
        nameAr: st.nameAr,
        studentCode: st.studentCode,
        grade: st.grade,
        remaining: effectiveFee(st.totalFee, st.discountPercent) - (paidByStudent.get(st.id) ?? 0),
        feeDueDate: st.feeDueDate,
      }))
      .sort((a, b) => b.remaining - a.remaining)
      .slice(0, 10);

    const recentPayments = await db.payment.findMany({
      where: { schoolId },
      orderBy: { paidAt: "desc" },
      take: 6,
      include: {
        student: { select: { nameAr: true, studentCode: true } },
        creator: { select: { fullName: true } },
      },
    });
    const recentExpenses = await db.expense.findMany({
      where: { schoolId },
      orderBy: { spentAt: "desc" },
      take: 5,
      include: { creator: { select: { fullName: true } } },
    });

    // رسم بياني شهري: إيرادات ومصروفات آخر أشهر السنة (أقساط + إيرادات أخرى)
    const yearOtherIncomes = allOtherIncomes.filter((o) => new Date(o.receivedAt) >= yearStart);
    const yearExpenses = await db.expense.findMany({
      where: { spentAt: { gte: yearStart }, schoolId },
      select: { amount: true, spentAt: true },
    });
    const monthNames = ["كانون2", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "تشرين1", "تشرين2", "كانون1"];
    const monthlyChart: { month: string; income: number; expenses: number }[] = [];
    for (let m = 0; m <= now.getMonth(); m++) {
      const income =
        allPayments.filter((p) => new Date(p.paidAt) >= yearStart && new Date(p.paidAt).getMonth() === m).reduce((s, p) => s + p.amount, 0) +
        yearOtherIncomes.filter((o) => new Date(o.receivedAt).getMonth() === m).reduce((s, o) => s + o.amount, 0);
      const expenses = yearExpenses
        .filter((e) => new Date(e.spentAt).getMonth() === m)
        .reduce((s, e) => s + e.amount, 0);
      monthlyChart.push({ month: monthNames[m], income, expenses });
    }

    // المستحق على الطلبة (المتبقي من الأقساط) لا يتأثر بالإيرادات الأخرى
    const outstanding = Math.max(0, totalFeeSum - installmentIncome);

    // مدير النظام العام + مدير المدرسة + المحاسب يرون الأرقام المالية
    const isFinanceViewer = isAdminLike(viewer.role) || viewer.role === "ACCOUNTANT";
    return NextResponse.json({
      stats: {
        studentsCount,
        totalIncome: isFinanceViewer ? totalIncome : 0,
        totalExpenses: isFinanceViewer ? totalExpenses : 0,
        netBalance: isFinanceViewer ? totalIncome - totalExpenses : 0,
        monthIncome: isFinanceViewer ? (monthPayments._sum.amount ?? 0) + (monthOtherIncomes._sum.amount ?? 0) : 0,
        monthExpenses: isFinanceViewer ? (monthExpenses._sum.amount ?? 0) : 0,
        todayIncome: isFinanceViewer ? (todayPayments._sum.amount ?? 0) + (todayOtherIncomes._sum.amount ?? 0) : 0,
        outstanding: isFinanceViewer ? outstanding : 0,
      },
      lateStudents: lateStudents,
      recentPayments: isFinanceViewer ? recentPayments : [],
      recentExpenses: isFinanceViewer ? recentExpenses : [],
      announcements,
      monthlyChart: isFinanceViewer ? monthlyChart : [],
    });
  } catch (err) {
    return handleApiError(err);
  }
}
