import { NextRequest, NextResponse } from "next/server";
import { db } from "@/lib/db";
import { requirePageRole, resolveSchoolId, hashPassword, ApiError } from "@/lib/auth";
import { logAudit } from "@/lib/audit";
import { handleApiError } from "@/lib/api-helpers";
import { randomBytes } from "node:crypto";
import { PAGE_KEYS } from "@/lib/constants";

/** إدارة المستخدمين - مدير المدرسة يرى حسابات مدرسته، ومدير النظام العام يرى الكل */
export async function GET(req: NextRequest) {
  try {
    const user = await requirePageRole("users", "ADMIN");
    const scopeSchoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const isSuper = user.role === "SUPER_ADMIN";
    const users = await db.user.findMany({
      where: { deletedAt: null, ...(isSuper ? {} : { schoolId: scopeSchoolId }) },
      orderBy: { createdAt: "asc" },
      select: { id: true, username: true, fullName: true, phone: true, role: true, isActive: true, allowedViews: true, schoolId: true, createdAt: true },
    });
    // الحسابات المحذوفة (حذف منطقي) — لعرضها في قسم منفصل مع إمكانية الاستعادة
    const deleted = await db.user.findMany({
      where: { deletedAt: { not: null }, ...(isSuper ? {} : { schoolId: scopeSchoolId }) },
      orderBy: { deletedAt: "desc" },
      select: { id: true, username: true, fullName: true, role: true, schoolId: true, deletedAt: true },
    });
    // أسماء المدارس لعرضها بجانب الحسابات (للمدير العام)
    const schools = isSuper ? await db.school.findMany({ select: { id: true, name: true } }) : [];
    const schoolMap = new Map(schools.map((s) => [s.id, s.name]));
    // تحويل allowedViews من نص JSON إلى مصفوفة
    const parsed = users.map((u) => {
      let views: string[] | null = null;
      if (u.allowedViews) {
        try { const p = JSON.parse(u.allowedViews); if (Array.isArray(p)) views = p; } catch { views = null; }
      }
      return { ...u, allowedViews: views, schoolName: u.schoolId ? schoolMap.get(u.schoolId) ?? null : null };
    });
    return NextResponse.json({
      users: parsed,
      deleted: deleted.map((u) => ({
        ...u,
        // عرض اسم المستخدم الأصلي (بعد إزالة لاحقة الحذف .delXXXX)
        username: u.username.replace(/\.del\d+$/, ""),
        schoolName: u.schoolId ? schoolMap.get(u.schoolId) ?? null : null,
      })),
    });
  } catch (err) {
    return handleApiError(err);
  }
}

/** إنشاء حساب جديد — مدير المدرسة يحسابه في مدرسته، ومدير النظام العام يحدد المدرسة */
export async function POST(req: NextRequest) {
  try {
    const user = await requirePageRole("users", "ADMIN");
    const body = await req.json();
    const { username, password, fullName, role, schoolId, phone, allowedViews } = body as Record<string, unknown>;
    if (typeof username !== "string" || !/^[a-zA-Z0-9_.]{3,30}$/.test(username)) {
      throw new ApiError("اسم المستخدم مطلوب (حروف إنجليزية وأرقام، 3-30 خانة)", 400);
    }
    if (typeof password !== "string" || password.length < 8 || Buffer.byteLength(password, "utf8") > 72) {
      throw new ApiError("كلمة المرور مطلوبة (8 خانات على الأقل)", 400);
    }
    if (!fullName || String(fullName).trim().length < 3) {
      throw new ApiError("الاسم الكامل مطلوب", 400);
    }
    if (typeof role !== "string" || !["ADMIN", "ACCOUNTANT", "STAFF"].includes(role)) {
      throw new ApiError("الدور الوظيفي غير صالح", 400);
    }
    const cleanPhone = typeof phone === "string" ? phone.replace(/[\s()-]/g, "") : "";
    if (!/^\+?[0-9]{7,15}$/.test(cleanPhone)) throw new ApiError("رقم هاتف صحيح مطلوب للاسترداد", 400);
    const phoneOwner = await db.user.findFirst({ where: { phone: cleanPhone, isActive: true, deletedAt: null }, select: { id: true } });
    if (phoneOwner) throw new ApiError("رقم الهاتف مرتبط بحساب نشط آخر", 409);
    if (allowedViews !== undefined && (!Array.isArray(allowedViews) || allowedViews.length === 0 || allowedViews.some((key) => typeof key !== "string" || !(PAGE_KEYS as readonly string[]).includes(key)))) {
      throw new ApiError("اختر صفحة واحدة على الأقل بصلاحيات صحيحة", 400);
    }
    // تحديد مدرسة الحساب: مدير النظام العام يختار، ومدير المدرسة حسابه لمدرسته دائماً (v8.0.1)
    let targetSchoolId: string;
    if (user.role === "SUPER_ADMIN") {
      const requested = String(schoolId ?? "").trim();
      if (requested) {
        const school = await db.school.findUnique({ where: { id: requested } });
        if (!school) throw new ApiError("المدرسة المحددة غير موجودة", 400);
        targetSchoolId = school.id;
      } else {
        targetSchoolId = await resolveSchoolId(user, null);
      }
    } else {
      targetSchoolId = await resolveSchoolId(user, null);
    }
    const exists = await db.user.findUnique({ where: { username } });
    if (exists) throw new ApiError("اسم المستخدم محجوز مسبقاً", 409);
    const passwordHash = await hashPassword(password);
    const recoveryCode = randomBytes(16).toString("hex").toUpperCase();
    const recoveryCodeHash = await hashPassword(recoveryCode);
    const safeViews = Array.isArray(allowedViews) ? [...new Set(allowedViews as string[])] : role === "ADMIN" ? [...PAGE_KEYS] : undefined;
    const created = await db.user.create({
      data: {
        username: String(username).trim(), passwordHash, recoveryCodeHash,
        fullName: String(fullName).trim(), phone: cleanPhone, role, schoolId: targetSchoolId,
        ...(safeViews ? { allowedViews: JSON.stringify(safeViews) } : {}),
      },
      select: { id: true, username: true, fullName: true, role: true, isActive: true, schoolId: true, createdAt: true },
    });
    const school = await db.school.findUnique({ where: { id: targetSchoolId }, select: { name: true } });
    await logAudit(user, {
      action: "CREATE",
      entity: "User",
      entityId: created.id,
      details: `إنشاء حساب جديد: ${created.fullName} (${created.username}) - الدور: ${created.role} - المدرسة: ${school?.name ?? "-"}`,
    });
    return NextResponse.json({ user: { ...created, schoolName: school?.name ?? null }, recoveryCode }, { status: 201 });
  } catch (err) {
    return handleApiError(err);
  }
}
