<?php

declare(strict_types=1);
class Session
{
    private $_handler;

    public function __construct()
    {
        $this->_handler = Box_SessionFile::getInstance();
    }

    public function getId()
    {
        return $this->_handler->getId();
    }

    public function delete($key)
    {
        return $this->_handler->delete($key);
    }

    public function get($key)
    {
        return $this->_handler->get($key);
    }

    public function set($key, $value): void
    {
        $this->_handler->set($key, $value);
    }

    public function destroy(): void
    {
        $this->_handler->destroy();
    }
}

class Box_SessionFile
{
    final public const bool SESSION_STARTED = true;
    final public const bool SESSION_NOT_STARTED = false;

    protected $sessionState = self::SESSION_NOT_STARTED;

    protected static $instance;

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
            if (!self::$instance->sessionExists() && !headers_sent()) {
                session_name('fb_sid');
                self::$instance->sessionState = session_start();
            }
        }

        return self::$instance;
    }

    public function getId(): string|false
    {
        return session_id();
    }

    public function destroy(): void
    {
        if (self::$instance->sessionExists()) {
            session_destroy();
        }
    }

    public function delete($key): bool
    {
        if (isset($_SESSION[$key])) {
            unset($_SESSION[$key]);
        }

        return true;
    }

    private function sessionExists(): bool
    {
        if (!isset($_SESSION)) {
            return false;
        }

        if (ini_get('session.use_cookies') == '1' && isset($_COOKIE[session_name()])) {
            return true;
        } elseif ($this->sessionState) {
            return true;
        }

        return false;
    }

    public function get($key)
    {
        return $this->__get($key);
    }

    public function set($key, $value)
    {
        return $this->__set($key, $value);
    }

    public function __get($key)
    {
        return $_SESSION[$key] ?? null;
    }

    public function __set($key, $value)
    {
        $_SESSION[$key] = $value;
    }

    public function __isset($name)
    {
        return isset($_SESSION[$name]);
    }

    public function __unset($name)
    {
        unset($_SESSION[$name]);
    }
}
