<?php
// Start or resume the session
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

// Default to not output HTML unless explicitly requested
$outputSessionTimeoutHTML = false;

// Include configuration and helper files
require_once './includes/config.php';
require_once './includes/audit_helper.php';

// Define session timeout in seconds (30 minutes)
define('SESSION_TIMEOUT', 1800);

// Rate limiting to prevent brute-force attacks
function checkRateLimit($pdo, $ipAddress) {
    $limit = 10; // Max allowed requests
    $timeWindow = 60; // Time window in seconds

    $stmt = $pdo->prepare("
        SELECT COUNT(*) 
        FROM rate_limits 
        WHERE ip_address = :ip AND timestamp > DATE_SUB(NOW(), INTERVAL :window SECOND)
    ");
    $stmt->execute(['ip' => $ipAddress, 'window' => $timeWindow]);
    $count = $stmt->fetchColumn();

    if ($count >= $limit) {
        error_log("Rate limit exceeded for IP: " . $ipAddress);
        header("HTTP/1.1 429 Too Many Requests");
        exit("Too many requests. Please try again later.");
    }

    // Log the request
    $stmt = $pdo->prepare("INSERT INTO rate_limits (ip_address) VALUES (:ip)");
    $stmt->execute(['ip' => $ipAddress]);
}

// Check rate limit before proceeding
checkRateLimit($pdo, $_SERVER['REMOTE_ADDR']);

// Function to check session timeout
function checkSessionTimeout() {
    $timeoutDuration = SESSION_TIMEOUT;

    if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity']) > $timeoutDuration) {
        session_unset();
        session_destroy();
        header("Location: login.php");
        exit();
    }

    $_SESSION['last_activity'] = time();
}

// Function to check if a user has a specific permission
function hasPermission($userId, $permission, $pdo) {
    try {
        $stmt = $pdo->prepare("
            SELECT 1 
            FROM users u
            JOIN roles r ON u.role_id = r.id
            LEFT JOIN user_permissions up ON u.id = up.user_id
            LEFT JOIN permissions p ON up.permission_id = p.id
            WHERE u.id = :user_id AND (LOWER(r.name) = 'superadmin' OR p.name = :permission)
        ");
        $stmt->execute(['user_id' => $userId, 'permission' => $permission]);
        return $stmt->fetchColumn() !== false;
    } catch (PDOException $e) {
        error_log("Database error in hasPermission: " . $e->getMessage());
        return false;
    }
}

// Function to check if a user is a Super Admin
function isSuperAdmin($userId, $pdo) {
    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*)
            FROM users
            WHERE id = :userId AND role_id = (
                SELECT id FROM roles WHERE LOWER(name) = 'superadmin'
            )
        ");
        $stmt->execute(['userId' => $userId]);
        return $stmt->fetchColumn() > 0;
    } catch (PDOException $e) {
        error_log("Database error in isSuperAdmin: " . $e->getMessage());
        return false;
    }
}

// Include the session timeout check at the beginning of every page
checkSessionTimeout();

/**
 * Outputs the session timeout warning HTML and JavaScript
 * Call this function only in pages where you want the timeout warning to appear
 */
function outputSessionTimeoutWarning() {
    ?>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!-- Include SweetAlert2 for a better warning dialog -->
        <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
        <script>
            let timeoutWarning;
            let timeoutLogout;
            const warningTime = 60000; // 1 minute (in milliseconds)
            const sessionTimeout = <?php echo SESSION_TIMEOUT * 1000; ?>; // Convert PHP timeout to milliseconds

            function startSessionTimer() {
                timeoutWarning = setTimeout(() => {
                    showWarning();
                }, sessionTimeout - warningTime);
            }

            function showWarning() {
                Swal.fire({
                    title: 'Session Expiry Warning',
                    html: 'Your session is about to expire in <span id="countdown">1:00</span>. Do you want to stay logged in?',
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonText: 'Stay Logged In',
                    cancelButtonText: 'Log Out',
                    timer: warningTime,
                    timerProgressBar: true,
                    didOpen: () => {
                        const timer = Swal.getPopup().querySelector('b');
                        let timeLeft = warningTime / 1000;
                        const interval = setInterval(() => {
                            timeLeft--;
                            timer.textContent = `${Math.floor(timeLeft / 60)}:${timeLeft % 60 < 10 ? '0' : ''}${timeLeft % 60}`;
                        }, 1000);
                        Swal.getPopup().addEventListener('mouseenter', () => clearInterval(interval));
                        Swal.getPopup().addEventListener('mouseleave', () => {
                            interval = setInterval(() => {
                                timeLeft--;
                                timer.textContent = `${Math.floor(timeLeft / 60)}:${timeLeft % 60 < 10 ? '0' : ''}${timeLeft % 60}`;
                            }, 1000);
                        });
                    }
                }).then((result) => {
                    if (result.isConfirmed) {
                        resetSessionTimer();
                    } else if (result.dismiss === Swal.DismissReason.timer) {
                        logoutUser();
                    } else {
                        logoutUser();
                    }
                });

                timeoutLogout = setTimeout(() => {
                    logoutUser();
                }, warningTime);
            }

            function resetSessionTimer() {
                clearTimeout(timeoutLogout);
                fetch("refresh_session.php")
                    .then(response => response.json())
                    .then(data => {
                        if (data.success) {
                            clearTimeout(timeoutWarning);
                            startSessionTimer();
                        }
                    })
                    .catch(error => console.error("Error refreshing session:", error));
            }

            function logoutUser() {
                window.location.href = "logout.php";
            }

            window.onload = startSessionTimer;
        </script>
    </head>
    </html>
    <?php
}