<?php
/**
 * ملف إدارة الصلاحيات
 * يحتوي هذا الملف على دوال إدارة الصلاحيات والتحقق منها
 *
 * @version 1.0
 * @author System Developer
 */

// تضمين ملف الاتصال بقاعدة البيانات إذا لم يكن موجودًا
if (!isset($conn) || !isset($pdo)) {
    require_once __DIR__ . '/../config/db_connection.php';
}

// تضمين ملف إدارة الجلسات (تم تعليقه لتجنب تعارض تعريف الثوابت)
// require_once __DIR__ . '/session_manager.php';

/**
 * التحقق من صلاحية المستخدم
 *
 * @param string $permissionName اسم الصلاحية
 * @return bool هل يملك المستخدم الصلاحية
 */
function checkUserPermission($permissionName) {
    // التحقق من تسجيل دخول المستخدم
    if (!isset($_SESSION['user_id'])) {
        return false;
    }

    // المدير يملك جميع الصلاحيات
    if (isset($_SESSION['role']) && $_SESSION['role'] === 'admin') {
        return true;
    }

    // الحصول على دور المستخدم
    $roleId = getUserRoleId();

    if (!$roleId) {
        return false;
    }

    // التحقق من وجود الصلاحية للدور
    return checkRolePermission($roleId, $permissionName);
}

/**
 * الحصول على معرف دور المستخدم
 *
 * @return int|null معرف الدور
 */
function getUserRoleId() {
    global $pdo;

    // التحقق من تسجيل دخول المستخدم
    if (!isset($_SESSION['user_id'])) {
        return null;
    }

    try {
        $stmt = $pdo->prepare("
            SELECT r.id
            FROM roles r
            JOIN users u ON r.name = u.role
            WHERE u.id = :user_id
        ");
        $stmt->execute(['user_id' => $_SESSION['user_id']]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);

        return $result ? $result['id'] : null;
    } catch (PDOException $e) {
        error_log("خطأ في الحصول على معرف دور المستخدم: " . $e->getMessage());
        return null;
    }
}

/**
 * التحقق من وجود صلاحية لدور
 *
 * @param int $roleId معرف الدور
 * @param string $permissionName اسم الصلاحية
 * @return bool هل يملك الدور الصلاحية
 */
function checkRolePermission($roleId, $permissionName) {
    global $pdo;

    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM role_permissions rp
            JOIN permissions p ON rp.permission_id = p.id
            WHERE rp.role_id = :role_id AND p.name = :permission_name
        ");
        $stmt->execute([
            'role_id' => $roleId,
            'permission_name' => $permissionName
        ]);

        return $stmt->fetchColumn() > 0;
    } catch (PDOException $e) {
        error_log("خطأ في التحقق من صلاحية الدور: " . $e->getMessage());
        return false;
    }
}

/**
 * الحصول على جميع صلاحيات المستخدم
 *
 * @param int $userId معرف المستخدم
 * @return array مصفوفة من الصلاحيات
 */
function getUserPermissions($userId = null) {
    global $pdo;

    // استخدام معرف المستخدم الحالي إذا لم يتم تحديده
    if ($userId === null) {
        if (!isset($_SESSION['user_id'])) {
            return [];
        }
        $userId = $_SESSION['user_id'];
    }

    try {
        $stmt = $pdo->prepare("
            SELECT p.*
            FROM permissions p
            JOIN role_permissions rp ON p.id = rp.permission_id
            JOIN roles r ON rp.role_id = r.id
            JOIN users u ON r.name = u.role
            WHERE u.id = :user_id
            ORDER BY p.category, p.id
        ");
        $stmt->execute(['user_id' => $userId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("خطأ في الحصول على صلاحيات المستخدم: " . $e->getMessage());
        return [];
    }
}

/**
 * الحصول على دور المستخدم
 *
 * @param int $userId معرف المستخدم
 * @return array|null معلومات الدور
 */
function getUserRole($userId = null) {
    global $pdo;

    // استخدام معرف المستخدم الحالي إذا لم يتم تحديده
    if ($userId === null) {
        if (!isset($_SESSION['user_id'])) {
            return null;
        }
        $userId = $_SESSION['user_id'];
    }

    try {
        $stmt = $pdo->prepare("
            SELECT r.*
            FROM roles r
            JOIN users u ON r.name = u.role
            WHERE u.id = :user_id
        ");
        $stmt->execute(['user_id' => $userId]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("خطأ في الحصول على دور المستخدم: " . $e->getMessage());
        return null;
    }
}

/**
 * إضافة دور جديد
 *
 * @param string $name اسم الدور
 * @param string $displayName الاسم المعروض
 * @param string $description وصف الدور
 * @return int|false معرف الدور الجديد أو false في حالة الفشل
 */
function addRole($name, $displayName, $description = '') {
    global $pdo;

    try {
        $stmt = $pdo->prepare("
            INSERT INTO roles (name, display_name, description)
            VALUES (:name, :display_name, :description)
        ");
        $stmt->execute([
            'name' => $name,
            'display_name' => $displayName,
            'description' => $description
        ]);

        return $pdo->lastInsertId();
    } catch (PDOException $e) {
        error_log("خطأ في إضافة دور جديد: " . $e->getMessage());
        return false;
    }
}

/**
 * تحديث دور
 *
 * @param int $id معرف الدور
 * @param string $displayName الاسم المعروض
 * @param string $description وصف الدور
 * @return bool نجاح العملية
 */
function updateRole($id, $displayName, $description = '') {
    global $pdo;

    try {
        $stmt = $pdo->prepare("
            UPDATE roles
            SET display_name = :display_name, description = :description
            WHERE id = :id AND is_system = 0
        ");
        $stmt->execute([
            'id' => $id,
            'display_name' => $displayName,
            'description' => $description
        ]);

        return $stmt->rowCount() > 0;
    } catch (PDOException $e) {
        error_log("خطأ في تحديث الدور: " . $e->getMessage());
        return false;
    }
}

/**
 * حذف دور
 *
 * @param int $id معرف الدور
 * @return bool نجاح العملية
 */
function deleteRole($id) {
    global $pdo;

    try {
        $stmt = $pdo->prepare("DELETE FROM roles WHERE id = :id AND is_system = 0");
        $stmt->execute(['id' => $id]);

        return $stmt->rowCount() > 0;
    } catch (PDOException $e) {
        error_log("خطأ في حذف الدور: " . $e->getMessage());
        return false;
    }
}

/**
 * إضافة صلاحية جديدة
 *
 * @param string $name اسم الصلاحية
 * @param string $displayName الاسم المعروض
 * @param string $description وصف الصلاحية
 * @param string $category فئة الصلاحية
 * @return int|false معرف الصلاحية الجديدة أو false في حالة الفشل
 */
function addPermission($name, $displayName, $description = '', $category = 'general') {
    global $pdo;

    try {
        $stmt = $pdo->prepare("
            INSERT INTO permissions (name, display_name, description, category)
            VALUES (:name, :display_name, :description, :category)
        ");
        $stmt->execute([
            'name' => $name,
            'display_name' => $displayName,
            'description' => $description,
            'category' => $category
        ]);

        return $pdo->lastInsertId();
    } catch (PDOException $e) {
        error_log("خطأ في إضافة صلاحية جديدة: " . $e->getMessage());
        return false;
    }
}

/**
 * تحديث صلاحية
 *
 * @param int $id معرف الصلاحية
 * @param string $displayName الاسم المعروض
 * @param string $description وصف الصلاحية
 * @param string $category فئة الصلاحية
 * @return bool نجاح العملية
 */
function updatePermission($id, $displayName, $description = '', $category = 'general') {
    global $pdo;

    try {
        $stmt = $pdo->prepare("
            UPDATE permissions
            SET display_name = :display_name, description = :description, category = :category
            WHERE id = :id
        ");
        $stmt->execute([
            'id' => $id,
            'display_name' => $displayName,
            'description' => $description,
            'category' => $category
        ]);

        return $stmt->rowCount() > 0;
    } catch (PDOException $e) {
        error_log("خطأ في تحديث الصلاحية: " . $e->getMessage());
        return false;
    }
}

/**
 * حذف صلاحية
 *
 * @param int $id معرف الصلاحية
 * @return bool نجاح العملية
 */
function deletePermission($id) {
    global $pdo;

    try {
        $stmt = $pdo->prepare("DELETE FROM permissions WHERE id = :id");
        $stmt->execute(['id' => $id]);

        return $stmt->rowCount() > 0;
    } catch (PDOException $e) {
        error_log("خطأ في حذف الصلاحية: " . $e->getMessage());
        return false;
    }
}

/**
 * الحصول على صلاحيات حسب الفئة
 *
 * @param string $category فئة الصلاحيات
 * @return array مصفوفة من الصلاحيات
 */
function getPermissionsByCategory($category) {
    global $pdo;

    try {
        $stmt = $pdo->prepare("SELECT * FROM permissions WHERE category = :category ORDER BY id");
        $stmt->execute(['category' => $category]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("خطأ في الحصول على الصلاحيات حسب الفئة: " . $e->getMessage());
        return [];
    }
}

/**
 * الحصول على فئات الصلاحيات
 *
 * @return array مصفوفة من فئات الصلاحيات
 */
function getPermissionCategories() {
    global $pdo;

    try {
        $stmt = $pdo->prepare("SELECT DISTINCT category FROM permissions ORDER BY category");
        $stmt->execute();
        $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

        $categories = [];
        foreach ($results as $row) {
            $categories[] = $row['category'];
        }

        return $categories;
    } catch (PDOException $e) {
        error_log("خطأ في الحصول على فئات الصلاحيات: " . $e->getMessage());
        return [];
    }
}

/**
 * الحصول على جميع الأدوار مع التحقق من وجود الجدول
 * (تم تعديل اسم الدالة لتجنب التعارض مع الدالة الموجودة في settings_manager.php)
 *
 * @return array مصفوفة من الأدوار
 */
function getSystemRoles() {
    global $pdo;

    try {
        // التحقق من وجود جدول الأدوار
        $stmt = $pdo->query("SHOW TABLES LIKE 'roles'");
        if ($stmt->rowCount() === 0) {
            // إذا لم يكن الجدول موجودًا، أرجع القيم الافتراضية
            return [
                ['id' => 1, 'name' => 'admin', 'display_name' => 'مدير النظام'],
                ['id' => 2, 'name' => 'manager', 'display_name' => 'مدير'],
                ['id' => 3, 'name' => 'employee', 'display_name' => 'موظف'],
                ['id' => 4, 'name' => 'client', 'display_name' => 'عميل']
            ];
        }

        $stmt = $pdo->query("SELECT * FROM roles ORDER BY id");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("خطأ في الحصول على الأدوار: " . $e->getMessage());
        // إرجاع القيم الافتراضية في حالة حدوث خطأ
        return [
            ['id' => 1, 'name' => 'admin', 'display_name' => 'مدير النظام'],
            ['id' => 2, 'name' => 'manager', 'display_name' => 'مدير'],
            ['id' => 3, 'name' => 'employee', 'display_name' => 'موظف'],
            ['id' => 4, 'name' => 'client', 'display_name' => 'عميل']
        ];
    }
}

/**
 * الحصول على جميع الصلاحيات
 * (تم تعديل اسم الدالة لتجنب التعارض مع الدالة الموجودة في settings_manager.php)
 *
 * @return array مصفوفة من الصلاحيات
 */
function getSystemPermissions() {
    global $pdo;

    try {
        // التحقق من وجود جدول الصلاحيات
        $stmt = $pdo->query("SHOW TABLES LIKE 'permissions'");
        if ($stmt->rowCount() === 0) {
            // إذا لم يكن الجدول موجودًا، أرجع مصفوفة فارغة
            return [];
        }

        $stmt = $pdo->query("SELECT * FROM permissions ORDER BY category, id");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("خطأ في الحصول على الصلاحيات: " . $e->getMessage());
        return [];
    }
}

/**
 * إنشاء جداول الصلاحيات إذا لم تكن موجودة
 */
function createPermissionsTables() {
    global $pdo;

    try {
        // التحقق من وجود جدول الأدوار
        $stmt = $pdo->query("SHOW TABLES LIKE 'roles'");
        if ($stmt->rowCount() === 0) {
            // إنشاء جدول الأدوار
            $pdo->exec("
                CREATE TABLE `roles` (
                  `id` INT AUTO_INCREMENT PRIMARY KEY,
                  `name` VARCHAR(50) NOT NULL UNIQUE COMMENT 'اسم الدور',
                  `display_name` VARCHAR(100) NOT NULL COMMENT 'الاسم المعروض',
                  `description` TEXT DEFAULT NULL COMMENT 'وصف الدور',
                  `is_system` TINYINT(1) DEFAULT 0 COMMENT 'هل هو دور نظام',
                  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'تاريخ الإنشاء',
                  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'تاريخ التحديث'
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ");

            // إدراج الأدوار الافتراضية
            $pdo->exec("
                INSERT INTO `roles` (`name`, `display_name`, `description`, `is_system`) VALUES
                ('admin', 'مدير النظام', 'يمتلك جميع الصلاحيات في النظام', 1),
                ('manager', 'مدير', 'يمتلك صلاحيات إدارية محدودة', 1),
                ('employee', 'موظف', 'يمتلك صلاحيات أساسية للعمل', 1),
                ('client', 'عميل', 'يمتلك صلاحيات محدودة للعملاء', 1)
            ");
        }

        // التحقق من وجود جدول الصلاحيات
        $stmt = $pdo->query("SHOW TABLES LIKE 'permissions'");
        if ($stmt->rowCount() === 0) {
            // إنشاء جدول الصلاحيات
            $pdo->exec("
                CREATE TABLE `permissions` (
                  `id` INT AUTO_INCREMENT PRIMARY KEY,
                  `name` VARCHAR(50) NOT NULL UNIQUE COMMENT 'اسم الصلاحية',
                  `display_name` VARCHAR(100) NOT NULL COMMENT 'الاسم المعروض',
                  `description` TEXT DEFAULT NULL COMMENT 'وصف الصلاحية',
                  `category` VARCHAR(50) DEFAULT 'general' COMMENT 'فئة الصلاحية',
                  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'تاريخ الإنشاء',
                  `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'تاريخ التحديث'
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ");

            // إدراج الصلاحيات الافتراضية
            $pdo->exec("
                INSERT INTO `permissions` (`name`, `display_name`, `description`, `category`) VALUES
                ('view_dashboard', 'عرض لوحة التحكم', 'السماح بعرض لوحة التحكم الرئيسية', 'dashboard'),
                ('view_users', 'عرض المستخدمين', 'السماح بعرض قائمة المستخدمين', 'users'),
                ('add_users', 'إضافة مستخدمين', 'السماح بإضافة مستخدمين جدد', 'users'),
                ('edit_users', 'تعديل المستخدمين', 'السماح بتعديل بيانات المستخدمين', 'users'),
                ('delete_users', 'حذف المستخدمين', 'السماح بحذف المستخدمين', 'users'),
                ('view_orders', 'عرض الطلبات', 'السماح بعرض قائمة الطلبات', 'orders'),
                ('create_orders', 'إنشاء طلبات', 'السماح بإنشاء طلبات جديدة', 'orders'),
                ('edit_orders', 'تعديل الطلبات', 'السماح بتعديل الطلبات', 'orders'),
                ('delete_orders', 'حذف الطلبات', 'السماح بحذف الطلبات', 'orders'),
                ('view_reports', 'عرض التقارير', 'السماح بعرض التقارير', 'reports'),
                ('view_statistics', 'عرض الإحصائيات', 'السماح بعرض الإحصائيات', 'reports'),
                ('export_data', 'تصدير البيانات', 'السماح بتصدير البيانات', 'data')
            ");
        }

        // التحقق من وجود جدول العلاقة بين الأدوار والصلاحيات
        $stmt = $pdo->query("SHOW TABLES LIKE 'role_permissions'");
        if ($stmt->rowCount() === 0) {
            // إنشاء جدول العلاقة بين الأدوار والصلاحيات
            $pdo->exec("
                CREATE TABLE `role_permissions` (
                  `id` INT AUTO_INCREMENT PRIMARY KEY,
                  `role_id` INT NOT NULL COMMENT 'معرف الدور',
                  `permission_id` INT NOT NULL COMMENT 'معرف الصلاحية',
                  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'تاريخ الإنشاء',
                  UNIQUE KEY `role_permission_unique` (`role_id`, `permission_id`),
                  FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE CASCADE,
                  FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`) ON DELETE CASCADE
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ");

            // إدراج صلاحيات الدور: مدير النظام (admin)
            $pdo->exec("
                INSERT INTO `role_permissions` (`role_id`, `permission_id`)
                SELECT r.id, p.id FROM `roles` r, `permissions` p
                WHERE r.name = 'admin'
            ");

            // إدراج صلاحيات الدور: مدير (manager)
            $pdo->exec("
                INSERT INTO `role_permissions` (`role_id`, `permission_id`)
                SELECT r.id, p.id FROM `roles` r, `permissions` p
                WHERE r.name = 'manager' AND p.name IN (
                  'view_dashboard', 'view_users', 'view_orders', 'create_orders', 'edit_orders',
                  'view_reports', 'view_statistics', 'export_data'
                )
            ");

            // إدراج صلاحيات الدور: موظف (employee)
            $pdo->exec("
                INSERT INTO `role_permissions` (`role_id`, `permission_id`)
                SELECT r.id, p.id FROM `roles` r, `permissions` p
                WHERE r.name = 'employee' AND p.name IN (
                  'view_dashboard', 'view_orders', 'create_orders'
                )
            ");

            // إدراج صلاحيات الدور: عميل (client)
            $pdo->exec("
                INSERT INTO `role_permissions` (`role_id`, `permission_id`)
                SELECT r.id, p.id FROM `roles` r, `permissions` p
                WHERE r.name = 'client' AND p.name IN (
                  'view_dashboard', 'view_orders'
                )
            ");
        }

        // التحقق من وجود جدول صلاحيات المستخدمين
        $stmt = $pdo->query("SHOW TABLES LIKE 'user_permissions'");
        if ($stmt->rowCount() === 0) {
            // إنشاء جدول صلاحيات المستخدمين
            $pdo->exec("
                CREATE TABLE `user_permissions` (
                  `id` INT AUTO_INCREMENT PRIMARY KEY,
                  `user_id` INT NOT NULL COMMENT 'معرف المستخدم',
                  `permission_id` INT NOT NULL COMMENT 'معرف الصلاحية',
                  `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'تاريخ الإنشاء',
                  UNIQUE KEY `user_permission_unique` (`user_id`, `permission_id`),
                  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
                  FOREIGN KEY (`permission_id`) REFERENCES `permissions`(`id`) ON DELETE CASCADE
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
            ");
        }

        return true;
    } catch (PDOException $e) {
        error_log("خطأ في إنشاء جداول الصلاحيات: " . $e->getMessage());
        return false;
    }
}

// محاولة إنشاء جداول الصلاحيات عند تضمين الملف
createPermissionsTables();
