<?php

declare(strict_types=1);

use Core\Csrf;
use Core\Session;

function loadEnv(string $path): void
{
    if (!file_exists($path)) {
        return;
    }

    $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if ($lines === false) {
        return;
    }

    foreach ($lines as $index => $line) {
        if ($index === 0) {
            $line = preg_replace('/^\xEF\xBB\xBF/', '', $line) ?? $line;
        }

        $line = trim($line);

        if ($line === '' || str_starts_with($line, '#')) {
            continue;
        }

        if (str_starts_with($line, 'export ')) {
            $line = trim(substr($line, 7));
        }

        if (!str_contains($line, '=')) {
            continue;
        }

        [$name, $value] = array_pad(explode('=', $line, 2), 2, '');
        $name = trim($name);
        $value = trim($value);

        if ($name === '') {
            continue;
        }

        if ($value !== '' && ((str_starts_with($value, '"') && str_ends_with($value, '"')) || (str_starts_with($value, "'") && str_ends_with($value, "'")))) {
            $value = substr($value, 1, -1);
        }

        $_ENV[$name] = $value;
        $_SERVER[$name] = $value;
        putenv($name . '=' . $value);
    }
}

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

    if (array_key_exists($key, $_SERVER)) {
        return $_SERVER[$key];
    }

    $value = getenv($key);
    return $value !== false ? $value : $default;
}


function requestIsHttps(): bool
{
    if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
        return true;
    }

    if (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443) {
        return true;
    }

    $forwardedProto = strtolower(trim((string) ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '')));
    if ($forwardedProto !== '' && in_array($forwardedProto, ['https', 'wss'], true)) {
        return true;
    }

    $forwardedSsl = strtolower(trim((string) ($_SERVER['HTTP_X_FORWARDED_SSL'] ?? '')));
    if ($forwardedSsl === 'on') {
        return true;
    }

    return false;
}

function baseUrl(string $path = ''): string
{
    $configured = trim((string) env('APP_URL', ''));

    if ($configured !== '') {
        $root = rtrim($configured, '/');
    } else {
        $scheme = requestIsHttps() ? 'https' : 'http';
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        $scriptDir = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'] ?? ''));
        $scriptDir = rtrim($scriptDir, '/');

        $root = $scheme . '://' . $host;
        if ($scriptDir !== '' && $scriptDir !== '/') {
            $root .= $scriptDir;
        }
    }

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

function asset(string $path): string
{
    return baseUrl('assets/' . ltrim($path, '/'));
}

function redirect(string $path): never
{
    $path = str_replace(["
", "
"], '', trim($path));
    $statusCode = strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET')) === 'POST' ? 303 : 302;

    while (ob_get_level() > 0) {
        @ob_end_clean();
    }

    header('Location: ' . $path, true, $statusCode);
    exit;
}

function data_get(array $array, string $key, mixed $default = null): mixed
{
    if ($key === '') {
        return $array;
    }

    $segments = explode('.', $key);
    $value = $array;

    foreach ($segments as $segment) {
        if (is_array($value) && array_key_exists($segment, $value)) {
            $value = $value[$segment];
            continue;
        }
        return $default;
    }

    return $value;
}

function old(string $key, mixed $default = ''): mixed
{
    $old = Session::getOldInput();
    return data_get($old, $key, $default);
}

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

function formatDate(?string $date): string
{
    if (!$date) {
        return '-';
    }
    try {
        return (new DateTimeImmutable($date))->format('d/m/Y');
    } catch (Throwable) {
        return (string) $date;
    }
}

function formatMoney(mixed $value): string
{
    if ($value === null || $value === '') {
        return '-';
    }
    return 'R$ ' . number_format((float) $value, 2, ',', '.');
}


function formatBytes(mixed $value): string
{
    $bytes = (int) $value;

    if ($bytes <= 0) {
        return '0 B';
    }

    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $size = (float) $bytes;
    $unitIndex = 0;

    while ($size >= 1024 && $unitIndex < count($units) - 1) {
        $size /= 1024;
        $unitIndex++;
    }

    $decimals = $size >= 100 || $unitIndex === 0 ? 0 : ($size >= 10 ? 1 : 2);

    return number_format($size, $decimals, ',', '.') . ' ' . $units[$unitIndex];
}

function yesNo(?int $value): string
{
    return (int) $value === 1 ? 'Sim' : 'Não';
}

function selected(mixed $value, mixed $expected): string
{
    return (string) $value === (string) $expected ? 'selected' : '';
}

function checked(mixed $value, mixed $expected = 1): string
{
    return (string) $value === (string) $expected ? 'checked' : '';
}

function csrf_field(): string
{
    return '<input type="hidden" name="_token" value="' . e(Csrf::token()) . '">';
}
