/**
 * @apigo.cc/loader
 * 全自动同步依赖调度器 (UMD 优先)
 */

const DEFAULT_VERSIONS = {
    'state': '1.0.23',
    'bootstrap': '1.0.9',
    'base': '1.0.23',
    'datatable': '1.0.16',
    'kanban': '1.0.2',
    'mindmap': '1.0.2',
    'chart': '1.0.2',
    'editor': '1.0.2',
    'loader': '1.0.7'
};

const DEPENDENCY_GRAPH = {
    'bootstrap': ['state'],
    'base': ['state', 'bootstrap'],
    'datatable': ['state', 'bootstrap', 'base'],
    'editor': ['state', 'bootstrap', 'base'],
    'mindmap': ['state', 'bootstrap', 'base']
};

const Loader = {
    _loaded: new Set(),
    _v: null, 

    load: (...pkgs) => {
        if (typeof document === 'undefined') return;

        const currentScript = document.currentScript;
        const currentUrl = (currentScript && currentScript.src) ? currentScript.src : '';
        
        // 1. 确定加载源与格式
        let tpl = '';
        const isMin = currentUrl.includes('.min.js');
        const ext = isMin ? '.min.js' : '.js';

        if (currentUrl && (currentUrl.includes('jsdelivr.net') || currentUrl.includes('unpkg.com') || currentUrl.includes('npm.elemecdn.com'))) {
            let cdnBase = 'https://cdn.jsdelivr.net/npm/@apigo.cc/{project}@{tag}/dist/{project}';
            if (currentUrl.includes('unpkg.com')) cdnBase = 'https://unpkg.com/@apigo.cc/{project}@{tag}/dist/{project}';
            else if (currentUrl.includes('npm.elemecdn.com')) cdnBase = 'https://npm.elemecdn.com/@apigo.cc/{project}@{tag}/dist/{project}';
            tpl = cdnBase + ext;
        } else if (currentUrl) {
            const baseDir = currentUrl.substring(0, currentUrl.lastIndexOf('/') + 1);
            tpl = baseDir + '{project}' + ext;
        } else {
            tpl = 'https://cdn.jsdelivr.net/npm/@apigo.cc/{project}@{tag}/dist/{project}' + ext;
        }

        // 2. 解析包名与显式指定的版本号
        const requested = pkgs.map(p => {
            const s = String(p).trim();
            const colonIdx = s.indexOf(':');
            return {
                name: colonIdx === -1 ? s : s.slice(0, colonIdx),
                version: colonIdx === -1 ? null : s.slice(colonIdx + 1)
            };
        }).filter(item => item.name);

        // 3. 分析依赖并排序
        const finalQueue = [];
        const nameToVersion = {}; 

        const addWithDeps = (item) => {
            const name = item.name.toLowerCase();
            if (item.version) nameToVersion[name] = item.version;

            const deps = DEPENDENCY_GRAPH[name] || [];
            deps.forEach(depName => addWithDeps({ name: depName }));
            
            if (!finalQueue.includes(name)) finalQueue.push(name);
        };
        requested.forEach(item => addWithDeps(item));

        // 4. 注入脚本
        const isInitialLoad = document.readyState === 'loading';
        
        finalQueue.forEach(name => {
            if (Loader._loaded.has(name)) return;
            
            const version = nameToVersion[name] || DEFAULT_VERSIONS[name] || 'latest';
            let url = tpl.replace(/{project}/g, name).replace(/{tag}/g, version);

            if (Loader._v) {
                const joinChar = url.includes('?') ? '&' : '?';
                url += `${joinChar}v=${Loader._v}`;
            }

            // 核心改进：如果是初始化阶段，使用 document.write 实现同步阻塞加载
            // 这能保证下一行内联脚本执行时，全局变量已经就绪。
            if (isInitialLoad) {
                document.write(`<script src="${url}"><\/script>`);
            } else {
                const script = document.createElement('script');
                script.src = url;
                document.head.appendChild(script);
            }
            Loader._loaded.add(name);
        });
    }
};

// 立即解析参数
if (typeof document !== 'undefined' && document.currentScript) {
    const loaderUrl = new URL(document.currentScript.src, location.href);
    Loader._v = loaderUrl.searchParams.get('v'); 

    let toLoad = loaderUrl.searchParams.get('load');
    const hash = loaderUrl.hash.substring(1); 
    if (!toLoad && hash) {
        toLoad = hash.startsWith('load=') ? hash.substring(5) : hash;
    }

    if (toLoad) {
        Loader.load(...toLoad.split(','));
    }
}

globalThis.__apigo_load = Loader.load;
