<?php

/**
 * Трейт для упрощенной работы с CSRF
 * Общие методы для работы с CSRF токенами
 *
 * @package Flowaxy\Support\Traits
 * @version 1.0.0 Alpha prerelease
 */

declare(strict_types=1);

namespace Flowaxy\Support\Traits;

use Flowaxy\Support\Helpers\SecurityHelper;
use Flowaxy\Support\Helpers\SessionHelper;
use Flowaxy\Infrastructure\Security\RequestFilter;
use Flowaxy\Support\Facades\Log;
use Flowaxy\Infrastructure\Security\Session as SecuritySession;

trait CsrfTrait
{
    /**
     * Проверка CSRF токена
     *
     * @param string|null $token Токен для проверки (если null, берется из запроса)
     * @return bool
     */
    protected function verifyCsrf(?string $token = null): bool
    {
        if ($token === null) {
            $token = RequestFilter::post('csrf_token', '', 'string');
            if (empty($token)) {
                $token = RequestFilter::get('csrf_token', '', 'string');
            }
        }

        if (empty($token)) {
            Log::Warning('CsrfTrait: CSRF token is missing', [
                'session_id' => session_id(),
                'session_started' => SecuritySession::isStarted(),
            ]);
            return false;
        }

        // Используем SecurityHelper для проверки
        return SecurityHelper::verifyCsrfToken($token);
    }

    /**
     * Проверка CSRF токена (публичный метод для совместимости)
     *
     * @return bool
     */
    public function verifyCsrfPublic(): bool
    {
        return $this->verifyCsrf();
    }

    /**
     * Генерация CSRF токена
     *
     * @return string
     */
    protected function generateCsrf(): string
    {
        return SecurityHelper::csrfToken();
    }

    /**
     * Получение CSRF токена из сессии
     *
     * @return string|null
     */
    protected function getCsrfToken(): ?string
    {
        $session = SessionHelper::getManager();
        if ($session) {
            // Сбрасываем префикс для получения CSRF токена
            $currentPrefix = $session->getPrefix();
            if ($currentPrefix !== '') {
                $session->setPrefix('');
            }

            $token = $session->get('csrf_token');

            // Восстанавливаем префикс
            if ($currentPrefix !== '') {
                $session->setPrefix($currentPrefix);
            }

            return $token;
        }

        return null;
    }
}
