import {exec, execSync} from 'child_process';
import * as path from "path";
import {promises as fs} from "fs";
import * as Os from "os";
import * as fsSync from "fs";

/** 压缩引擎路径表 */
const enginePathMap = {
  /** macOS */
  'darwin': 'pngquant/macos/pngquant',
  /** Windows */
  'win32': 'pngquant/windows/pngquant'
}

export async function compressAllImage(
  paths = [],
  onProgress: (cur?: number, total?: number) => void = () => void 0,
) {
  const platform = Os.platform();
  const pngquantPath = path.join(__dirname, "./", enginePathMap[platform]);
  // 设置引擎文件的执行权限（仅 macOS）
  if (pngquantPath && platform === 'darwin') {
    if ((await fs.stat(pngquantPath)).mode != 33261) {
      // 默认为 33188
      await fs.chmod(pngquantPath, 33261);
    }
  }

  const qualityParam = `--quality 0-99`,
    speedParam = `--speed 4`,
    skipParam = platform == "win32" ? "" : '--skip-if-larger',
    outputParam = '--ext=.png',
    writeParam = '--force',
    // colorsParam = config.colors,
    // compressOptions = `${qualityParam} ${speedParam} ${skipParam} ${outputParam} ${writeParam} ${colorsParam}`;
    compressOptions = `${qualityParam} ${speedParam} ${skipParam} ${outputParam} ${writeParam}`;

  let completed = 0;

  const chunkSize = 20;
  const totalBatches = Math.ceil(paths.length / chunkSize);

  if (platform == "win32") {

    const now = Date.now();
    const tempDir = `C:\\Temp\\duiba\\${now}`;

    if (!fsSync.existsSync("C:\\Temp")) await fs.mkdir("C:\\Temp");
    if (!fsSync.existsSync("C:\\Temp\\duiba")) await fs.mkdir("C:\\Temp\\duiba");
    if (!fsSync.existsSync(tempDir)) await fs.mkdir(tempDir);

    for (let i = 0; i < paths.length; i += chunkSize) {
      const currentBatch = Math.floor(i / chunkSize) + 1;
      // console.log(`正在处理第 ${currentBatch}/${totalBatches} 批图片压缩...\n`);

      const chunk = paths.slice(i, i + chunkSize);

      const ps = chunk.map(async (imgPath, idx) => {
        const tempName = `${tempDir}/${i + idx}.png`;
        await fs.copyFile(imgPath, tempName);
        execSync(`"${pngquantPath}" ${compressOptions} "${tempName}"`);
        await fs.copyFile(tempName, imgPath);
        completed++;
        onProgress(completed, paths.length);
      });

      await Promise.all(ps);
    }

    await fs.rm(tempDir, {recursive: true});

  } else {
    // 批次执行
    for (let i = 0; i < paths.length; i += chunkSize) {
      const currentBatch = Math.floor(i / chunkSize) + 1;
      // console.log(`正在处理第 ${currentBatch}/${totalBatches} 批图片压缩...\n`);

      const chunk = paths.slice(i, i + chunkSize);

      let command = "";

      chunk.forEach((imgPath) => {
        command += `"${pngquantPath}" ${compressOptions} "${imgPath}" &`;  // 使用分号替代&实现串行
      });

      await new Promise<void>((resolve) => {
        exec(command, (error, stdout, stderr) => {
          if (error) {
            // console.error(error);
          }

          completed += chunk.length;
          onProgress(completed, paths.length);
          resolve();
        });
      });
    }

  }

}
