<?php
declare(strict_types=1);

if (!function_exists('env')) {
    function env(string $key, mixed $default = null): mixed {
        $v = $_ENV[$key] ?? $_SERVER[$key] ?? getenv($key);
        if ($v === false || $v === null || $v === '') return $default;
        return $v;
    }
}

if (!function_exists('e')) {
    function e(?string $value): string {
        return htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }
}

if (!function_exists('url')) {
    function url(string $path = ''): string {
        $path = '/' . ltrim($path, '/');
        return PROOT . $path;
    }
}

if (!function_exists('redirect')) {
    // Return type omitted (rather than `: never`) so we stay PHP 8.0-compatible.
    function redirect(string $path, int $code = 302) {
        header('Location: ' . url($path), true, $code);
        exit;
    }
}

if (!function_exists('json_response')) {
    function json_response(mixed $data, int $code = 200) {
        http_response_code($code);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        exit;
    }
}

if (!function_exists('input_json')) {
    function input_json(): array {
        $raw = file_get_contents('php://input') ?: '';
        $decoded = json_decode($raw, true);
        return is_array($decoded) ? $decoded : [];
    }
}

if (!function_exists('dd')) {
    function dd(mixed ...$vars) {
        if (PHP_SAPI !== 'cli') header('Content-Type: text/plain; charset=utf-8');
        foreach ($vars as $v) { var_export($v); echo PHP_EOL; }
        exit;
    }
}
