import { createLogger, defineConfig } from 'vite';
import path from 'path';
import fs from 'fs';
import { viteSingleFile } from 'vite-plugin-singlefile';
import viteImagemin from '@vheemstra/vite-plugin-imagemin';
import imageminMozjpeg from 'imagemin-mozjpeg';
import imageminPngquant from 'imagemin-pngquant';
import imageminWebp from 'imagemin-webp';
import { PLATFORM_CONFIGS } from './platform-configs.js';
import { vitePlatformPlugin } from './plugin-platform.js';
import { createPlatformAdapter } from '../platforms/index.js';
/**
 * 通用 Vite 配置构建器（外部引擎专用）
 *
 * 与 PlayCanvas 专用配置构建器不同，通用版本：
 * - 不使用 vitePlayCanvasPlugin（不需要处理 config.json 等专有格式）
 * - 不使用 viteESMBundlePlugin 和 viteModelCompressionPlugin（Draco/Meshopt 是 PlayCanvas 特有的）
 * - 仅使用通用的插件：
 *   - viteSingleFile：HTML 内联
 *   - vitePlatformPlugin：平台 SDK 注入
 *   - viteImagemin：图片压缩
 */
export class GenericViteConfigBuilder {
    constructor(baseBuildDir, platform, options, baseBuildMetadata) {
        this.baseBuildDir = baseBuildDir;
        this.platform = platform;
        this.options = options;
        this.baseBuildMetadata = baseBuildMetadata;
        this.finalOutputDir = '';
        this.viteOutputDir = '';
        // 统一规范化 baseBuildDir（与 ViteConfigBuilder 一致）
        // realpathSync.native 能在 Windows 上正确解析 8.3 短路径名（如 HOMKER~1 → homkerliu）
        // macOS 上解析符号链接。Vite 内部也使用 native realpath，必须对齐。
        this.baseBuildDir = fs.realpathSync.native(baseBuildDir).replace(/\\/g, '/');
    }
    /**
     * 创建 Vite 配置
     */
    async create() {
        console.log('[GenericViteConfigBuilder] 创建通用配置...');
        console.log(`  - 引擎: ${this.baseBuildMetadata.engine}`);
        const platformConfig = this.getPlatformConfig();
        const outputDir = this.options.outputDir || './dist';
        const playableOptions = this.getPlayableOptions(platformConfig);
        const rootDir = this.baseBuildDir;
        const viteOutputDir = '__dist__';
        const viteOutputDirAbsolute = path.join(rootDir, viteOutputDir);
        const finalOutputDir = path.isAbsolute(outputDir)
            ? outputDir
            : path.resolve(process.cwd(), outputDir);
        this.finalOutputDir = finalOutputDir;
        this.viteOutputDir = viteOutputDirAbsolute;
        console.log(`[GenericViteConfigBuilder] 路径配置:`);
        console.log(`  - root: ${rootDir}`);
        console.log(`  - viteOutputDir: ${viteOutputDirAbsolute}`);
        console.log(`  - finalOutputDir: ${finalOutputDir}`);
        return this.createConfig(platformConfig, viteOutputDir, playableOptions, rootDir);
    }
    /**
     * 获取 Vite 的临时输出目录
     */
    getViteOutputDir() {
        return this.viteOutputDir || '';
    }
    /**
     * 获取最终输出目录
     */
    getFinalOutputDir() {
        return this.finalOutputDir || '';
    }
    /**
     * 创建通用配置
     */
    createConfig(platformConfig, outputDir, playableOptions, rootDir) {
        const logger = this.createLogger();
        return defineConfig({
            root: rootDir,
            base: './',
            customLogger: logger,
            build: {
                outDir: outputDir,
                emptyOutDir: true,
                cssMinify: this.shouldMinifyCSS(platformConfig) ? 'lightningcss' : false,
                minify: this.shouldMinifyJS(platformConfig) ? 'terser' : false,
                terserOptions: {
                    compress: {
                        drop_console: true,
                        drop_debugger: true,
                    },
                },
                // 所有资源内联（生成单文件 HTML）
                assetsInlineLimit: Infinity,
                sourcemap: platformConfig.includeSourcemap,
                rollupOptions: {
                    onwarn: this.createRollupWarnHandler(),
                },
            },
            plugins: this.createPlugins(platformConfig, playableOptions),
        });
    }
    /**
     * 创建插件列表
     */
    createPlugins(platformConfig, playableOptions) {
        const plugins = [];
        // 1. 平台特定插件（注入平台 SDK：MRAID、CTA 等）
        const platformAdapter = createPlatformAdapter(this.options);
        const absoluteOutputDir = this.viteOutputDir || path.resolve(this.baseBuildDir, '__dist__');
        plugins.push(vitePlatformPlugin({
            platform: this.platform,
            adapter: platformAdapter,
            outputDir: absoluteOutputDir,
            baseBuildDir: this.baseBuildDir,
            outputFormat: platformConfig.outputFormat,
            externFiles: playableOptions.externFiles,
            mraidSupport: playableOptions.mraidSupport,
        }));
        // 2. 图片压缩插件
        if (platformConfig.compressImages) {
            const imageQuality = platformConfig.imageQuality || {
                jpg: 75,
                png: [0.7, 0.8],
                webp: 75,
            };
            const jpegQuality = this.options.imageQuality ?? imageQuality.jpg ?? 75;
            const pngQuality = Array.isArray(imageQuality.png) && imageQuality.png.length >= 2
                ? [imageQuality.png[0], imageQuality.png[1]]
                : [0.7, 0.8];
            const webpQuality = imageQuality.webp ?? 75;
            const imageminPlugin = viteImagemin({
                plugins: {
                    jpg: [imageminMozjpeg({ quality: jpegQuality })],
                    jpeg: [imageminMozjpeg({ quality: jpegQuality })],
                    png: [imageminPngquant({ quality: pngQuality })],
                },
                makeWebp: this.options.convertToWebP !== false
                    ? {
                        plugins: {
                            jpg: [imageminWebp({ quality: webpQuality })],
                            jpeg: [imageminWebp({ quality: webpQuality })],
                            png: [imageminWebp({ quality: webpQuality })],
                        },
                    }
                    : undefined,
            });
            if (imageminPlugin) {
                plugins.push(imageminPlugin);
            }
        }
        // 3. 单文件输出插件（仅 HTML 格式）
        if (platformConfig.outputFormat === 'html') {
            plugins.push(viteSingleFile({
                removeViteModuleLoader: true,
            }));
        }
        return plugins.filter(Boolean);
    }
    /**
     * 获取平台配置
     */
    getPlatformConfig() {
        const baseConfig = PLATFORM_CONFIGS[this.platform];
        const resolvedOutputFormat = this.options.format ?? baseConfig.outputFormat;
        return {
            ...baseConfig,
            outputFormat: resolvedOutputFormat,
            minifyCSS: this.options.cssMinify ?? baseConfig.minifyCSS,
            minifyJS: this.options.jsMinify ?? baseConfig.minifyJS,
            compressImages: this.options.compressImages ?? baseConfig.compressImages,
            // 外部引擎不支持模型压缩
            compressModels: false,
        };
    }
    /**
     * 获取 Playable 选项
     */
    getPlayableOptions(config) {
        const playable = config.playable ?? {};
        const externFiles = this.resolveExternFiles(playable.externFiles);
        return {
            outputFormat: config.outputFormat,
            patchXhrOut: this.options.patchXhrOut ?? playable.patchXhrOut ?? false,
            inlineGameScripts: false, // 外部引擎不使用此选项
            compressEngine: false, // 外部引擎不支持引擎压缩
            compressConfigJson: false, // 外部引擎没有 config.json
            configJsonInline: false,
            externFiles,
            mraidSupport: this.options.mraidSupport ?? playable.mraidSupport ?? false,
            snapchatCta: this.options.snapchatCta ?? playable.snapchatCta ?? false,
        };
    }
    /**
     * 解析外部文件配置
     */
    resolveExternFiles(defaultValue) {
        const optionValue = this.options.externFiles;
        const raw = optionValue ?? defaultValue;
        if (!raw) {
            return undefined;
        }
        if (typeof raw === 'object') {
            return raw;
        }
        const folderName = this.options.snapchat?.folderName;
        const externalUrlPrefix = this.options.snapchat?.externalUrlPrefix;
        return {
            enabled: true,
            folderName,
            externalUrlPrefix,
        };
    }
    /**
     * 是否应该压缩 CSS
     */
    shouldMinifyCSS(config) {
        return config.minifyCSS;
    }
    /**
     * 是否应该压缩 JS
     */
    shouldMinifyJS(config) {
        return config.minifyJS;
    }
    /**
     * 创建自定义 Logger
     */
    createLogger() {
        const logger = createLogger();
        return {
            ...logger,
            warn(msg, options) {
                if (typeof msg === 'string' && msg.includes('can\'t be bundled without type="module"')) {
                    return;
                }
                logger.warn(msg, options);
            },
        };
    }
    /**
     * 创建 Rollup 警告处理器
     */
    createRollupWarnHandler() {
        return (warning, warn) => {
            const message = typeof warning === 'string' ? warning : warning.message;
            if (message && message.includes('can\'t be bundled without type="module"')) {
                return;
            }
            warn(warning);
        };
    }
}
