<?php

namespace App\Core;

/**
 * ITSWEBER CMS – CSRF Protection
 */
class Csrf
{
    private Session $session;

    public function __construct(Session $session)
    {
        $this->session = $session;
    }

    /**
     * Generate or retrieve the CSRF token.
     */
    public function token(): string
    {
        if (!$this->session->has('_csrf_token')) {
            $this->session->set('_csrf_token', bin2hex(random_bytes(32)));
        }
        return $this->session->get('_csrf_token');
    }

    /**
     * Generate an HTML hidden input field.
     */
    public function field(): string
    {
        return '<input type="hidden" name="_csrf_token" value="' . $this->token() . '">';
    }

    /**
     * Validate a submitted CSRF token.
     */
    public function validate(string $token): bool
    {
        $sessionToken = $this->session->get('_csrf_token', '');
        return hash_equals($sessionToken, $token);
    }

    /**
     * Validate from POST data. Aborts if invalid.
     * Returns JSON error for XHR/AJAX requests, plain text otherwise.
     */
    public function check(): bool
    {
        $token = $_POST['_csrf_token'] ?? '';
        if (!$this->validate($token)) {
            http_response_code(403);
            $isAjax = (
                (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')
                || (isset($_SERVER['HTTP_ACCEPT']) && str_contains($_SERVER['HTTP_ACCEPT'], 'application/json'))
            );
            if ($isAjax) {
                header('Content-Type: application/json; charset=utf-8');
                echo json_encode(['success' => false, 'error' => 'Invalid CSRF token.']);
            } else {
                echo 'Invalid CSRF token.';
            }
            exit;
        }
        return true;
    }
}
