<?php
class CsrfProtection
{
    private $sessionKey = 'csrf_tokens';
    private $tokenLength = 32; // 32 bytes = 64 hex chars
    private $maxTokens = 10;   // Keep a small history for multi-tab support

    public function __construct()
    {
        if (session_status() === PHP_SESSION_NONE) {
            session_start([
                'cookie_httponly' => true,
                'cookie_secure'   => isset($_SERVER['HTTPS']), // only secure if HTTPS
                'cookie_samesite' => 'Strict'
            ]);
        }

        if (!isset($_SESSION[$this->sessionKey])) {
            $_SESSION[$this->sessionKey] = [];
        }
    }

    /**
     * Generate and store a CSRF token
     */
    public function generateToken(): string
    {
        $token = bin2hex(random_bytes($this->tokenLength));

        // Store the token in session
        $_SESSION[$this->sessionKey][] = $token;

        // Limit stored tokens to prevent session bloat
        if (count($_SESSION[$this->sessionKey]) > $this->maxTokens) {
            array_shift($_SESSION[$this->sessionKey]); // remove oldest
        }

        return $token;
    }

    /**
     * Verify if token is valid
     */
    public function validateToken(string $token): bool
    {
        if (in_array($token, $_SESSION[$this->sessionKey], true)) {
            // Remove token once used (one-time)
            $_SESSION[$this->sessionKey] = array_diff($_SESSION[$this->sessionKey], [$token]);
            return true;
        }
        return false;
    }

    /**
     * Generate hidden input for forms
     */
    public function csrfInput(): string
    {
        $token = $this->generateToken();
        return '<input type="hidden" id="csrf_token" name="csrf_token" value="' . htmlspecialchars($token, ENT_QUOTES, 'UTF-8') . '">';
    }
}

?>