<?php

namespace xmvc;

/**
 * SESSION
 */
class Session
{
    /** 是否开启了 Session */
    protected static bool $isStart = false;

    /** Session 数据 */
    protected static array $data = [];

    /** Session ID */
    protected static string $id = '';

    /**
     * 是否开启了 Session
     */
    public static function isStart(): bool
    {
        return self::$isStart;
    }

    /**
     * 开启 Session
     * @param int $lifetime 有效时间, 默认一天
     */
    public static function start(int $lifetime = 86400)
    {
        if (!self::$isStart) {
            if (session_status() == PHP_SESSION_NONE) {
                ini_set('session.gc_maxlifetime', $lifetime);
                session_set_cookie_params(
                    [
                        'lifetime' => $lifetime,
                        'samesite' => 'None',
                        'secure' => true,
                    ]
                );
                session_start();
            }
            self::load();
        }
        self::$isStart = true;
    }

    /**
     * 取或设置 SESSION ID
     */
    public static function id(string $key = '')
    {
        self::start();
        if ($key == '') {
            return session_id();
        } else {
            session_id($key);
        }
    }

    /**
     * 加载 $_SESSION 中的数据
     */
    public static function load()
    {
        if (!empty($_SESSION)) {
            foreach ($_SESSION as $key => $value) {
                self::$data[$key] = $value;
                unset($_SESSION[$key]); // 禁止访问 $_SESSION 数组
            }
            $_SESSION = null;
        }
    }

    /**
     * 键是否被定义
     */
    public static function has(string $key): bool
    {
        self::start();
        return self::$data && isset(self::$data[$key]);
    }

    /**
     * 取值
     */
    public static function get(string $key, mixed $default = null): mixed
    {
        return self::has($key) ? self::$data[$key] : $default;
    }

    /**
     * 取所有值
     */
    public static function getAll(): array
    {
        self::start();
        return self::$data;
    }

    /**
     * 写值
     */
    public static function set(string $key, mixed $value)
    {
        self::start();
        self::$data[$key] = $value;
    }

    /**
     * 删值
     */
    public static function remove(string $key)
    {
        if (self::has($key)) {
            unset(self::$data[$key]);
        }
    }

    /**
     * 清空所有
     */
    public static function clear()
    {
        self::start();
        self::$data = [];
    }

    /**
     * 保存数据到 $_SESSION 中, 一般不需要手动调用
     * - 在 MVC::onShutdown() 代码中调用
     */
    public static function save()
    {
        if (self::isStart()) {
            $_SESSION = self::$data;
        }
    }
}
