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 { PAGE_KEYS } from "@/lib/constants";
import { randomBytes } from "node:crypto";

/** تعديل مستخدم: الاسم، الدور، التفعيل/التعطيل، كلمة المرور، الصفحات المسموحة — مع دعم استعادة الحساب المحذوف */
export async function PATCH(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  try {
    const user = await requirePageRole("users", "ADMIN");
    const scopeSchoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const isSuper = user.role === "SUPER_ADMIN";
    const { id } = await ctx.params;
    const target = await db.user.findUnique({ where: { id } });
    if (!target) throw new ApiError("المستخدم غير موجود", 404);
    if (!isSuper && target.schoolId !== scopeSchoolId) throw new ApiError("المستخدم غير موجود", 404);
    if (target.role === "SUPER_ADMIN" && !isSuper) throw new ApiError("لا يمكنك تعديل حساب مدير النظام", 403);
    const body = await req.json();
    const { fullName, role, isActive, password, allowedViews, restore, phone } = body as Record<string, unknown>;

    // استعادة حساب محذوف: إزالة علامة الحذف + التفعيل + إرجاع اسم المستخدم الأصلي
    if (restore === true) {
      if (!target.deletedAt) throw new ApiError("هذا الحساب غير محذوف", 400);
      const restoredUsername = target.username.replace(/\.del\d+$/, "");
      const taken = await db.user.findFirst({
        where: { username: restoredUsername, id: { not: id } },
        select: { id: true },
      });
      const finalUsername = taken ? target.username : restoredUsername;
      const restored = await db.user.update({
        where: { id },
        data: { deletedAt: null, isActive: true, username: finalUsername },
        select: { id: true, username: true, fullName: true, role: true, isActive: true, deletedAt: true, createdAt: true },
      });
      await logAudit(user, {
        action: "UPDATE",
        entity: "User",
        entityId: id,
        details: `استعادة حساب محذوف: ${restored.fullName} (${restored.username})`,
      });
      return NextResponse.json({ user: restored });
    }

    if (target.deletedAt) throw new ApiError("هذا الحساب محذوف — استعده أولاً قبل تعديله", 400);

    const data: Record<string, string | boolean | null | Date> = {};
    let recoveryCode: string | undefined;
    if (fullName !== undefined) {
      if (String(fullName).trim().length < 3) throw new ApiError("الاسم الكامل قصير جداً", 400);
      data.fullName = String(fullName).trim();
    }
    if (role !== undefined) {
      if (!["ADMIN", "ACCOUNTANT", "STAFF"].includes(String(role))) throw new ApiError("الدور غير صالح", 400);
      if (target.id === user.id && role !== "ADMIN" && !isSuper) {
        throw new ApiError("لا يمكنك تغيير دور حسابك الحالي", 400);
      }
      data.role = String(role);
    }
    if (isActive !== undefined) {
      if (typeof isActive !== "boolean") throw new ApiError("حالة الحساب غير صالحة", 400);
      if (target.id === user.id && isActive === false) {
        throw new ApiError("لا يمكنك تعطيل حسابك الحالي", 400);
      }
      data.isActive = isActive;
    }
    if (password !== undefined && password !== "") {
      if (String(password).length < 8 || Buffer.byteLength(String(password), "utf8") > 72) throw new ApiError("كلمة المرور يجب أن تكون 8 خانات على الأقل", 400);
      data.passwordHash = await hashPassword(String(password));
      data.passwordChangedAt = new Date();
    }
    if (phone !== undefined) {
      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, id: { not: id } }, select: { id: true } });
      if (phoneOwner) throw new ApiError("رقم الهاتف مرتبط بحساب نشط آخر", 409);
      data.phone = cleanPhone;
    }
    if (phone !== undefined || password !== undefined && password !== "") {
      recoveryCode = randomBytes(16).toString("hex").toUpperCase();
      data.recoveryCodeHash = await hashPassword(recoveryCode);
    }
    // الصفحات المسموحة: null = الافتراضي حسب الدور، مصفوفة = تقييد داخل صفحات الدور
    if (allowedViews !== undefined) {
      if (target.id === user.id) throw new ApiError("لا يمكنك تغيير صلاحيات حسابك الحالي", 400);
      if (allowedViews === null) {
        data.allowedViews = null;
      } else if (Array.isArray(allowedViews)) {
        const valid = allowedViews.filter((k): k is string =>
          typeof k === "string" && (PAGE_KEYS as readonly string[]).includes(k)
        );
        if (valid.length === 0 || valid.length !== allowedViews.length) throw new ApiError("اختر صفحة واحدة على الأقل بصلاحيات صحيحة", 400);
        data.allowedViews = JSON.stringify(valid);
      } else {
        throw new ApiError("قائمة الصفحات المسموحة غير صالحة", 400);
      }
    } else if (role === "ADMIN") {
      data.allowedViews = JSON.stringify([...PAGE_KEYS]);
    }
    const updated = await db.user.update({
      where: { id },
      data,
      select: { id: true, username: true, fullName: true, phone: true, role: true, isActive: true, allowedViews: true, createdAt: true },
    });
    await logAudit(user, {
      action: "UPDATE",
      entity: "User",
      entityId: id,
      details: `تعديل حساب المستخدم ${updated.fullName} (${updated.username})` +
        (password ? " - تغيير كلمة المرور" : "") +
        (isActive !== undefined ? ` - الحالة: ${updated.isActive ? "نشط" : "معطل"}` : "") +
        (allowedViews !== undefined ? " - تحديث الصفحات المسموحة" : ""),
    });
    let parsedViews: string[] | null = null;
    if (updated.allowedViews) {
      try { const p = JSON.parse(updated.allowedViews); if (Array.isArray(p)) parsedViews = p; } catch { parsedViews = null; }
    }
    return NextResponse.json({ user: { ...updated, allowedViews: parsedViews }, ...(recoveryCode ? { recoveryCode } : {}) });
  } catch (err) {
    return handleApiError(err);
  }
}

/**
 * حذف حساب مستخدم (مدير فقط) — حذف منطقي آمن:
 * - لا يُحذف السجل من قاعدة البيانات حفاظاً على سجل الحركات والمدفوعات والمصروفات المسجلة باسمه
 * - يصبح لا يستطيع الدخول فوراً ويختفي من قائمة المستخدمين النشطين
 * - يظهر في قسم "الحسابات المحذوفة" ويمكن استعادته لاحقاً
 * - يُحرَّر اسم المستخدم (بإضافة لاحقة .delXXXX) ليسمح بإنشاء حساب جديد بنفس الاسم
 */
export async function DELETE(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  try {
    const user = await requirePageRole("users", "ADMIN");
    const scopeSchoolId = await resolveSchoolId(user, req.nextUrl.searchParams.get("schoolId"));
    const isSuper = user.role === "SUPER_ADMIN";
    const { id } = await ctx.params;
    const target = await db.user.findUnique({ where: { id } });
    if (!target) throw new ApiError("المستخدم غير موجود", 404);
    if (!isSuper && target.schoolId !== scopeSchoolId) throw new ApiError("المستخدم غير موجود", 404);
    if (target.role === "SUPER_ADMIN" && !isSuper) throw new ApiError("لا يمكنك حذف حساب مدير النظام", 403);
    if (target.deletedAt) throw new ApiError("هذا الحساب محذوف مسبقاً", 400);
    if (target.id === user.id) throw new ApiError("لا يمكنك حذف حسابك الحالي", 400);
    if (target.role === "ADMIN") {
      const activeAdmins = await db.user.count({
        where: { role: "ADMIN", isActive: true, deletedAt: null, id: { not: id }, schoolId: target.schoolId },
      });
      if (activeAdmins === 0) {
        throw new ApiError("لا يمكن حذف آخر مدير في المدرسة — يجب أن يبقى مدير نشط واحد على الأقل", 400);
      }
    }
    const suffix = String(Date.now() % 100000).padStart(5, "0");
    const deleted = await db.user.update({
      where: { id },
      data: { isActive: false, deletedAt: new Date(), username: `${target.username}.del${suffix}` },
      select: { id: true, username: true, fullName: true, role: true, isActive: true, deletedAt: true },
    });
    await logAudit(user, {
      action: "DELETE",
      entity: "User",
      entityId: id,
      details: `حذف حساب المستخدم ${target.fullName} (@${target.username}) — الدور: ${target.role}`,
    });
    return NextResponse.json({ ok: true, user: deleted });
  } catch (err) {
    return handleApiError(err);
  }
}
