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

// بدء الجلسة إذا لم تكن قد بدأت بالفعل
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// تضمين ملف الاتصال بقاعدة البيانات
require_once __DIR__ . '/../config/db_connection.php';

/**
 * تسجيل دخول المستخدم
 * 
 * @param string $username اسم المستخدم أو البريد الإلكتروني
 * @param string $password كلمة المرور
 * @param bool $remember تذكر تسجيل الدخول
 * @return array مصفوفة تحتوي على نتيجة تسجيل الدخول
 */
function loginUser($username, $password, $remember = false) {
    global $conn;
    
    try {
        // التحقق من وجود المستخدم باستخدام اسم المستخدم أو البريد الإلكتروني
        $stmt = $conn->prepare("SELECT * FROM users WHERE username = :username OR email = :email");
        $stmt->bindParam(':username', $username);
        $stmt->bindParam(':email', $username);
        $stmt->execute();
        
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        // التحقق من وجود المستخدم
        if (!$user) {
            return [
                'success' => false,
                'message' => 'اسم المستخدم أو كلمة المرور غير صحيحة'
            ];
        }
        
        // التحقق من حالة المستخدم
        if ($user['status'] === 'pending') {
            return [
                'success' => false,
                'message' => 'حسابك قيد المراجعة. يرجى الانتظار حتى تتم الموافقة عليه.'
            ];
        }
        
        if ($user['status'] === 'inactive') {
            return [
                'success' => false,
                'message' => 'تم تعطيل حسابك. يرجى التواصل مع الإدارة.'
            ];
        }
        
        // التحقق من كلمة المرور
        if (!password_verify($password, $user['password'])) {
            // تسجيل محاولة تسجيل دخول فاشلة
            logFailedLoginAttempt($username);
            
            return [
                'success' => false,
                'message' => 'اسم المستخدم أو كلمة المرور غير صحيحة'
            ];
        }
        
        // تحديث آخر تسجيل دخول
        $stmt = $conn->prepare("UPDATE users SET last_login = NOW() WHERE id = :id");
        $stmt->bindParam(':id', $user['id']);
        $stmt->execute();
        
        // تخزين معلومات المستخدم في الجلسة
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['username'] = $user['username'];
        $_SESSION['full_name'] = $user['full_name'];
        $_SESSION['email'] = $user['email'];
        $_SESSION['role'] = $user['role'];
        $_SESSION['branch_id'] = $user['branch_id'];
        $_SESSION['logged_in'] = true;
        $_SESSION['login_time'] = time();
        $_SESSION['last_activity'] = time();
        
        // إنشاء رمز CSRF للجلسة
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        
        // إذا كان المستخدم اختار تذكر تسجيل الدخول
        if ($remember) {
            // إنشاء رمز تذكر تسجيل الدخول
            $token = bin2hex(random_bytes(32));
            $expires = date('Y-m-d H:i:s', strtotime('+30 days'));
            $userAgent = $_SERVER['HTTP_USER_AGENT'];
            $ip = $_SERVER['REMOTE_ADDR'];
            
            // تشفير البيانات
            $tokenHash = hash('sha256', $token);
            
            // حذف أي رموز قديمة للمستخدم
            $stmt = $conn->prepare("DELETE FROM remember_tokens WHERE user_id = :user_id");
            $stmt->bindParam(':user_id', $user['id']);
            $stmt->execute();
            
            // تخزين الرمز في قاعدة البيانات
            $stmt = $conn->prepare("INSERT INTO remember_tokens (user_id, token, expires, user_agent, ip) VALUES (:user_id, :token, :expires, :user_agent, :ip)");
            $stmt->bindParam(':user_id', $user['id']);
            $stmt->bindParam(':token', $tokenHash);
            $stmt->bindParam(':expires', $expires);
            $stmt->bindParam(':user_agent', $userAgent);
            $stmt->bindParam(':ip', $ip);
            $stmt->execute();
            
            // تعيين ملف تعريف الارتباط
            setcookie('remember_token', $token, strtotime('+30 days'), '/', '', true, true);
        }
        
        return [
            'success' => true,
            'message' => 'تم تسجيل الدخول بنجاح',
            'user' => $user
        ];
    } catch (PDOException $e) {
        // تسجيل الخطأ
        error_log('خطأ في تسجيل الدخول: ' . $e->getMessage());
        
        return [
            'success' => false,
            'message' => 'حدث خطأ أثناء تسجيل الدخول. يرجى المحاولة مرة أخرى.'
        ];
    }
}

/**
 * تسجيل محاولة تسجيل دخول فاشلة
 * 
 * @param string $username اسم المستخدم أو البريد الإلكتروني
 */
function logFailedLoginAttempt($username) {
    global $conn;
    
    try {
        // التحقق من وجود جدول محاولات تسجيل الدخول
        $stmt = $conn->prepare("
            CREATE TABLE IF NOT EXISTS login_attempts (
                id INT AUTO_INCREMENT PRIMARY KEY,
                username VARCHAR(100) NOT NULL,
                ip VARCHAR(45) NOT NULL,
                user_agent TEXT,
                attempt_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ");
        $stmt->execute();
        
        // تسجيل محاولة تسجيل الدخول الفاشلة
        $ip = $_SERVER['REMOTE_ADDR'];
        $userAgent = $_SERVER['HTTP_USER_AGENT'];
        
        $stmt = $conn->prepare("INSERT INTO login_attempts (username, ip, user_agent) VALUES (:username, :ip, :user_agent)");
        $stmt->bindParam(':username', $username);
        $stmt->bindParam(':ip', $ip);
        $stmt->bindParam(':user_agent', $userAgent);
        $stmt->execute();
    } catch (PDOException $e) {
        // تسجيل الخطأ
        error_log('خطأ في تسجيل محاولة تسجيل الدخول الفاشلة: ' . $e->getMessage());
    }
}

/**
 * التحقق من عدد محاولات تسجيل الدخول الفاشلة
 * 
 * @param string $username اسم المستخدم أو البريد الإلكتروني
 * @param int $maxAttempts الحد الأقصى لعدد المحاولات
 * @param int $timeWindow نافذة الوقت بالدقائق
 * @return bool ما إذا كان المستخدم تجاوز الحد الأقصى لعدد المحاولات
 */
function isUserLocked($username, $maxAttempts = 5, $timeWindow = 30) {
    global $conn;
    
    try {
        // التحقق من وجود جدول محاولات تسجيل الدخول
        $stmt = $conn->prepare("SHOW TABLES LIKE 'login_attempts'");
        $stmt->execute();
        
        if ($stmt->rowCount() === 0) {
            return false;
        }
        
        // الحصول على عدد محاولات تسجيل الدخول الفاشلة في نافذة الوقت المحددة
        $ip = $_SERVER['REMOTE_ADDR'];
        $timeAgo = date('Y-m-d H:i:s', strtotime("-{$timeWindow} minutes"));
        
        $stmt = $conn->prepare("
            SELECT COUNT(*) as attempts 
            FROM login_attempts 
            WHERE (username = :username OR ip = :ip) 
            AND attempt_time > :time_ago
        ");
        $stmt->bindParam(':username', $username);
        $stmt->bindParam(':ip', $ip);
        $stmt->bindParam(':time_ago', $timeAgo);
        $stmt->execute();
        
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        return $result['attempts'] >= $maxAttempts;
    } catch (PDOException $e) {
        // تسجيل الخطأ
        error_log('خطأ في التحقق من قفل المستخدم: ' . $e->getMessage());
        
        // في حالة حدوث خطأ، نفترض أن المستخدم غير مقفل
        return false;
    }
}

/**
 * تسجيل خروج المستخدم
 */
function logoutUser() {
    // حذف رمز تذكر تسجيل الدخول من قاعدة البيانات إذا كان موجودًا
    if (isset($_SESSION['user_id'])) {
        try {
            global $conn;
            
            $stmt = $conn->prepare("DELETE FROM remember_tokens WHERE user_id = :user_id");
            $stmt->bindParam(':user_id', $_SESSION['user_id']);
            $stmt->execute();
        } catch (PDOException $e) {
            // تسجيل الخطأ
            error_log('خطأ في حذف رمز تذكر تسجيل الدخول: ' . $e->getMessage());
        }
    }
    
    // حذف ملف تعريف الارتباط
    if (isset($_COOKIE['remember_token'])) {
        setcookie('remember_token', '', time() - 3600, '/', '', true, true);
    }
    
    // تدمير الجلسة
    session_unset();
    session_destroy();
    
    // إعادة بدء الجلسة لتجنب الأخطاء
    session_start();
}

/**
 * التحقق من حالة تسجيل الدخول
 * 
 * @return bool حالة تسجيل الدخول
 */
function isLoggedIn() {
    // التحقق من وجود معلومات المستخدم في الجلسة
    if (isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true) {
        // تحديث وقت آخر نشاط
        $_SESSION['last_activity'] = time();
        return true;
    }
    
    // التحقق من وجود رمز تذكر تسجيل الدخول
    if (isset($_COOKIE['remember_token'])) {
        return loginWithRememberToken($_COOKIE['remember_token']);
    }
    
    return false;
}

/**
 * تسجيل دخول المستخدم باستخدام رمز تذكر تسجيل الدخول
 * 
 * @param string $token رمز تذكر تسجيل الدخول
 * @return bool نجاح تسجيل الدخول
 */
function loginWithRememberToken($token) {
    global $conn;
    
    try {
        // التحقق من وجود جدول رموز تذكر تسجيل الدخول
        $stmt = $conn->prepare("SHOW TABLES LIKE 'remember_tokens'");
        $stmt->execute();
        
        if ($stmt->rowCount() === 0) {
            return false;
        }
        
        // تشفير الرمز
        $tokenHash = hash('sha256', $token);
        
        // البحث عن الرمز في قاعدة البيانات
        $stmt = $conn->prepare("
            SELECT rt.*, u.* 
            FROM remember_tokens rt
            JOIN users u ON rt.user_id = u.id
            WHERE rt.token = :token 
            AND rt.expires > NOW()
            AND rt.user_agent = :user_agent
        ");
        $stmt->bindParam(':token', $tokenHash);
        $stmt->bindParam(':user_agent', $_SERVER['HTTP_USER_AGENT']);
        $stmt->execute();
        
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$result) {
            // حذف ملف تعريف الارتباط إذا كان الرمز غير صالح
            setcookie('remember_token', '', time() - 3600, '/', '', true, true);
            return false;
        }
        
        // تخزين معلومات المستخدم في الجلسة
        $_SESSION['user_id'] = $result['user_id'];
        $_SESSION['username'] = $result['username'];
        $_SESSION['full_name'] = $result['full_name'];
        $_SESSION['email'] = $result['email'];
        $_SESSION['role'] = $result['role'];
        $_SESSION['branch_id'] = $result['branch_id'];
        $_SESSION['logged_in'] = true;
        $_SESSION['login_time'] = time();
        $_SESSION['last_activity'] = time();
        
        // إنشاء رمز CSRF للجلسة
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        
        return true;
    } catch (PDOException $e) {
        // تسجيل الخطأ
        error_log('خطأ في تسجيل الدخول باستخدام رمز تذكر تسجيل الدخول: ' . $e->getMessage());
        
        return false;
    }
}
