<?php
require_once 'functions.php';
// Session Management Functions
class SessionManager {
    private static $instance = null;
    private $db;

    private function __construct() {
        global $functions;
        $this->functions = $functions;
        $this->db = Database::getInstance()->getConnection();
    }

    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // Start secure session
    public function startSecureSession() {
        if (session_status() == PHP_SESSION_NONE) {
            // Set secure session parameters
            ini_set('session.cookie_httponly', 1);
            ini_set('session.cookie_secure', isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on');
            ini_set('session.use_only_cookies', 1);
            ini_set('session.cookie_samesite', 'Strict');

            session_start();

            // Regenerate session ID periodically for security
            if (!isset($_SESSION['last_regeneration'])) {
                $_SESSION['last_regeneration'] = time();
            } elseif (time() - $_SESSION['last_regeneration'] > 300) { // 5 minutes
                session_regenerate_id(true);
                $_SESSION['last_regeneration'] = time();
            }
        }
    }

    // Set user session data
    public function setUserSession($user_id, $username, $email, $role = 'user') {
        $_SESSION['user_id'] = $user_id;
        $_SESSION['username'] = $username;
        $_SESSION['email'] = $email;
        $_SESSION['role'] = $role;
        $_SESSION['login_time'] = time();
        $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
    }

    // Set admin session data
    public function setAdminSession($admin_id, $username, $email, $role) {
        $_SESSION['admin_id'] = $admin_id;
        $_SESSION['admin_username'] = $username;
        $_SESSION['admin_email'] = $email;
        $_SESSION['admin_role'] = $role;
        $_SESSION['admin_login_time'] = time();
        $_SESSION['admin_ip_address'] = $_SERVER['REMOTE_ADDR'];
        $_SESSION['admin_user_agent'] = $_SERVER['HTTP_USER_AGENT'];
    }

    // Check if user is logged in
    public function isUserLoggedIn() {
        return isset($_SESSION['user_id']) &&
               isset($_SESSION['ip_address']) &&
               $_SESSION['ip_address'] === $_SERVER['REMOTE_ADDR'] &&
               isset($_SESSION['user_agent']) &&
               $_SESSION['user_agent'] === $_SERVER['HTTP_USER_AGENT'];
    }

    // Check if admin is logged in
    public function isAdminLoggedIn() {
        return isset($_SESSION['admin_id']) &&
               isset($_SESSION['admin_ip_address']) &&
               $_SESSION['admin_ip_address'] === $_SERVER['REMOTE_ADDR'] &&
               isset($_SESSION['admin_user_agent']) &&
               $_SESSION['admin_user_agent'] === $_SERVER['HTTP_USER_AGENT'];
    }

    // Get current user ID
    public function getCurrentUserId() {
        return $_SESSION['user_id'] ?? null;
    }

    // Get current admin ID
    public function getCurrentAdminId() {
        return $_SESSION['admin_id'] ?? null;
    }

    // Get current user role
    public function getCurrentUserRole() {
        return $_SESSION['role'] ?? null;
    }

    // Get current admin role
    public function getCurrentAdminRole() {
        return $_SESSION['admin_role'] ?? null;
    }

    // Update last activity
    public function updateLastActivity() {
        if ($this->isUserLoggedIn()) {
            $_SESSION['last_activity'] = time();
        } elseif ($this->isAdminLoggedIn()) {
            $_SESSION['admin_last_activity'] = time();
        }
    }

    // Check session timeout (30 minutes for users, 60 minutes for admins)
    public function isSessionExpired() {
        $timeout = $this->isAdminLoggedIn() ? 3600 : 1800; // 60 min for admin, 30 min for users

        if ($this->isUserLoggedIn()) {
            return isset($_SESSION['last_activity']) &&
                   (time() - $_SESSION['last_activity']) > $timeout;
        } elseif ($this->isAdminLoggedIn()) {
            return isset($_SESSION['admin_last_activity']) &&
                   (time() - $_SESSION['admin_last_activity']) > $timeout;
        }

        return false;
    }

    // Destroy session
    public function destroySession() {
        // Clear all session variables
        $_SESSION = [];

        // Destroy the session cookie
        if (isset($_COOKIE[session_name()])) {
            setcookie(session_name(), '', time() - 3600, '/');
        }

        // Destroy the session
        session_destroy();
    }

    // Logout user
    public function logoutUser() {
        // Log logout activity
        if ($this->isUserLoggedIn()) {
            $this->functions->logActivity($_SESSION['user_id'], 'logout', ['description' => 'User logged out']);
        }

        $this->destroySession();
    }

    // Logout admin
    public function logoutAdmin() {
        // Log admin logout activity
        if ($this->isAdminLoggedIn()) {
            $this->functions->logActivity($_SESSION['admin_id'], 'admin_logout', ['description' => 'Admin logged out']);
        }

        $this->destroySession();
    }

    // Validate session integrity
    public function validateSession() {
        if ($this->isUserLoggedIn()) {
            // Check if IP address changed (possible session hijacking)
            if ($_SESSION['ip_address'] !== $_SERVER['REMOTE_ADDR']) {
                $this->logoutUser();
                return false;
            }

            // Check if user agent changed
            if ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
                $this->logoutUser();
                return false;
            }

            // Check session timeout
            if ($this->isSessionExpired()) {
                $this->logoutUser();
                return false;
            }

            $this->updateLastActivity();
            return true;
        }

        if ($this->isAdminLoggedIn()) {
            // Similar checks for admin sessions
            if ($_SESSION['admin_ip_address'] !== $_SERVER['REMOTE_ADDR']) {
                $this->logoutAdmin();
                return false;
            }

            if ($_SESSION['admin_user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {
                $this->logoutAdmin();
                return false;
            }

            if ($this->isSessionExpired()) {
                $this->logoutAdmin();
                return false;
            }

            $this->updateLastActivity();
            return true;
        }

        return false;
    }

    // Get session info for debugging
    public function getSessionInfo() {
        return [
            'user_logged_in' => $this->isUserLoggedIn(),
            'admin_logged_in' => $this->isAdminLoggedIn(),
            'user_id' => $this->getCurrentUserId(),
            'admin_id' => $this->getCurrentAdminId(),
            'user_role' => $this->getCurrentUserRole(),
            'admin_role' => $this->getCurrentAdminRole(),
            'session_id' => session_id(),
            'last_activity' => $_SESSION['last_activity'] ?? null,
            'admin_last_activity' => $_SESSION['admin_last_activity'] ?? null
        ];
    }
}

// Initialize session manager
$sessionManager = SessionManager::getInstance();
$sessionManager->startSecureSession();
?>
