<?php

declare(strict_types=1);

namespace Flowaxy\Bootstrap;

use Flowaxy\Core\System\PathResolver;
use Flowaxy\Support\Facades\Log;
use Flowaxy\Support\Facades\Settings;
use Flowaxy\Support\Helpers\UrlHelper;
use Throwable;

use function file_exists;
use function is_readable;
use function is_string;
use const DS;

// Определение протокола (HTTP/HTTPS)
final class ProtocolDetector
{
    // Определение протокола (HTTP/HTTPS)
    public static function detect(): string
    {
        // Проверяем глобальную переменную
        if (isset($GLOBALS['_SITE_PROTOCOL']) && is_string($GLOBALS['_SITE_PROTOCOL']) && $GLOBALS['_SITE_PROTOCOL'] !== '') {
            return $GLOBALS['_SITE_PROTOCOL'];
        }

        // Перевіряємо налаштування з БД тільки якщо БД явно увімкнена в storage/config/system/database.ini
        $databaseIniFile = PathResolver::storageConfig() . DS . 'system' . DS . 'database.ini';
        $dbEnabled = defined('DB_HOST') && defined('DB_NAME') && is_string(DB_NAME) && DB_NAME !== '';

        if ($dbEnabled && file_exists($databaseIniFile) && is_readable($databaseIniFile)) {
            try {
                $protocolSetting = Settings::get('site_protocol', 'auto');

                // Если настройка установлена явно, используем её
                if (is_string($protocolSetting)) {
                    if ($protocolSetting === 'https') {
                        $GLOBALS['_SITE_PROTOCOL'] = 'https://';
                        return 'https://';
                    } elseif ($protocolSetting === 'http') {
                        $GLOBALS['_SITE_PROTOCOL'] = 'http://';
                        return 'http://';
                    }
                }
            } catch (Throwable $e) {
                // Если не удалось загрузить настройки, продолжаем автоматическое определение
                try {
                    Log::Error('detectProtocol: Не удалось загрузить настройки', ['exception' => $e]);
                } catch (Throwable $logError) {
                    // Игнорируем ошибки логирования
                }
            }
        }

        // Автоматическое определение протокола
        if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && is_string($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
            $protocol = 'https://';
            $GLOBALS['_SITE_PROTOCOL'] = $protocol;
            return $protocol;
        }

        if (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && is_string($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on') {
            $protocol = 'https://';
            $GLOBALS['_SITE_PROTOCOL'] = $protocol;
            return $protocol;
        }

        $isHttps = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https' || isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443;

        $protocol = $isHttps ? 'https://' : 'http://';
        $GLOBALS['_SITE_PROTOCOL'] = $protocol;

        return $protocol;
    }

    // Определение, является ли соединение безопасным
    public static function isSecure(bool $isInstalled): bool
    {
        $isSecure = false;
        $protocolFromSettings = null;

        if ($isInstalled) {
            try {
                $protocolSetting = Settings::get('site_protocol', 'auto');

                if (is_string($protocolSetting)) {
                    if ($protocolSetting === 'https') {
                        $protocolFromSettings = 'https://';
                        $isSecure = true;
                        $GLOBALS['_SITE_PROTOCOL'] = 'https://';
                    } elseif ($protocolSetting === 'http') {
                        $protocolFromSettings = 'http://';
                        $isSecure = false;
                        $GLOBALS['_SITE_PROTOCOL'] = 'http://';
                    }
                }
            } catch (Throwable $e) {
                // Игнорируем ошибки при загрузке настроек
            }
        }

        // Автоматическое определение протокола, если не установлено в настройках
        if ($protocolFromSettings === null) {
            $realHttps = !empty($_SERVER['HTTPS']) && is_string($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || isset($_SERVER['REQUEST_SCHEME']) && is_string($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https' || isset($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443 || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && is_string($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https';

            if ($realHttps) {
                $isSecure = true;
            } else {
                try {
                    $isSecure = UrlHelper::isHttps();
                } catch (Throwable $e) {
                    // Если не удалось определить через UrlHelper, используем значение по умолчанию
                }
            }
        }

        return $isSecure;
    }
}
