<?php
// app/cnx/professeur/SessionManager.php

namespace app\cnx\professeur;

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

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

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

    private function initSession()
    {
        session_name($this->sessionName);

        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        if (!isset($_SESSION['created_at'])) {
            $_SESSION['created_at'] = time();
            session_regenerate_id(true);
        } else if (time() - $_SESSION['created_at'] > 1800) {
            session_regenerate_id(true);
            $_SESSION['created_at'] = time();
        }

        $this->checkSessionTimeout();
    }

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

    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'] ?? 'professeur';
        $_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'];

        session_regenerate_id(true);
        return true;
    }

    public function isLoggedIn()
    {
        if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
            return false;
        }

        if (!$this->checkSessionTimeout()) {
            return false;
        }

        if (isset($_SESSION['ip_address']) && $_SESSION['ip_address'] !== $_SERVER['REMOTE_ADDR']) {
            $this->destroySession();
            return false;
        }

        return true;
    }

    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
        ];
    }

    public function getUserId()
    {
        return $_SESSION['user_id'] ?? null;
    }

    public function getUserRole()
    {
        return $_SESSION['user_role'] ?? null;
    }

    public function hasRole($role)
    {
        return isset($_SESSION['user_role']) && $_SESSION['user_role'] === $role;
    }

    public function hasAnyRole($roles)
    {
        if (!is_array($roles)) {
            $roles = [$roles];
        }
        return isset($_SESSION['user_role']) && in_array($_SESSION['user_role'], $roles);
    }

    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;
    }

    public function logout()
    {
        $this->destroySession();
        return true;
    }

    private function destroySession()
    {
        $_SESSION = array();

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

        session_destroy();
    }

    public function setFlashMessage($type, $message)
    {
        $_SESSION['flash_message'] = [
            'type' => $type,
            'message' => $message,
            'timestamp' => time()
        ];
    }

    public function getFlashMessage()
    {
        if (isset($_SESSION['flash_message'])) {
            $message = $_SESSION['flash_message'];
            unset($_SESSION['flash_message']);
            return $message;
        }
        return null;
    }

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

    public function verifyCsrfToken($token)
    {
        if (empty($token) || empty($_SESSION['csrf_token'])) {
            return false;
        }
        return hash_equals($_SESSION['csrf_token'], $token);
    }
}
?>