<?php

use App\Providers\AppServiceProvider;
use App\Providers\DataImportServiceProvider;
use App\Providers\DberpPassportServiceProvider;
use App\Providers\DBErpServiceProvider;
use App\Providers\Filament\AdminPanelProvider;
use App\Providers\TelescopeServiceProvider;
use App\Providers\ToolServiceProvider;
use App\Tools\ToolRegistry;
use Laravel\Passport\Passport;
use Laravel\Telescope\TelescopeApplicationServiceProvider;

/**
 * 在线更新会先 ReplaceFiles、后 ReplaceVendor。新 Provider 可能已落盘，Composer 包要到下一步才进 vendor。
 * 依赖第三方包的条目必须声明 requires；先检查依赖类再 autoload Provider，缺类则跳过，避免更新轮询 fatal。
 *
 * 新增依赖 Composer 包的 App Provider 时：在此追加 requires，并保证依赖类在 register()/boot() 前可 class_exists。
 *
 * @var list<array{class: class-string, requires: list<class-string>}>
 */
$catalog = [
    ['class' => AppServiceProvider::class, 'requires' => []],
    // ignoreRoutes 必须在 Passport 已进 vendor 时执行；laravel/mcp 未到位时由 Provider boot() 的 class_exists 跳过 MCP 逻辑，不能把 Registrar 放进 requires。
    ['class' => DberpPassportServiceProvider::class, 'requires' => [Passport::class]],
    ['class' => DataImportServiceProvider::class, 'requires' => []],
    ['class' => ToolServiceProvider::class, 'requires' => [ToolRegistry::class]],
    ['class' => DBErpServiceProvider::class, 'requires' => []],
    ['class' => AdminPanelProvider::class, 'requires' => []],
    // 发布包按行删除 Telescope；本条必须保持单行。
    ['class' => TelescopeServiceProvider::class, 'requires' => [TelescopeApplicationServiceProvider::class]],
];

$providers = [];

foreach ($catalog as $entry) {
    $provider = $entry['class'];
    $requirementsMet = true;

    foreach ($entry['requires'] as $required) {
        if (! is_string($required) || $required === '' || ! class_exists($required)) {
            $requirementsMet = false;
            break;
        }
    }

    if (! $requirementsMet) {
        continue;
    }

    if (! class_exists($provider)) {
        continue;
    }

    $providers[] = $provider;
}

return $providers;
