<?php
function app_config(): array {
    static $config = null;
    if ($config === null) {
        $config = require dirname(__DIR__, 2) . '/config/config.php';
        date_default_timezone_set($config['timezone'] ?? 'America/Sao_Paulo');
    }
    return $config;
}
function json_response($data, int $status = 200): void {
    http_response_code($status);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}
function money_float($value): float {
    if ($value === null || $value === '') return 0.0;
    $value = str_replace(['R$', ' ', "\xc2\xa0"], '', (string)$value);
    $value = str_replace(',', '.', $value);
    return is_numeric($value) ? (float)$value : 0.0;
}
function normalize_key(string $key): string {
    $key = trim($key);
    if (function_exists('iconv')) {
        $converted = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $key);
        if (is_string($converted) && $converted !== '') $key = $converted;
    } elseif (class_exists('Transliterator')) {
        $converted = \Transliterator::create('Any-Latin; Latin-ASCII; Lower()')?->transliterate($key);
        if (is_string($converted) && $converted !== '') $key = $converted;
    } else {
        $map = ['á'=>'a','à'=>'a','ã'=>'a','â'=>'a','ä'=>'a','Á'=>'A','À'=>'A','Ã'=>'A','Â'=>'A','Ä'=>'A','é'=>'e','è'=>'e','ê'=>'e','ë'=>'e','É'=>'E','È'=>'E','Ê'=>'E','Ë'=>'E','í'=>'i','ì'=>'i','î'=>'i','ï'=>'i','Í'=>'I','Ì'=>'I','Î'=>'I','Ï'=>'I','ó'=>'o','ò'=>'o','õ'=>'o','ô'=>'o','ö'=>'o','Ó'=>'O','Ò'=>'O','Õ'=>'O','Ô'=>'O','Ö'=>'O','ú'=>'u','ù'=>'u','û'=>'u','ü'=>'u','Ú'=>'U','Ù'=>'U','Û'=>'U','Ü'=>'U','ç'=>'c','Ç'=>'C','ñ'=>'n','Ñ'=>'N'];
        $key = strtr($key, $map);
    }
    $key = strtolower($key);
    $key = preg_replace('/[^a-z0-9]+/', '_', $key);
    return trim((string)$key, '_') ?: 'campo';
}
function clean_text(?string $value): string {
    $value = trim((string)$value);
    return preg_replace('/\s+/', ' ', $value) ?? '';
}
function require_auth(): void {
    if (empty($_SESSION['user'])) json_response(['ok'=>false,'message'=>'Não autenticado.'], 401);
}
function csrf_token(): string {
    if (empty($_SESSION['csrf'])) $_SESSION['csrf'] = bin2hex(random_bytes(32));
    return $_SESSION['csrf'];
}
function require_csrf(): void {
    $token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? ($_POST['_csrf'] ?? '');
    if (!$token || !hash_equals($_SESSION['csrf'] ?? '', $token)) json_response(['ok'=>false,'message'=>'Token CSRF inválido.'], 419);
}
function storage_path(string $path=''): string {
    return dirname(__DIR__, 2) . '/storage' . ($path ? '/' . ltrim($path, '/') : '');
}
function h($value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
function br_money($value): string { return 'R$ ' . number_format((float)$value, 2, ',', '.'); }
