import fs from 'fs/promises';
import path from 'path';
import { formatBytes } from './utils.js';
/**
 * 构建状态管理器
 *
 * 职责：
 * 1. 记录打包过程中每个资源的处理信息
 * 2. 追踪资源的转换过程（原始大小 -> 处理后大小）
 * 3. 生成 state.json 文件供分析使用
 */
export class BuildStateManager {
    constructor(outputDir, platform, buildMode) {
        this.stateFilePath = path.join(outputDir, 'build-state.json');
        this.state = {
            version: '1.0.0',
            buildTime: new Date().toISOString(),
            platform,
            buildMode,
            assets: {},
            output: {
                totalSize: 0,
                files: {},
            },
        };
    }
    /**
     * 记录资源的原始信息
     */
    recordAsset(assetId, originalName, originalPath, originalSize, type) {
        this.state.assets[assetId] = {
            originalName,
            originalPath,
            originalSize,
            type,
        };
    }
    /**
     * 更新资源的处理信息
     */
    updateAssetProcessing(assetId, processedName, processedSize, processedPath, options) {
        const asset = this.state.assets[assetId];
        if (!asset) {
            console.warn(`[BuildState] 资源不存在: ${assetId}`);
            return;
        }
        asset.processedName = processedName;
        asset.processedSize = processedSize;
        asset.processedPath = processedPath;
        asset.minified = options?.minified;
        asset.inlined = options?.inlined;
        // 计算压缩率
        if (asset.originalSize > 0) {
            asset.compressionRate = ((asset.originalSize - processedSize) / asset.originalSize) * 100;
        }
    }
    /**
     * 更新资源的最终位置
     */
    updateAssetFinalLocation(assetId, finalLocation, finalReference) {
        const asset = this.state.assets[assetId];
        if (!asset) {
            console.warn(`[BuildState] 资源不存在: ${assetId}`);
            return;
        }
        asset.finalLocation = finalLocation;
        asset.finalReference = finalReference;
    }
    /**
     * 记录输出文件
     */
    recordOutputFile(filename, size, type) {
        this.state.output.files[filename] = { size, type };
        this.state.output.totalSize += size;
        if (filename.endsWith('.html')) {
            this.state.output.htmlSize = size;
        }
    }
    /**
     * 获取状态
     */
    getState() {
        return this.state;
    }
    /**
     * 保存状态到文件
     */
    async save() {
        await fs.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), 'utf-8');
        console.log(`[BuildState] 状态已保存: ${this.stateFilePath}`);
    }
    /**
     * 从文件加载状态
     */
    static async load(outputDir) {
        const stateFilePath = path.join(outputDir, 'build-state.json');
        try {
            const content = await fs.readFile(stateFilePath, 'utf-8');
            const state = JSON.parse(content);
            const manager = new BuildStateManager(outputDir);
            manager.state = state;
            return manager;
        }
        catch (error) {
            console.warn(`[BuildState] 无法加载状态文件: ${stateFilePath}`);
            return null;
        }
    }
    /**
     * 生成分析报告数据
     */
    generateAnalysisData() {
        const assets = Object.entries(this.state.assets).map(([id, asset]) => ({
            name: asset.processedName || asset.originalName,
            originalSize: asset.originalSize,
            processedSize: asset.processedSize || asset.originalSize,
            compressionRate: asset.compressionRate || 0,
            type: asset.type,
            finalLocation: asset.finalLocation || 'unknown',
        }));
        const totalOriginalSize = assets.reduce((sum, a) => sum + a.originalSize, 0);
        const totalProcessedSize = assets.reduce((sum, a) => sum + a.processedSize, 0);
        const totalCompressionRate = totalOriginalSize > 0
            ? ((totalOriginalSize - totalProcessedSize) / totalOriginalSize) * 100
            : 0;
        return {
            assets,
            summary: {
                totalOriginalSize,
                totalProcessedSize,
                totalCompressionRate,
                assetCount: assets.length,
            },
        };
    }
    /**
     * 打印摘要
     */
    printSummary() {
        const { assets, summary } = this.generateAnalysisData();
        console.log('\n📊 构建状态摘要');
        console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        console.log(`资源总数: ${summary.assetCount}`);
        console.log(`原始大小: ${formatBytes(summary.totalOriginalSize)}`);
        console.log(`处理后大小: ${formatBytes(summary.totalProcessedSize)}`);
        console.log(`压缩率: ${summary.totalCompressionRate.toFixed(2)}%`);
        console.log(`最终产物大小: ${formatBytes(this.state.output.totalSize)}`);
        if (this.state.output.htmlSize) {
            console.log(`HTML 大小: ${formatBytes(this.state.output.htmlSize)}`);
        }
        // 按类型分组
        const byType = new Map();
        for (const asset of assets) {
            const existing = byType.get(asset.type) || { count: 0, originalSize: 0, processedSize: 0 };
            existing.count++;
            existing.originalSize += asset.originalSize;
            existing.processedSize += asset.processedSize;
            byType.set(asset.type, existing);
        }
        console.log('\n按类型统计:');
        for (const [type, stats] of byType.entries()) {
            const rate = stats.originalSize > 0
                ? ((stats.originalSize - stats.processedSize) / stats.originalSize) * 100
                : 0;
            console.log(`  ${type}: ${stats.count} 个, ${formatBytes(stats.originalSize)} → ${formatBytes(stats.processedSize)} (${rate.toFixed(1)}%)`);
        }
        console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
    }
}
