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 { nextExpenseVoucherNumber } from "@/lib/voucher";

/** سجل دفعات الرواتب التفصيلية (v8.1) — المبلغ الاسمي، الخصومات، المكافآت، رقم وصل الصرف (نطاق المدرسة)
 *  ?month=YYYY-MM — تصفية بشهر الصرف */
export async function GET(req: NextRequest) {
  try {
    const viewer = await requirePageRole("finance", "ADMIN", "ACCOUNTANT");
    const schoolId = await resolveSchoolId(viewer, req.nextUrl.searchParams.get("schoolId"));
    const monthParam = req.nextUrl.searchParams.get("month")?.trim() ?? "";

    const payments = await db.employeePayment.findMany({
      orderBy: { paidAt: "desc" },
      take: 500,
      where: {
        employee: { schoolId },
        ...(monthParam && /^\d{4}-\d{2}$/.test(monthParam)
          ? {
              paidAt: {
                gte: new Date(`${monthParam}-01T00:00:00.000Z`),
                lt: new Date(
                  new Date(`${monthParam}-01T00:00:00.000Z`).getFullYear(),
                  new Date(`${monthParam}-01T00:00:00.000Z`).getMonth() + 1,
                  1
                ),
              },
            }
          : {}),
      },
      include: {
        employee: { select: { name: true, role: true, employeeType: true, monthlySalary: true } },
        creator: { select: { fullName: true } },
      },
    });

    return NextResponse.json({
      payments,
      summary: {
        count: payments.length,
        totalNet: payments.reduce((s, p) => s + p.amount, 0),
        totalBase: payments.reduce((s, p) => s + (p.baseAmount || 0), 0),
        totalDeductions: payments.reduce((s, p) => s + (p.deductions || 0), 0),
        totalBonuses: payments.reduce((s, p) => s + (p.bonuses || 0), 0),
      },
    });
  } catch (err) {
    return handleApiError(err);
  }
}

/** تسجيل دفعة راتب تفصيلية — تُنشئ مصروفاً تلقائياً (رواتب الموظفين) مع رقم وصل صرف
 *  المبلغ الصافي = المبلغ الاسمي + المكافآت - الخصومات (إذا غاب المبلغ الصافي يُحسب تلقائياً) */
export async function POST(req: NextRequest) {
  try {
    const user = await requirePageRole("finance", "ADMIN", "ACCOUNTANT", "SUPER_ADMIN");
    const schoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const body = await req.json();
    const { employeeId, amount, baseAmount, deductions, bonuses, voucherNumber, paidAt, notes } =
      body as Record<string, string | number | undefined>;

    if (employeeId === undefined || employeeId === null || String(employeeId).trim() === "") throw new ApiError("الموظف مطلوب", 400);
    const cleanEmployeeId = String(employeeId);
    const employee = await db.employee.findFirst({ where: { id: cleanEmployeeId, deletedAt: null, schoolId } });
    if (!employee) throw new ApiError("الموظف غير موجود", 404);

    const base = Number(baseAmount ?? 0) || 0;
    const ded = Math.abs(Number(deductions ?? 0) || 0);
    const bon = Math.abs(Number(bonuses ?? 0) || 0);
    // الصافي: إن مرّر المستخدم مبلغاً صريحاً يستخدمه، وإلا يُحسب = الاسمي + المكافآت - الخصومات
    const amt = amount !== undefined && amount !== null && String(amount).trim() !== ""
      ? Number(amount)
      : base > 0
        ? base + bon - ded
        : NaN;
    if (isNaN(amt) || amt <= 0) throw new ApiError("مبلغ الدفعة غير صالح — تأكد من المبلغ الاسمي والخصومات والمكافآت", 400);
    const date = paidAt ? new Date(String(paidAt)) : new Date();
    if (isNaN(date.getTime())) throw new ApiError("تاريخ الدفع غير صالح", 400);

    const voucher = voucherNumber && String(voucherNumber).trim() ? String(voucherNumber).trim() : await nextExpenseVoucherNumber(schoolId, date);

    const payment = await db.$transaction(async (tx) => {
      const expense = await tx.expense.create({
        data: {
          category: "رواتب الموظفين",
          kind: "SALARY",
          description: `دفعة راتب: ${employee.name}`,
          amount: amt,
          spentAt: date,
          voucherNumber: voucher,
          createdById: user.id,
          schoolId,
        },
      });
      return tx.employeePayment.create({
        data: {
          employeeId: cleanEmployeeId,
          amount: amt,
          baseAmount: base > 0 ? base : amt,
          deductions: ded,
          bonuses: bon,
          voucherNumber: voucher,
          paidAt: date,
          notes: notes && String(notes).trim() ? String(notes).trim() : null,
          expenseId: expense.id,
          creatorId: user.id,
        },
        include: { employee: { select: { name: true } } },
      });
    });

    await logAudit(user, {
      action: "CREATE",
      entity: "EmployeePayment",
      entityId: payment.id,
      details:
        `دفعة راتب للموظف ${employee.name} — الصافي: ${amt}` +
        (base > 0 ? ` (الاسمي: ${base}${ded > 0 ? ` - خصومات: ${ded}` : ""}${bon > 0 ? ` + مكافآت: ${bon}` : ""})` : "") +
        ` — وصل صرف: ${voucher}`,
    });

    return NextResponse.json({ payment }, { status: 201 });
  } catch (err) {
    return handleApiError(err);
  }
}
