<?php
declare(strict_types=1);

/**
 * /public_html/test_erp/api/_csrf_guard.php
 * CSRF Guard v1.1 — Test environment
 *
 * Compatibility mode:
 * - Valid CSRF token is always accepted.
 * - A supplied but invalid token is always rejected.
 * - A missing token is temporarily allowed only for verifiably same-origin requests.
 *   This prevents older ERP pages from breaking while the JS helper is added gradually.
 */

if (isset($_SERVER['SCRIPT_FILENAME'])
    && realpath((string)$_SERVER['SCRIPT_FILENAME']) === realpath(__FILE__)) {
    http_response_code(403);
    exit('Forbidden');
}

function erp_csrf_get_submitted(): string
{
    $header = trim((string)($_SERVER['HTTP_X_CSRF_TOKEN'] ?? ''));
    if ($header !== '') {
        return $header;
    }

    if (isset($_POST['_csrf']) && $_POST['_csrf'] !== '') {
        return trim((string)$_POST['_csrf']);
    }

    static $jsonCache;
    static $loaded = false;

    if (!$loaded) {
        $loaded = true;
        $raw = file_get_contents('php://input');
        $decoded = json_decode((string)$raw, true);
        $jsonCache = is_array($decoded) ? $decoded : [];
    }

    return trim((string)($jsonCache['_csrf'] ?? ''));
}

function erp_csrf_request_host(): string
{
    $host = strtolower(trim((string)($_SERVER['HTTP_HOST'] ?? '')));
    return preg_replace('/:\d+$/', '', $host) ?: '';
}

function erp_csrf_is_same_origin(): bool
{
    $requestHost = erp_csrf_request_host();
    if ($requestHost === '') {
        return false;
    }

    foreach (['HTTP_ORIGIN', 'HTTP_REFERER'] as $key) {
        $value = trim((string)($_SERVER[$key] ?? ''));
        if ($value === '') {
            continue;
        }

        $sourceHost = strtolower((string)(parse_url($value, PHP_URL_HOST) ?? ''));
        if ($sourceHost !== '' && hash_equals($requestHost, $sourceHost)) {
            return true;
        }
    }

    // Browser-controlled Fetch Metadata header; scripts cannot freely forge it.
    return strtolower((string)($_SERVER['HTTP_SEC_FETCH_SITE'] ?? '')) === 'same-origin';
}

function erp_csrf_fail(): void
{
    http_response_code(419);
    header('Content-Type: application/json; charset=UTF-8');
    echo json_encode([
        'status'  => 419,
        'success' => false,
        'message' => 'সেশন টোকেন মেলেনি, পেজ রিলোড করুন',
        'data'    => null,
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

function erp_csrf_required(bool $allowSameOriginFallback = true): void
{
    $method = strtoupper((string)($_SERVER['REQUEST_METHOD'] ?? 'GET'));
    if (in_array($method, ['GET', 'HEAD', 'OPTIONS'], true)) {
        return;
    }

    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }

    $submitted = erp_csrf_get_submitted();
    $expected  = (string)($_SESSION['csrf_token'] ?? '');

    if ($submitted !== '') {
        if ($expected !== '' && hash_equals($expected, $submitted)) {
            return;
        }

        erp_csrf_fail();
    }

    if ($allowSameOriginFallback && erp_csrf_is_same_origin()) {
        return;
    }

    erp_csrf_fail();
}
