<?php
declare(strict_types=1);

namespace App\Core;

final class CSRF
{
    /**
     * Generate a new CSRF token and store in session.
     * Only generates if one doesn't already exist.
     */
    public static function generate(): string
    {
        $session = App::getInstance()->session();
        $existing = $session->get('_csrf_token');
        
        if ($existing && is_string($existing) && strlen($existing) > 10) {
            return $existing;
        }

        $token = bin2hex(random_bytes(32));
        $session->set('_csrf_token', $token);
        return $token;
    }

    /**
     * Get current token, or generate one.
     */
    public static function token(): string
    {
        return self::generate();
    }

    /**
     * Validate a submitted token.
     */
    public static function validate(string $token): bool
    {
        if ($token === '') {
            return false;
        }

        $session = App::getInstance()->session();
        $stored = $session->get('_csrf_token');

        if (!$stored || !is_string($stored)) {
            return false;
        }

        return hash_equals($stored, $token);
    }

    /**
     * Return hidden input field.
     */
    public static function field(): string
    {
        return '<input type="hidden" name="_csrf_token" value="' . htmlspecialchars(self::token(), ENT_QUOTES, 'UTF-8') . '">';
    }
}