import path from 'path';
import { BuildStateManager } from '../state/index.js';
/**
 * Vite 插件：记录 Playable Build 状态
 * 在 Vite 打包过程中记录资源的处理信息
 */
export function viteBuildStatePlugin(options) {
    let stateManager;
    const transformedModules = new Map();
    return {
        name: 'vite-plugin-build-state',
        enforce: 'post', // 在其他插件之后执行，以便记录最终的处理结果
        async configResolved(config) {
            console.log('[BuildState] 初始化状态管理器...');
            // 创建状态管理器
            stateManager = new BuildStateManager(options.baseBuildDir, options.outputDir);
            // 尝试加载 Base Build 的状态
            const loaded = await stateManager.loadState();
            if (loaded) {
                console.log('[BuildState] 已加载 Base Build 状态');
            }
            else {
                console.log('[BuildState] 未找到 Base Build 状态，将创建新状态');
            }
            // 开始 Playable 构建阶段
            stateManager.startStage('playable', {
                platform: options.platform,
                mode: config.mode,
            });
        },
        async transform(code, id) {
            // 记录模块转换信息
            if (!id.includes('node_modules') && !id.startsWith('\0')) {
                const originalSize = code.length;
                // 这里我们只记录原始大小，转换后的大小将在后续的 hook 中更新
                transformedModules.set(id, {
                    originalSize,
                    transformedSize: originalSize, // 初始值
                });
            }
            return null; // 不修改代码
        },
        async generateBundle(options, bundle) {
            console.log('[BuildState] 记录打包产物...');
            // 遍历所有生成的文件
            for (const [fileName, output] of Object.entries(bundle)) {
                if (output.type === 'asset') {
                    // 资产文件（图片、字体等）
                    const assetId = `playable-asset-${fileName}`;
                    const assetSize = typeof output.source === 'string'
                        ? Buffer.byteLength(output.source, 'utf-8')
                        : output.source.length;
                    // 尝试从 Base Build 状态中找到原始资产
                    const existingAsset = stateManager.getAsset(assetId);
                    const originalSize = existingAsset?.originalSize || assetSize;
                    // 判断资产类型
                    const ext = path.extname(fileName).toLowerCase();
                    let assetType = 'other';
                    if (['.png', '.jpg', '.jpeg', '.webp', '.gif'].includes(ext)) {
                        assetType = 'texture';
                    }
                    else if (['.mp3', '.wav', '.ogg'].includes(ext)) {
                        assetType = 'audio';
                    }
                    else if (['.glb', '.gltf', '.obj', '.fbx'].includes(ext)) {
                        assetType = 'model';
                    }
                    else if (ext === '.css') {
                        assetType = 'css';
                    }
                    else if (['.woff', '.woff2', '.ttf', '.otf'].includes(ext)) {
                        assetType = 'font';
                    }
                    // 如果资产不存在，先记录
                    if (!existingAsset) {
                        stateManager.recordAsset(assetId, fileName, fileName, originalSize, assetType);
                    }
                    // 更新 Playable 阶段的处理信息
                    const optimizations = [];
                    // 检测图片压缩
                    if (assetType === 'texture' && assetSize < originalSize * 0.9) {
                        optimizations.push('image-compress');
                    }
                    // 检测格式转换（如 PNG -> WebP）
                    if (fileName.includes('.webp') && existingAsset?.originalName.includes('.png')) {
                        optimizations.push('format-convert');
                    }
                    stateManager.updateAsset(assetId, 'playable', fileName, fileName, assetSize, {
                        optimizations,
                        inlined: false,
                    });
                }
                else if (output.type === 'chunk') {
                    // JavaScript chunk
                    const chunkId = `playable-chunk-${fileName}`;
                    const chunkSize = Buffer.byteLength(output.code, 'utf-8');
                    // 计算原始大小（所有模块的原始大小之和）
                    let originalSize = 0;
                    for (const moduleId of Object.keys(output.modules)) {
                        const moduleInfo = transformedModules.get(moduleId);
                        if (moduleInfo) {
                            originalSize += moduleInfo.originalSize;
                        }
                    }
                    if (originalSize === 0) {
                        originalSize = chunkSize; // 回退值
                    }
                    // 记录 chunk
                    stateManager.recordAsset(chunkId, fileName, fileName, originalSize, 'script');
                    const optimizations = [];
                    // 检测压缩
                    if (output.code.length < originalSize * 0.8) {
                        optimizations.push('minify');
                    }
                    // 检测 tree-shaking（通过模块数量判断）
                    if (Object.keys(output.modules).length < Object.keys(output.modules).length * 0.9) {
                        optimizations.push('tree-shake');
                    }
                    // 检测代码分割
                    if (fileName.includes('chunk') || fileName.includes('-')) {
                        optimizations.push('code-split');
                    }
                    stateManager.updateAsset(chunkId, 'playable', fileName, fileName, chunkSize, {
                        optimizations,
                        inlined: false,
                    });
                }
            }
        },
        async closeBundle() {
            // 结束 Playable 构建阶段
            stateManager.endStage();
            // 只在分析模式下保存状态文件（分析报告需要用到）
            if (options.analyze) {
                console.log('[BuildState] 保存构建状态...');
                await stateManager.saveState();
            }
            // 输出统计信息
            const stats = stateManager.getStatistics();
            console.log(`[BuildState] 构建统计:`);
            console.log(`  - 总资产数: ${stats.totalAssets}`);
            console.log(`  - 原始大小: ${(stats.totalOriginalSize / 1024).toFixed(2)} KB`);
            console.log(`  - 最终大小: ${(stats.totalFinalSize / 1024).toFixed(2)} KB`);
            console.log(`  - 总压缩率: ${(stats.totalCompressionRatio * 100).toFixed(1)}%`);
        },
    };
}
