const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const { minify } = require('terser');


// 定义项目根目录
const rootDir = __dirname;
// 定义输出目录
const distDir = path.join(rootDir, 'dist');
// 定义要排除的目录和文件
const excludeDirs = ['node_modules', '.git', 'dist', '.vscode', 'scripts'];
const excludeFiles = ['.gitignore', 'package-lock.json', 'yarn.lock', 'release.js', 'README.md'];

// 统计信息变量
let totalJsOriginalSize = 0;
let totalJsCompressedSize = 0;
let jsFileCount = 0;
const jsSizeDetails = [];
// 存储包含console语句的JS文件
const filesWithConsole = [];
// 存储压缩错误的JS文件
const filesWithCompressionError = [];
// 存储压缩后仍含console语句的JS文件
const filesWithConsoleAfterCompression = [];

// 获取当前日期，用于生成zip文件名（格式：YYYY-MM-DD）
function getCurrentDate() {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0');
  const day = String(now.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}

// 定义wxml压缩函数
function compressWxml(content) {
  // 移除HTML注释
  content = content.replace(/<!--[\s\S]*?-->/g, '');
  
  // 移除多余的空白字符（空格、换行、制表符）
  // 保留标签内的必要空格
  content = content.replace(/\s+/g, ' ');
  
  // 移除标签前后的空格
  content = content.replace(/\s*</g, '<');
  content = content.replace(/>\s*/g, '>');
  
  return content;
}

// 定义js压缩函数 - 使用Terser去除console语句
function compressJs(content, filePath) {
    return content;
    try {
        // 使用Terser进行压缩
        const result = minify(content, {
            compress: {
                drop_console: true,  // 去除所有console语句
                drop_debugger: true, // 去除debugger语句
                dead_code: true,
                passes: 3  // 增加压缩次数
            },
            mangle: false,  // 不混淆变量名，保持代码可读性
            output: {
                ascii_only: true,  // 确保输出ASCII字符
                comments: false   // 去除所有注释
            }
        });
        
        if (result.error) {
            console.warn('Terser compression failed for', filePath, ':', result.error.message);
            if (filePath && !filesWithCompressionError.includes(filePath)) {
                filesWithCompressionError.push(filePath);
            }
            return content;  // 出错时返回原始内容
        }
        
        return result.code || content;
    } catch (error) {
        console.warn('Error in compressJs for', filePath, ':', error.message);
        if (filePath && !filesWithCompressionError.includes(filePath)) {
            filesWithCompressionError.push(filePath);
        }
        return content;  // 捕获异常时返回原始内容
    }
}


// 定义css压缩函数
function compressCss(content) {
  // 移除单行注释
  content = content.replace(/\/\/.*$/gm, '');
  
  // 移除多行注释
  content = content.replace(/\/\*[\s\S]*?\*\//g, '');
  
  // 移除多余的空白字符
  content = content.replace(/\s+/g, ' ');
  
  // 移除CSS属性前后的空格
  content = content.replace(/\s*([{:;}])\s*/g, '$1');
  
  // 移除行首和行尾的空格
  content = content.replace(/^\s+|\s+$/gm, '');
  
  return content;
}

// 定义json压缩函数
function compressJson(content) {
  try {
    // 使用JSON.parse和JSON.stringify进行压缩
    // 确保中文等非ASCII字符不会被转义
    const jsonObj = JSON.parse(content);
    return JSON.stringify(jsonObj, null, 0);
  } catch (error) {
    // 如果JSON解析失败，返回原始内容
    console.warn('Failed to compress JSON, using original content:', error.message);
    return content;
  }
}

// 输出JS文件压缩统计结果
function outputJsCompressionStats() {
  if (jsFileCount === 0) {
    console.log('\nNo JS files were processed.');
    return;
  }
  
  console.log('\n=== JS File Compression Statistics ===');
  
  // 输出每个文件的详细信息
  console.log('\nIndividual File Statistics:');
  jsSizeDetails.forEach(file => {
    console.log(`${file.path}`);
    console.log(`  Original: ${file.originalSize} bytes`);
    console.log(`  Compressed: ${file.compressedSize} bytes`);
    console.log(`  Saved: ${file.sizeDiff} bytes (-${file.compressionRatio}%)`);
    console.log('');
  });
  
  // 计算整体统计信息
  const totalSaved = totalJsOriginalSize - totalJsCompressedSize;
  const overallRatio = totalJsOriginalSize > 0 ? (totalSaved / totalJsOriginalSize * 100).toFixed(2) : '0.00';
  
  // 输出整体统计结果
  console.log('=== Overall JS Compression Results ===');
  console.log(`Total JS files processed: ${jsFileCount}`);
  console.log(`Total original size: ${totalJsOriginalSize} bytes`);
  console.log(`Total compressed size: ${totalJsCompressedSize} bytes`);
  console.log(`Total saved: ${totalSaved} bytes (-${overallRatio}%)`);
  console.log('=====================================');
}

// 递归复制目录并压缩文件（wxml, js, css, json）
function copyAndCompressDir(sourceDir, targetDir) {
  // 创建目标目录
  if (!fs.existsSync(targetDir)) {
    fs.mkdirSync(targetDir, { recursive: true });
  }
  
  const files = fs.readdirSync(sourceDir);
  
  files.forEach(file => {
    const sourcePath = path.join(sourceDir, file);
    const targetPath = path.join(targetDir, file);
    const stats = fs.statSync(sourcePath);
    
    // 跳过排除的目录和文件
    if (excludeDirs.includes(file) || excludeFiles.includes(file)) {
      return;
    }
    
    if (stats.isDirectory()) {
      // 递归处理子目录
      copyAndCompressDir(sourcePath, targetPath);
    } else {
      const extname = path.extname(file);
      let compressedContent;
      let content;
      
      try {
        // 根据文件类型选择不同的处理方式
        if (extname === '.wxml') {
          // 压缩wxml文件
          content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
          compressedContent = compressWxml(content);
          fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' });
          console.log(`Compressed and copied: ${sourcePath}`);
        } else if (extname === '.js') {
          // 压缩js文件
          content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
          
          // 检测是否包含console语句
          const hasConsole = /console\.(log|warn|error|info|debug|trace|table|dir|time|timeEnd)/i.test(content);
          if (hasConsole) {
            filesWithConsole.push(sourcePath);
          }
          
          compressedContent = compressJs(content, sourcePath);
          
          // 检测压缩后是否仍包含console语句
          const hasConsoleAfterCompression = /console\.(log|warn|error|info|debug|trace|table|dir|time|timeEnd)/i.test(compressedContent);
          if (hasConsoleAfterCompression) {
            filesWithConsoleAfterCompression.push({ sourcePath, targetPath });
          }
          
          fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' });
          
          // 统计JS文件大小变化
          const originalSize = Buffer.from(content).length;
          const compressedSize = Buffer.from(compressedContent).length;
          const sizeDiff = originalSize - compressedSize;
          const compressionRatio = originalSize > 0 ? (sizeDiff / originalSize * 100).toFixed(2) : '0.00';
          
          totalJsOriginalSize += originalSize;
          totalJsCompressedSize += compressedSize;
          jsFileCount++;
          jsSizeDetails.push({
            path: sourcePath,
            originalSize,
            compressedSize,
            sizeDiff,
            compressionRatio
          });
          
          console.log(`Compressed and copied: ${sourcePath} - ${originalSize} → ${compressedSize} bytes (-${compressionRatio}%)`);
        } else if (extname === '.css') {
          // 压缩css文件
          content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
          compressedContent = compressCss(content);
          fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' });
          console.log(`Compressed and copied: ${sourcePath}`);
        } else if (extname === '.json') {
          // 压缩json文件
          content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
          compressedContent = compressJson(content);
          fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' });
          console.log(`Compressed and copied: ${sourcePath}`);
        } else {
          // 直接复制其他文件
          fs.copyFileSync(sourcePath, targetPath);
          console.log(`Copied: ${sourcePath}`);
        }
      } catch (error) {
        console.error(`Error processing file ${sourcePath}:`, error.message);
        // 发生错误时，直接复制原始文件
        fs.copyFileSync(sourcePath, targetPath);
        console.log(`Fallback: Copied original file ${sourcePath}`);
      }
    }
  });
}

// 使用系统命令创建zip压缩包
function createZipArchive(sourceDir, outputPath) {
  try {
    // 根据操作系统选择命令
    if (process.platform === 'win32') {
      // Windows系统使用PowerShell命令，排除文件名后缀为 -mp-weixin.zip 的文件
      // 使用PowerShell的管道功能和Where-Object来排除特定文件
      const command = `PowerShell.exe -Command "Get-ChildItem -Path \"${sourceDir}\" | Where-Object { $_.Name -notlike '*\-mp\-weixin\.zip' } | Compress-Archive -DestinationPath \"${outputPath}\" -Force"`;
      execSync(command, { shell: 'cmd.exe' });
    } else {
      // Linux/Mac系统使用zip命令，排除文件名后缀为 -mp-weixin.zip 的文件
      const command = `zip -r \"${outputPath}\" * -x \"*-mp-weixin.zip\"`;
      execSync(command, { cwd: sourceDir });
    }
    console.log(`Zip archive created: ${outputPath}`);
  } catch (error) {
    console.error('Error creating zip archive:', error.message);
    throw error;
  }
}

function cleanDistDir(distDir) {
  if (fs.existsSync(distDir)) {
      // 清理dist目录下除**-mp-weixin.zip文件外的所有内容
      const files = fs.readdirSync(distDir);
      files.forEach(file => {
        const filePath = path.join(distDir, file);
        const stats = fs.statSync(filePath);
        
        // 只保留符合特定命名模式的zip文件（**-mp-weixin.zip）
        if (stats.isFile() && path.extname(file) === '.zip' && file.endsWith('-mp-weixin.zip')) {
          console.log(`Keeping zip file: ${file}`);
        } else {
          if (stats.isDirectory()) {
            fs.rmSync(filePath, { recursive: true, force: true });
            console.log(`Removed directory: ${file}`);
          } else {
            fs.unlinkSync(filePath);
            console.log(`Removed file: ${file}`);
          }
        }
      });
      console.log('Cleaned dist directory (excluding -mp-weixin.zip files)');
  }
}

// 主函数
function main() {
  try {
    // 解析命令行参数
    const args = process.argv.slice(2);
    const keepDist = args.includes('--keep-dist') || args.includes('-k');
    const noZip = args.includes('--no-zip') || args.includes('-n');
    
    // 清理dist目录（如果存在且不保留）
    if (fs.existsSync(distDir)) {
      cleanDistDir(distDir);
    } else {
      // 创建dist目录
      fs.mkdirSync(distDir, { recursive: true });
      console.log('Created dist directory');
    }
    
    // 复制并压缩文件到dist目录
    console.log('Start copying and compressing files...');
    copyAndCompressDir(rootDir, distDir);
    console.log('Files copied and compressed successfully!');
    
    // 输出JS文件压缩统计结果
    outputJsCompressionStats();
    
    // 生成zip文件名（格式：POCT检测分析平台-定制化-YYYY-MM-DD-mp-weixin.zip）
    const currentDate = getCurrentDate();
    const zipFileName = `POCT检测分析平台-定制化-${currentDate}-mp-weixin.zip`;
    const zipPath = path.join(distDir, zipFileName);
    
    // 创建zip压缩包（如果未指定--no-zip参数）
    if (!noZip) {
      console.log('Creating zip archive...');
      createZipArchive(distDir, zipPath);
    } else {
      console.log('Skipping zip archive creation (--no-zip specified)');
    }

    // 清理dist目录（如果不保留）
    if (!keepDist) {
      cleanDistDir(distDir);
    }
    
    console.log('\nAll tasks completed successfully!');
    console.log(`Dist directory: ${distDir}`);
    console.log(`Zip file: ${zipPath}`);
    
    // 输出包含console语句的JS文件列表
    if (filesWithConsole.length > 0) {
      console.log('\n=== JS Files with Console Statements ===');
      console.log(`Found ${filesWithConsole.length} file(s) containing console statements:`);
      filesWithConsole.forEach(file => {
        console.log(`- ${file}`);
      });
      console.log('======================================');
    } else {
      console.log('\nNo JS files contain console statements.');
    }
    
    // 输出压缩错误的JS文件列表
    if (filesWithCompressionError.length > 0) {
      console.log('\n=== JS Files with Compression Errors ===');
      console.log(`Found ${filesWithCompressionError.length} file(s) with compression errors:`);
      filesWithCompressionError.forEach(file => {
        console.log(`- ${file}`);
      });
      console.log('======================================');
    } else {
      console.log('\nNo JS files had compression errors.');
    }
    
    // 输出压缩后仍含有console语句的JS文件列表
    if (filesWithConsoleAfterCompression.length > 0) {
      console.log('\n=== JS Files with Console Statements After Compression ===');
      console.log(`Found ${filesWithConsoleAfterCompression.length} file(s) still containing console statements after compression:`);
      filesWithConsoleAfterCompression.forEach((file, index) => {
        console.log(`${index + 1}. ${file.targetPath}`);
      });
      console.log('\n=================================================');
    } else {
      console.log('\nNo JS files contain console statements after compression.');
    }
  } catch (error) {
    console.error('Error occurred:', error);
    process.exit(1);
  }
}

// 执行主函数
main();

// 输出帮助信息
if (process.argv.includes('--help') || process.argv.includes('-h')) {
  console.log('Usage: node release.js [options]');
  console.log('Options:');
  console.log('  --keep-dist, -k    Keep existing dist directory contents');
  console.log('  --no-zip, -n       Skip zip archive creation');
  console.log('  --help, -h         Show this help message');
}