<?php

namespace Kylin\Modules\Providers;

use Illuminate\Support\ServiceProvider;
use Kylin\Modules\Console\Commands\ModuleMakeCommand;
use Kylin\Modules\Console\Commands\ModuleListCommand;
use Kylin\Modules\Console\Commands\ModuleMigrateCommand;
use Kylin\Modules\Console\Commands\ModuleMigrateRefreshCommand;
use Kylin\Modules\Console\Commands\ModuleMigrateRollbackCommand;
use Kylin\Modules\Console\Commands\ModuleMigrateResetCommand;
use Kylin\Modules\Console\Commands\ModuleSeedCommand;
use Kylin\Modules\Console\Commands\ModuleInstallCommand;
use Kylin\Modules\Console\Commands\ModuleUninstallCommand;
use Kylin\Modules\Console\Commands\ModuleUpdateCommand;
use Kylin\Modules\Console\Commands\ModuleShowCommand;
use Kylin\Modules\Console\Commands\ModuleCopyCommand;
use Kylin\Modules\Console\Commands\ModuleExportCommand;
use Kylin\Modules\Console\Commands\ModuleImportCommand;
use Kylin\Modules\Console\Commands\ModuleDependencyCommand;
use Kylin\Modules\Console\Commands\ModuleStatusCommand;
use Kylin\Modules\Console\Commands\ModuleSearchCommand;
use Kylin\Modules\Console\Commands\ModuleBackupCommand;
use Kylin\Modules\Console\Commands\ModuleStatsCommand;
use Kylin\Modules\Console\Commands\ModuleVersionCommand;
use Kylin\Modules\Console\Commands\ModuleInitCommand;
use Kylin\Modules\Console\Commands\ModuleHealthCommand;
use Kylin\Modules\Console\Commands\ModuleDocCommand;
use Kylin\Modules\Console\Commands\ModuleMonitorCommand;
use Kylin\Modules\Console\Commands\ModuleSecurityCommand;
use Kylin\Modules\Console\Commands\ModuleI18nCommand;
use Kylin\Modules\Console\Commands\ModuleTestCommand;
use Kylin\Modules\Console\Commands\ModuleQualityCommand;
use Kylin\Modules\Console\Commands\ModuleRouteCommand;
use Kylin\Modules\Console\Commands\ModuleEventCommand;
use Kylin\Modules\Console\Commands\ModuleQueueCommand;
use Kylin\Modules\Console\Commands\ModuleConfigCommand;
use Kylin\Modules\Console\Commands\ModuleEnableCommand;
use Kylin\Modules\Console\Commands\ModuleDisableCommand;
use Kylin\Modules\Console\Commands\ModuleDeleteCommand;
use Kylin\Modules\Console\Commands\ModulePublishCommand;
use Kylin\Modules\Console\Commands\ModuleCacheCommand;
use Kylin\Modules\Console\Commands\ModuleClearCacheCommand;
use Kylin\Modules\Console\Commands\ModuleMakeControllerCommand;
use Kylin\Modules\Console\Commands\ModuleMakeModelCommand;
use Kylin\Modules\Console\Commands\ModuleMakeMigrationCommand;
use Kylin\Modules\Console\Commands\ModuleMakeSeederCommand;
use Kylin\Modules\Console\Commands\ModuleMakeFactoryCommand;
use Kylin\Modules\Console\Commands\ModuleMakeMiddlewareCommand;
use Kylin\Modules\Console\Commands\ModuleMakeRequestCommand;
use Kylin\Modules\Console\Commands\ModuleMakeCommandCommand;
use Kylin\Modules\Console\Commands\ModuleMakePolicyCommand;
use Kylin\Modules\Console\Commands\ModuleMakeRuleCommand;
use Kylin\Modules\Console\Commands\ModuleMakeMailCommand;
use Kylin\Modules\Console\Commands\ModuleMakeNotificationCommand;
use Kylin\Modules\Console\Commands\ModuleMakeResourceCommand;
use Kylin\Modules\Console\Commands\ModuleMakeComponentCommand;
use Kylin\Modules\Console\Commands\ModuleMakeTestCommand;
use Kylin\Modules\Console\Commands\ModuleMakeListenerCommand;
use Kylin\Modules\Console\Commands\ModuleMakeEventCommand;
use Kylin\Modules\Console\Commands\ModuleMakeObserverCommand;
use Kylin\Modules\Console\Commands\ModuleMakeJobCommand;
use Kylin\Modules\Console\Commands\ModuleMakeScopeCommand;
use Kylin\Modules\Console\Commands\ModuleMakeTraitCommand;
use Kylin\Modules\Console\Commands\ModuleMakeInterfaceCommand;
use Kylin\Modules\Console\Commands\ModuleMakeEnumCommand;
use Kylin\Modules\Console\Commands\ModuleMakeProviderCommand;
use Kylin\Modules\Console\Commands\ModuleMakeExceptionCommand;
use Kylin\Modules\Console\Commands\ModuleMakeHelperCommand;
use Kylin\Modules\Console\Commands\ModuleMakeContractCommand;
use Kylin\Modules\Console\Commands\ModuleMakeServiceCommand;
use Kylin\Modules\Console\Commands\ModuleMakeRepositoryCommand;
use Kylin\Modules\Console\Commands\ModuleMakeConfigCommand;
use Kylin\Modules\Console\Commands\ModuleMakeRouteCommand;
use Kylin\Modules\Console\Commands\ModuleMakeViewCommand;
use Kylin\Modules\Console\Commands\ModuleMakeLangCommand;
use Kylin\Modules\Console\Commands\ModuleMakeApiRouteCommand;
use Kylin\Modules\Console\Commands\ModuleMakeBroadcastCommand;
use Kylin\Modules\Console\Commands\ModuleMakeSubscriberCommand;
use Kylin\Modules\Console\Commands\ModuleMakeAllCommand;
use Kylin\Modules\Console\Commands\ModuleMakeCastCommand;
use Kylin\Modules\Console\Commands\ModuleMakeInertiaCommand;
use Kylin\Modules\Autoload\Autoloader;
use Kylin\Modules\ModuleManager;
use Illuminate\Contracts\Container\Container;

/**
 * 模块服务提供者
 *
 * 负责注册模块相关的服务、命令和自动加载器
 */
class ModulesServiceProvider extends ServiceProvider
{
    /**
     * 注册应用服务
     */
    public function register(): void
    {
        $this->registerConfig();
        $this->registerModuleManager();
        $this->registerAutoloader();
    }

    /**
     * 引导应用服务
     */
    public function boot(): void
    {
        $this->registerCommands();
        $this->publishConfig();
        $this->bootModules();
    }

    /**
     * 注册模块配置
     */
    protected function registerConfig(): void
    {
        $this->mergeConfigFrom(
            __DIR__ . '/../../config/modules.php', 'modules'
        );
    }

    /**
     * 发布模块配置
     */
    protected function publishConfig(): void
    {
        $this->publishes([
            __DIR__ . '/../../config/modules.php' => config_path('modules.php'),
        ], 'modules-config');
    }

    /**
     * 注册模块管理器
     */
    protected function registerModuleManager(): void
    {
        $this->app->singleton('modules', fn (Container $app) => new ModuleManager($app));

        $this->app->alias('modules', ModuleManager::class);
    }

    /**
     * 注册自动加载器
     */
    protected function registerAutoloader(): void
    {
        $this->app->singleton(Autoloader::class, fn (Container $app) => new Autoloader($app['files'], $app['modules']));

        $this->app->make(Autoloader::class)->register();
    }

    /**
     * 注册控制台命令
     */
    protected function registerCommands(): void
    {
        if ($this->app->runningInConsole()) {
            $this->commands([
                ModuleMakeCommand::class,
                ModuleListCommand::class,
                ModuleMigrateCommand::class,
                ModuleMigrateRefreshCommand::class,
                ModuleMigrateRollbackCommand::class,
                ModuleMigrateResetCommand::class,
                ModuleSeedCommand::class,
                ModuleInstallCommand::class,
                ModuleUninstallCommand::class,
                ModuleUpdateCommand::class,
                ModuleShowCommand::class,
                ModuleCopyCommand::class,
                ModuleExportCommand::class,
                ModuleImportCommand::class,
                ModuleDependencyCommand::class,
                ModuleStatusCommand::class,
                ModuleSearchCommand::class,
                ModuleBackupCommand::class,
                ModuleStatsCommand::class,
                ModuleVersionCommand::class,
                ModuleInitCommand::class,
                ModuleHealthCommand::class,
                ModuleDocCommand::class,
                ModuleMonitorCommand::class,
                ModuleSecurityCommand::class,
                ModuleI18nCommand::class,
                ModuleTestCommand::class,
                ModuleQualityCommand::class,
                ModuleRouteCommand::class,
                ModuleEventCommand::class,
                ModuleQueueCommand::class,
                ModuleConfigCommand::class,
                ModuleEnableCommand::class,
                ModuleDisableCommand::class,
                ModuleDeleteCommand::class,
                ModulePublishCommand::class,
                ModuleCacheCommand::class,
                ModuleClearCacheCommand::class,
                ModuleMakeControllerCommand::class,
                ModuleMakeModelCommand::class,
                ModuleMakeMigrationCommand::class,
                ModuleMakeSeederCommand::class,
                ModuleMakeFactoryCommand::class,
                ModuleMakeMiddlewareCommand::class,
                ModuleMakeRequestCommand::class,
                ModuleMakeCommandCommand::class,
                ModuleMakePolicyCommand::class,
                ModuleMakeRuleCommand::class,
                ModuleMakeMailCommand::class,
                ModuleMakeNotificationCommand::class,
                ModuleMakeResourceCommand::class,
                ModuleMakeComponentCommand::class,
                ModuleMakeTestCommand::class,
                ModuleMakeListenerCommand::class,
                ModuleMakeEventCommand::class,
                ModuleMakeObserverCommand::class,
                ModuleMakeJobCommand::class,
                ModuleMakeScopeCommand::class,
                ModuleMakeTraitCommand::class,
                ModuleMakeInterfaceCommand::class,
                ModuleMakeEnumCommand::class,
                ModuleMakeProviderCommand::class,
                ModuleMakeExceptionCommand::class,
                ModuleMakeHelperCommand::class,
                ModuleMakeContractCommand::class,
                ModuleMakeServiceCommand::class,
                ModuleMakeRepositoryCommand::class,
                ModuleMakeConfigCommand::class,
                ModuleMakeRouteCommand::class,
                ModuleMakeViewCommand::class,
                ModuleMakeLangCommand::class,
                ModuleMakeApiRouteCommand::class,
                ModuleMakeBroadcastCommand::class,
                ModuleMakeSubscriberCommand::class,
                ModuleMakeAllCommand::class,
                ModuleMakeCastCommand::class,
                ModuleMakeInertiaCommand::class,
            ]);
        }
    }

    /**
     * 启动所有模块
     */
    protected function bootModules(): void
    {
        $this->app['modules']->boot();
    }

    /**
     * 获取提供者提供的服务
     */
    public function provides(): array
    {
        return ['modules', ModuleManager::class, Autoloader::class];
    }
}