<?php

// auth_guard.php (النسخة الموحدة للدخول والحماية)

// ----------------------------------------------------
// 1. إعدادات الجلسة وبدؤها (يجب أن تكون قبل أي إخراج)
// ----------------------------------------------------

$lifetime = 60 * 60 * 24 * 7; // أسبوع واحد

// 🔑 إعدادات آمنة للجلسة
session_set_cookie_params([
    'lifetime' => $lifetime,
    'path' => '/',
    // 💡 التحسين: استخدام HTTPS لتأمين الكوكيز إذا كان متاحًا
    'secure' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on',
    'httponly' => true,
    'samesite' => 'Lax'
]);

// 🔑 بدء الجلسة إذا لم يتم البدء
if (session_status() === PHP_SESSION_NONE) {
    session_name('CLIENT_SAIDI_SESSION');
    session_start();
}

// 2. تضمين ملفات الاتصال والتشفير
// يجب التأكد من صحة مسارات الملفات
require_once __DIR__ . '/../db_connect.php'; 
require_once __DIR__ . '/../inc/SecureIdHandler.php'; 

// ----------------------------------------------------
// 3. منطق الحظر التصاعدي
// ----------------------------------------------------

$lockout_durations = [
    1 => 60,        // محاولة أولى فاشلة بعد الصفر: 60 ثانية
    2 => 600,       // محاولة ثانية فاشلة بعد الأولى: 10 دقائق
    3 => 172800,    // محاولة ثالثة فاشلة بعد الثانية: 48 ساعة (حظر طويل)
];

/**
 * وظيفة للتحقق من حالة الحظر لعنوان IP الحالي
 * @param PDO $pdo اتصال قاعدة البيانات
 * @param string $ip_address عنوان IP
 * @return array تحتوي على is_locked_out, is_permanent_blocked, error, attempt_record
 */
function checkLockoutStatus(PDO $pdo, string $ip_address): array {
    // لا نحتاج لـ global $lockout_durations هنا، لكنه موجود في الكود الأصلي.
    $result = [
        'is_locked_out' => false,
        'is_permanent_blocked' => false,
        'error' => '',
        'attempt_record' => null
    ];

    $stmt = $pdo->prepare("SELECT attempts, lockout_until, is_permanent FROM login_attempts WHERE ip_address = ?");
    $stmt->execute([$ip_address]);
    $attempt_record = $stmt->fetch(PDO::FETCH_ASSOC);
    $result['attempt_record'] = $attempt_record;

    if ($attempt_record) {
        // 3.1 التحقق من الحظر الدائم
        if ($attempt_record['is_permanent']) {
            $result['is_locked_out'] = true;
            $result['is_permanent_blocked'] = true;
            $result['error'] = "🔴 تم حظر الوصول إلى هذا النظام نهائياً من عنوان IP هذا.";
        } 
        // 3.2 التحقق من الحظر المؤقت
        elseif ($attempt_record['lockout_until']) {
            $lockout_time = strtotime($attempt_record['lockout_until']);
            $current_time = time();

            if ($lockout_time > $current_time) {
                $result['is_locked_out'] = true;
                $remaining_time = $lockout_time - $current_time;
                $minutes = floor($remaining_time / 60);
                $seconds = $remaining_time % 60;
                $result['error'] = "🔴 لقد تجاوزت الحد المسموح به. يرجى المحاولة بعد: $minutes دقائق و $seconds ثواني.";
            } else {
                // انتهى وقت الحظر المؤقت: (اختياري) تنظيف السجل
                $pdo->prepare("UPDATE login_attempts SET lockout_until = NULL WHERE ip_address = ?")->execute([$ip_address]);
            }
        }
    }
    return $result;
}


// ----------------------------------------------------
// 4. وظيفة تسجيل الدخول التلقائي (تذكرني) - تم تحسين الأمان
// ----------------------------------------------------

/**
 * دالة لتوليد رمز مميز آمن ومقسم (Split Token)
 * @return array تحتوي على raw_token و hashed_token
 */
function generateSecureToken(): array {
    // توليد رمز مميز عشوائي وآمن جداً
    $raw_token = bin2hex(random_bytes(32)); 
    // هاش الرمز الخام للتخزين في قاعدة البيانات
    $hashed_token = hash('sha256', $raw_token);
    return ['raw_token' => $raw_token, 'hashed_token' => $hashed_token];
}

function attemptAutoLogin() {
    global $pdo;
    
    // التحقق من وجود الكوكي
    if (isset($_COOKIE['saidi_remember_token'])) {
        $raw_token = $_COOKIE['saidi_remember_token'];
        $current_time = date('Y-m-d H:i:s');
        
        // 🛑 الأمان: يجب هاش الرمز الخام قبل البحث في قاعدة البيانات
        $hashed_token = hash('sha256', $raw_token);

        // 🛑 الأمان: يجب البحث عن الرمز الهاش وليس الرمز الخام
        $stmt = $pdo->prepare("SELECT id, username, role, token_expiry FROM users WHERE remember_token = ? AND token_expiry > ? LIMIT 1");
        $stmt->execute([$hashed_token, $current_time]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user) {
            // تسجيل الدخول
            $_SESSION['user_id'] = $user['id'];
            $_SESSION['username'] = $user['username'];
            $_SESSION['role'] = $user['role'];

            // 💡 الأمان: تجديد الرمز المميز (Rotation) واستخدام رمز جديد
            $seconds_in_30_days = 86400 * 30;
            $new_cookie_expiry = time() + $seconds_in_30_days; 
            $new_db_expiry = date('Y-m-d H:i:s', $new_cookie_expiry); 
            
            // توليد رمز مميز جديد وآمن
            $new_tokens = generateSecureToken(); 

            // تحديث قاعدة البيانات بالرمز الهاش الجديد
            $updateStmt = $pdo->prepare("UPDATE users SET remember_token = ?, token_expiry = ? WHERE id = ?");
            $updateStmt->execute([$new_tokens['hashed_token'], $new_db_expiry, $user['id']]);

            // إعداد كوكي جديد بالرمز الخام الجديد
            setcookie("saidi_remember_token", $new_tokens['raw_token'], [
                'expires' => $new_cookie_expiry, 
                'path' => '/',
                'secure' => isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on', // استخدم نفس إعدادات الجلسة
                'httponly' => true,
                'samesite' => 'Lax'
            ]);

            return true;

        } else {
            // فشل التحقق، حذف الكوكي
            setcookie("saidi_remember_token", "", time() - 3600, '/');
        }
    }

    return false;
}


// ----------------------------------------------------
// 5. وظيفة حماية الصفحة
// ----------------------------------------------------

function protectPage(string $required_role = 'any', string $redirect_url = '../auth/login.php') {
    global $pdo; 
    
    // 5.1 التحقق من وجود جلسة
    if (!isset($_SESSION['user_id'])) {
        // محاولة تسجيل الدخول التلقائي
        $loggedIn = attemptAutoLogin();
        
        if (!$loggedIn) {
            header("Location: " . $redirect_url);
            exit;
        }
    }

    // 5.2 التحقق من الدور
    $current_role = $_SESSION['role'] ?? 'guest'; 

    if ($required_role !== 'any') {
        if ($required_role === 'admin' && $current_role !== 'admin') {
            // 💡 التحسين: إعادة التوجيه إلى لوحة التحكم بدلًا من إيقاف الصفحة
            header("Location: dashboard.php");
            exit;
        }
        // يمكن إضافة المزيد من التحقق للدور assistant إذا لزم الأمر
    }

    // 5.3 تحديث المتغيرات العامة
    $GLOBALS['isAdmin'] = ($current_role == 'admin');
    $GLOBALS['isAssistant'] = ($current_role == 'assistant');
    $GLOBALS['current_user_id'] = $_SESSION['user_id'] ?? null; // يجب أن يكون موجودًا بعد التحقق
    $GLOBALS['current_username'] = $_SESSION['username'] ?? 'Guest';
    $GLOBALS['current_role'] = $current_role;
}

?>