<?php

declare(strict_types=1);

/**
 * Global helper functions.
 *
 * These are intentionally tiny, dependency-free wrappers that make controllers
 * and views terser without pulling in the DI container everywhere. They are
 * autoloaded via composer's "files" entry (see composer.json).
 */

use BotGuard\Core\Config;

if (! function_exists('env')) {
    /**
     * Read an environment variable with an optional default.
     *
     * Values "true", "false", "null" and "empty" are coerced to their native
     * PHP equivalents so `.env` booleans behave intuitively.
     */
    function env(string $key, mixed $default = null): mixed
    {
        $value = $_ENV[$key] ?? $_SERVER[$key] ?? getenv($key);

        if ($value === false || $value === null) {
            return $default;
        }

        return match (strtolower((string) $value)) {
            'true', '(true)'   => true,
            'false', '(false)' => false,
            'null', '(null)'   => null,
            'empty', '(empty)' => '',
            default            => $value,
        };
    }
}

if (! function_exists('config')) {
    /**
     * Read a dotted configuration key, e.g. config('app.name').
     */
    function config(string $key, mixed $default = null): mixed
    {
        return Config::get($key, $default);
    }
}

if (! function_exists('e')) {
    /**
     * Escape a value for safe HTML output (XSS prevention).
     */
    function e(mixed $value): string
    {
        return htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }
}

if (! function_exists('base_path')) {
    /**
     * Absolute path to the project root, optionally joined with a sub-path.
     */
    function base_path(string $path = ''): string
    {
        $root = dirname(__DIR__, 2);

        return $path === '' ? $root : $root . DIRECTORY_SEPARATOR . ltrim($path, '/\\');
    }
}

if (! function_exists('storage_path')) {
    function storage_path(string $path = ''): string
    {
        return base_path('storage' . ($path !== '' ? '/' . ltrim($path, '/\\') : ''));
    }
}

if (! function_exists('now')) {
    /**
     * Current UTC timestamp in MySQL DATETIME format.
     */
    function now(): string
    {
        return (new DateTimeImmutable('now', new DateTimeZone('UTC')))->format('Y-m-d H:i:s');
    }
}

if (! function_exists('str_random')) {
    /**
     * Cryptographically-secure random hex string.
     */
    function str_random(int $bytes = 32): string
    {
        return bin2hex(random_bytes($bytes));
    }
}

if (! function_exists('array_get')) {
    /**
     * Safely read a possibly-missing array key with a default.
     */
    function array_get(array $array, string|int $key, mixed $default = null): mixed
    {
        return $array[$key] ?? $default;
    }
}

if (! function_exists('clamp')) {
    /**
     * Constrain a number to the inclusive [min, max] range.
     */
    function clamp(float $value, float $min, float $max): float
    {
        return max($min, min($max, $value));
    }
}
