<?php

declare(strict_types=1);

namespace Flowaxy\Bootstrap;

use Flowaxy\Core\System\Container\CoreServiceProvider;
use Flowaxy\Core\System\Container\Providers\AuthServiceProvider;
use Flowaxy\Core\System\Container\Providers\ThemeServiceProvider;
use Flowaxy\Core\System\Container\ServiceProvider;
use Flowaxy\Core\System\PathResolver;
use Flowaxy\Core\System\ServiceConfig;
use Throwable;

use function class_exists;
use function file_exists;
use function is_readable;
use const DS;

// Загрузчик сервис-провайдеров
final class ServiceProviderLoader
{
    // Загрузка и регистрация сервис-провайдеров
    public static function load(object $container): array
    {
        $flowaxyDir = PathResolver::flowaxy();
        $engineDir = PathResolver::engine();

        // Загрузка конфигурации сервисов из storage/config/flowaxy/services.json
        $configDir = PathResolver::storageConfig();
        $servicesConfigFile = $configDir . DS . 'flowaxy' . DS . 'services.json';

        // Fallback для обратной совместимости: проверяем старый путь config/flowaxy/services.php
        if (!file_exists($servicesConfigFile)) {
            $legacyServicesFile = PathResolver::root() . DS . 'config' . DS . 'flowaxy' . DS . 'services.php';
            if (file_exists($legacyServicesFile)) {
                $servicesConfigFile = $legacyServicesFile;
            } else {
                // Последний fallback: engine/core/config/services.php
                $servicesConfigFile = "{$engineDir}/core/config/services.php";
            }
        }

        if (file_exists($servicesConfigFile) && is_readable($servicesConfigFile)) {
            try {
                $servicesConfig = ServiceConfig::load($servicesConfigFile, null);
                if ($servicesConfig !== null) {
                    ServiceConfig::register($container, $servicesConfig);
                }
            } catch (Throwable $e) {
                // Продолжаем работу даже если конфигурацию не удалось загрузить
            }
        }

        // Регистрация сервис-провайдеров
        $serviceProviders = [
            CoreServiceProvider::class,
            ThemeServiceProvider::class,
            AuthServiceProvider::class,
        ];

        $providerInstances = [];
        foreach ($serviceProviders as $providerClass) {
            if (!class_exists($providerClass)) {
                continue;
            }

            try {
                $provider = new $providerClass();
                if ($provider instanceof ServiceProvider) {
                    $provider->register($container);
                    $providerInstances[] = $provider;
                }
            } catch (Throwable $e) {
                // Логируем ошибку, но не прерываем инициализацию
                // Это критично для отладки проблем с регистрацией сервисов
                if (class_exists('Flowaxy\Support\Facades\Log')) {
                    try {
                        \Flowaxy\Support\Facades\Log::Error('ServiceProviderLoader: Failed to register provider', [
                            'provider' => $providerClass,
                            'error' => $e->getMessage(),
                            'trace' => $e->getTraceAsString()
                        ]);
                    } catch (Throwable $logError) {
                        // Игнорируем ошибки логирования
                    }
                }
                // Пропускаем провайдер, который не удалось инициализировать
                continue;
            }
        }

        // Запуск сервис-провайдеров
        foreach ($providerInstances as $provider) {
            try {
                $provider->boot($container);
            } catch (Throwable $e) {
                // Продолжаем работу даже если boot не удался
            }
        }

        return $providerInstances;
    }
}
