<?php

declare(strict_types=1);

namespace Flowaxy\Bootstrap;

use function php_sapi_name;
use function file_exists;
use function is_readable;
use function function_exists;
use function defined;
use const DIRECTORY_SEPARATOR;

// Головний клас застосунку для ініціалізації системи
final class Application
{
    // Запуск застосунку та ініціалізація всіх компонентів системи
    public function run(): void
    {
        $isCli = php_sapi_name() === 'cli';
        $ds = defined('DS') ? DS : DIRECTORY_SEPARATOR;

        // Завантажуємо всі Bootstrap класи вручну, оскільки автозавантажувач ще не ініціалізований
        // Установщик удален - InstallerChecker и DatabaseChecker больше не нужны
        $bootstrapClasses = [
            'PathResolverInitializer',
            'HelperFunctionsLoader',
            'ErrorHandlerLoader',
            'ProtocolDetector',
            'ConfigLoader',
            'ConstantsDefiner',
            'ConfigurationInitializer',
            'AutoloaderInitializer',
            'CacheInitializer',
            'EnvironmentInitializer',
            'ContainerInitializer',
            'ServiceProviderLoader',
            'SessionInitializer',
            'MigrationRunner',
            'ApplicationInitializer',
            'RouterLoader',
        ];

        foreach ($bootstrapClasses as $className) {
            $file = __DIR__ . $ds . $className . '.php';
            if (file_exists($file) && is_readable($file)) {
                require_once $file;
            }
        }

        // Ініціалізація шляхів
        PathResolverInitializer::initialize();

        // Завантаження функцій-хелперів
        HelperFunctionsLoader::load();

        // Завантаження обробника помилок
        ErrorHandlerLoader::load();

        // Установщик удален - система работает без проверки установки
        // Root пользователь позволяет войти в админку даже без БД

        // Визначення протоколу та конфігурації
        $protocol = ProtocolDetector::detect();
        $host = $_SERVER['HTTP_HOST'] ?? 'localhost';
        ConfigurationInitializer::initialize($protocol, $host);

        // Ініціалізація автозавантажувача та кешу
        $buildClassMap = function_exists('buildClassMap')
            ? static fn(): array => buildClassMap()
            : static fn(): array => [];
        AutoloaderInitializer::initialize($buildClassMap);
        CacheInitializer::initialize();

        // Ініціалізація оточення
        // Проверяем наличие БД для миграций, но не блокируем работу без БД
        $hasDatabase = defined('DB_HOST') && defined('DB_NAME') && !empty(DB_HOST) && !empty(DB_NAME);
        EnvironmentInitializer::initialize($hasDatabase);

        // Ініціалізація контейнера та сервіс-провайдерів
        $container = ContainerInitializer::initialize();
        ServiceProviderLoader::load($container);

        // Ініціалізація сесії та міграцій
        $isSecure = ProtocolDetector::isSecure($hasDatabase);
        SessionInitializer::initialize($isSecure);
        // Миграции запускаются только если БД настроена
        if ($hasDatabase) {
            MigrationRunner::run(true);
        }

        // Ініціалізація та запуск ядра
        $kernel = ApplicationInitializer::initialize($container, $isCli);

        if ($isCli) {
            $kernel->serve();
            return;
        }

        // Завантаження роутера для HTTP
        RouterLoader::load();
    }
}
