<?php
declare(strict_types=1);

namespace Celena\Core\Security;

/**
 * Защита от CSRF: токен в сессии + double-submit через скрытое поле / заголовок X-CSRF-Token.
 * Используется как статический фасад: Csrf::token(), Csrf::validate($token).
 */
final class Csrf
{
    private const SESSION_KEY = '_celena_csrf';

    public static function init(): void
    {
        if (PHP_SAPI === 'cli' || session_status() !== PHP_SESSION_ACTIVE) {
            return;
        }
        if (!isset($_SESSION[self::SESSION_KEY])) {
            $_SESSION[self::SESSION_KEY] = bin2hex(random_bytes(32));
        }
    }

    public static function token(): string
    {
        if (PHP_SAPI === 'cli' || session_status() !== PHP_SESSION_ACTIVE) {
            return '';
        }
        if (!isset($_SESSION[self::SESSION_KEY])) {
            self::init();
        }
        return (string) $_SESSION[self::SESSION_KEY];
    }

    public static function validate(?string $token): bool
    {
        if ($token === null || $token === '') {
            return false;
        }
        $expected = self::token();
        if ($expected === '') {
            return false;
        }
        return hash_equals($expected, $token);
    }

    public static function rotate(): void
    {
        if (PHP_SAPI === 'cli' || session_status() !== PHP_SESSION_ACTIVE) {
            return;
        }
        $_SESSION[self::SESSION_KEY] = bin2hex(random_bytes(32));
    }
}
