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";

const MONTH_RE = /^\d{4}-\d{2}$/;

/** أجور المحاضرات (v8.1) — سجل أجور شهر معين + قائمة المعلمين (نطاق المدرسة)
 *  ?month=YYYY-MM — الافتراضي الشهر الحالي */
export async function GET(req: NextRequest) {
  try {
    const user = await requirePageRole("finance", "ADMIN", "ACCOUNTANT");
    const schoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const monthParam = req.nextUrl.searchParams.get("month")?.trim() ?? "";
    const month = MONTH_RE.test(monthParam)
      ? monthParam
      : new Date().toISOString().slice(0, 7);

    const [wages, teachers] = await Promise.all([
      db.lectureWage.findMany({
        where: { schoolId, month },
        orderBy: { createdAt: "desc" },
        include: {
          employee: { select: { name: true, role: true, lecturePrice: true, employeeType: true } },
        },
      }),
      db.employee.findMany({
        where: { schoolId, deletedAt: null, employeeType: "TEACHER", isActive: true },
        orderBy: { name: "asc" },
        select: { id: true, name: true, role: true, lecturePrice: true },
      }),
    ]);

    const rows = wages.map((w) => ({
      id: w.id,
      employeeId: w.employeeId,
      employeeName: w.employee.name,
      employeeRole: w.employee.role,
      month: w.month,
      lectureCount: w.lectureCount,
      lecturePrice: w.lecturePrice,
      total: w.total,
      notes: w.notes,
      paidAt: w.paidAt,
      voucherNumber: w.voucherNumber,
      isPaid: w.paidAt != null,
      createdAt: w.createdAt,
    }));

    // كشف مستقل لكل مدرس: مجموع الأجور على مدار الأشهر (كل السجلات)
    const allWages = await db.lectureWage.findMany({
      where: { schoolId, employee: { schoolId, deletedAt: null } },
      orderBy: { month: "desc" },
      include: { employee: { select: { name: true } } },
    });
    const teacherStatements = new Map<string, { employeeId: string; employeeName: string; records: { month: string; lectureCount: number; lecturePrice: number; total: number; paidAt: string | null; voucherNumber: string | null }[] }>();
    for (const w of allWages) {
      const key = w.employeeId;
      const entry = teacherStatements.get(key) ?? {
        employeeId: key,
        employeeName: w.employee.name,
        records: [],
      };
      entry.records.push({
        month: w.month,
        lectureCount: w.lectureCount,
        lecturePrice: w.lecturePrice,
        total: w.total,
        paidAt: w.paidAt?.toISOString() ?? null,
        voucherNumber: w.voucherNumber,
      });
      teacherStatements.set(key, entry);
    }

    return NextResponse.json({
      month,
      wages: rows,
      teachers,
      summary: {
        totalWages: rows.reduce((s, w) => s + w.total, 0),
        paidWages: rows.filter((w) => w.isPaid).reduce((s, w) => s + w.total, 0),
        unpaidWages: rows.filter((w) => !w.isPaid).reduce((s, w) => s + w.total, 0),
        recordsCount: rows.length,
      },
      teacherStatements: [...teacherStatements.values()],
    });
  } 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()) as Record<string, unknown>;
    const employeeId = String(body.employeeId ?? "");
    const month = String(body.month ?? "").trim();
    const lectureCount = Number(body.lectureCount);
    const lecturePriceInput = body.lecturePrice;
    const notes = body.notes == null || String(body.notes).trim() === "" ? null : String(body.notes).trim();

    if (!employeeId) throw new ApiError("المعلم مطلوب", 400);
    const employee = await db.employee.findFirst({
      where: { id: employeeId, schoolId, deletedAt: null },
    });
    if (!employee) throw new ApiError("المعلم غير موجود", 404);
    if (!MONTH_RE.test(month)) throw new ApiError("الشهر غير صالح — الصيغة YYYY-MM", 400);
    if (!Number.isFinite(lectureCount) || lectureCount <= 0 || !Number.isInteger(lectureCount)) {
      throw new ApiError("عدد المحاضرات يجب أن يكون عدداً صحيحاً أكبر من صفر", 400);
    }
    const lecturePrice = Number.isFinite(Number(lecturePriceInput)) && Number(lecturePriceInput) > 0
      ? Number(lecturePriceInput)
      : employee.lecturePrice;
    if (!Number.isFinite(lecturePrice) || lecturePrice <= 0) {
      throw new ApiError("سعر المحاضرة غير محدد — حدد سعر المحاضرة في بيانات المعلم أو في النموذج", 400);
    }
    const total = Math.round(lectureCount * lecturePrice * 100) / 100;

    const dup = await db.lectureWage.findFirst({ where: { employeeId, month, schoolId } });
    if (dup) throw new ApiError(`يوجد سجل أجر للمعلم ${employee.name} في شهر ${month} — عدّله بدلاً من التكرار`, 409);

    const wage = await db.lectureWage.create({
      data: { employeeId, month, lectureCount, lecturePrice, total, notes, schoolId, creatorId: user.id },
      include: { employee: { select: { name: true } } },
    });

    await logAudit(user, {
      action: "CREATE",
      entity: "LectureWage",
      entityId: wage.id,
      details: `تسجيل أجر محاضرات: ${employee.name} — شهر ${month} — ${lectureCount} محاضرة × ${lecturePrice} = ${total}`,
    });
    return NextResponse.json({ wage }, { status: 201 });
  } catch (err) {
    return handleApiError(err);
  }
}

/** حذف سجل أجر غير مصروف */
export async function DELETE(req: NextRequest) {
  try {
    const user = await requirePageRole("finance", "ADMIN", "ACCOUNTANT", "SUPER_ADMIN");
    const schoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const id = req.nextUrl.searchParams.get("id") ?? "";
    const wage = await db.lectureWage.findFirst({ where: { id, schoolId } });
    if (!wage) throw new ApiError("سجل الأجر غير موجود", 404);
    if (wage.paidAt) throw new ApiError("لا يمكن حذف سجل مصروف — احذف المصروف المرتبط أولاً من صفحة المصروفات", 400);
    await db.lectureWage.delete({ where: { id } });
    await logAudit(user, {
      action: "DELETE",
      entity: "LectureWage",
      entityId: id,
      details: `حذف سجل أجر محاضرات (شهر ${wage.month}) — مبلغ: ${wage.total}`,
    });
    return NextResponse.json({ ok: true });
  } catch (err) {
    return handleApiError(err);
  }
}
