<?php
declare(strict_types=1);

use App\Core\Container;
use App\Repositories\SettingRepository;

function app(): Container {
    static $container = null;
    if ($container === null) {
        $container = new Container();
    }
    return $container;
}

function env(string $key, ?string $default = null): ?string {
    return $_ENV[$key] ?? $default;
}

function e($value): string {
    return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
}

function app_base_url(): string {
    $base = rtrim((string)(env('APP_URL', '')), '/');
    if ($base !== '') {
        return preg_replace('~/public$~', '', $base) ?: $base;
    }
    $script = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? '/public'));
    $script = rtrim($script === '/' ? '' : $script, '/');
    return preg_replace('~/public$~', '', $script) ?: $script;
}

function base_url(string $path = ''): string {
    $base = rtrim((string)(env('APP_URL', '')), '/');
    if ($base === '') {
        $script = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? '/public'));
        $base = rtrim($script === '/' ? '' : $script, '/');
    }
    return $base . '/' . ltrim($path, '/');
}

function file_url(string $path = ''): string {
    if (preg_match('~^(https?:)?//~', $path) || str_starts_with($path, 'data:')) {
        return $path;
    }
    return rtrim(app_base_url(), '/') . '/' . ltrim($path, '/');
}

function redirect(string $url): void {
    header('Location: ' . $url);
    exit;
}

function csrf_token(): string {
    if (empty($_SESSION['_csrf'])) $_SESSION['_csrf'] = bin2hex(random_bytes(24));
    return $_SESSION['_csrf'];
}

function verify_csrf(): void {
    if (($_POST['_csrf'] ?? '') !== ($_SESSION['_csrf'] ?? '')) {
        http_response_code(419);
        exit('Invalid CSRF token');
    }
}

function flash(string $key, ?string $value = null): ?string {
    if ($value !== null) {
        $_SESSION['_flash'][$key] = $value;
        return null;
    }
    $result = $_SESSION['_flash'][$key] ?? null;
    unset($_SESSION['_flash'][$key]);
    return $result;
}

function current_user(): ?array {
    return app()->get(App\Core\SessionAuth::class)->user();
}

function require_role(array $roles): void {
    $auth = app()->get(App\Core\SessionAuth::class);
    $auth->requireLogin();
    $user = $auth->user();
    $role = (string)($user['role_code'] ?? '');
    if (!in_array($role, $roles, true)) {
        http_response_code(403);
        exit('Forbidden');
    }
}

function setting(string $key, string $default = ''): string {
    return (new SettingRepository())->get($key, $default);
}

function normalize_phone(?string $phone): string {
    return preg_replace('/\D+/', '', (string)$phone) ?: '';
}


function can_access_page(string $page): bool {
    $auth = app()->get(App\Core\SessionAuth::class);
    if (!$auth->check()) return false;
    return $auth->canAccess($page);
}
