<?php
// app/core/SessionManager.php

namespace app\cnx\admin;

class SessionManager
{
    private static $instance = null;
    private $sessionTimeout = 3600; // 1 hour in seconds
    private $sessionName = 'EST_CONCOURS_SESSION';

    private function __construct()
    {
        $this->initSession();
    }

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

    /**
     * Initialize session
     */
    private function initSession()
    {
        // Set session name
        session_name($this->sessionName);

        // Start session if not already started
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        // Regenerate session ID periodically for security
        if (!isset($_SESSION['created_at'])) {
            $_SESSION['created_at'] = time();
            session_regenerate_id(true);
        } else if (time() - $_SESSION['created_at'] > 1800) {
            // Regenerate every 30 minutes
            session_regenerate_id(true);
            $_SESSION['created_at'] = time();
        }

        // Check session timeout
        $this->checkSessionTimeout();
    }

    /**
     * Check if session has expired
     */
    private function checkSessionTimeout()
    {
        if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > $this->sessionTimeout)) {
            $this->destroySession();
            return false;
        }
        $_SESSION['last_activity'] = time();
        return true;
    }

    /**
     * Login user
     */
    public function login($userData)
    {
        $_SESSION['user_id'] = $userData['id'];
        $_SESSION['user_email'] = $userData['email'];
        $_SESSION['user_nom'] = $userData['nom'] ?? '';
        $_SESSION['user_prenom'] = $userData['prenom'] ?? '';
        $_SESSION['user_role'] = $userData['role'] ?? 'admin';
        $_SESSION['user_photo'] = $userData['photo'] ?? null;
        $_SESSION['logged_in'] = true;
        $_SESSION['login_time'] = time();
        $_SESSION['last_activity'] = time();
        $_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
        $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT'];

        // Regenerate session ID on login
        session_regenerate_id(true);

        return true;
    }

    /**
     * Check if user is logged in
     */
    public function isLoggedIn()
    {
        if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
            return false;
        }

        // Check if session has expired
        if (!$this->checkSessionTimeout()) {
            return false;
        }

        // Optional: Check IP address for additional security
        if (isset($_SESSION['ip_address']) && $_SESSION['ip_address'] !== $_SERVER['REMOTE_ADDR']) {
            $this->destroySession();
            return false;
        }

        return true;
    }

    /**
     * Get current user data
     */
    public function getCurrentUser()
    {
        if (!$this->isLoggedIn()) {
            return null;
        }

        return [
            'id' => $_SESSION['user_id'] ?? null,
            'email' => $_SESSION['user_email'] ?? null,
            'nom' => $_SESSION['user_nom'] ?? null,
            'prenom' => $_SESSION['user_prenom'] ?? null,
            'role' => $_SESSION['user_role'] ?? null,
            'photo' => $_SESSION['user_photo'] ?? null,
            'login_time' => $_SESSION['login_time'] ?? null
        ];
    }

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

    /**
     * Get user role
     */
    public function getUserRole()
    {
        return $_SESSION['user_role'] ?? null;
    }

    /**
     * Check if user has specific role
     */
    public function hasRole($role)
    {
        return isset($_SESSION['user_role']) && $_SESSION['user_role'] === $role;
    }

    /**
     * Check if user has any of the specified roles
     */
    public function hasAnyRole($roles)
    {
        if (!is_array($roles)) {
            $roles = [$roles];
        }
        return isset($_SESSION['user_role']) && in_array($_SESSION['user_role'], $roles);
    }

    /**
     * Update user data in session
     */
    public function updateUserData($userData)
    {
        if (isset($userData['nom'])) $_SESSION['user_nom'] = $userData['nom'];
        if (isset($userData['prenom'])) $_SESSION['user_prenom'] = $userData['prenom'];
        if (isset($userData['email'])) $_SESSION['user_email'] = $userData['email'];
        if (isset($userData['photo'])) $_SESSION['user_photo'] = $userData['photo'];
        if (isset($userData['role'])) $_SESSION['user_role'] = $userData['role'];
        return true;
    }

    /**
     * Logout user - destroy session
     */
    public function logout()
    {
        $this->destroySession();
        return true;
    }

    /**
     * Destroy session completely
     */
    private function destroySession()
    {
        // Unset all session variables
        $_SESSION = array();

        // Delete session cookie
        if (ini_get("session.use_cookies")) {
            $params = session_get_cookie_params();
            setcookie(session_name(), '', time() - 42000,
                $params["path"], $params["domain"],
                $params["secure"], $params["httponly"]
            );
        }

        // Destroy session
        session_destroy();
    }

    /**
     * Set flash message
     */
    public function setFlashMessage($type, $message)
    {
        $_SESSION['flash_message'] = [
            'type' => $type, // success, error, warning, info
            'message' => $message,
            'timestamp' => time()
        ];
    }

    /**
     * Get and clear flash message
     */
    public function getFlashMessage()
    {
        if (isset($_SESSION['flash_message'])) {
            $message = $_SESSION['flash_message'];
            unset($_SESSION['flash_message']);
            return $message;
        }
        return null;
    }

    /**
     * Set CSRF token
     */
    public function generateCsrfToken()
    {
        if (empty($_SESSION['csrf_token'])) {
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        }
        return $_SESSION['csrf_token'];
    }

    /**
     * Verify CSRF token
     */
    public function verifyCsrfToken($token)
    {
        if (empty($token) || empty($_SESSION['csrf_token'])) {
            return false;
        }
        return hash_equals($_SESSION['csrf_token'], $token);
    }
}

?>
