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";
import * as crypto from "crypto";

/** 压缩引擎路径表 */
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 userHomeDir = Os.homedir();
  const cacheDir = path.join(userHomeDir, ".image_compress_cache");

  if (!fsSync.existsSync(cacheDir)) await fs.mkdir(cacheDir, { recursive: true });

  const now = Date.now();
  const tempDir = path.join(userHomeDir, `.image_compress_temp/${now}`);

  if (!fsSync.existsSync(tempDir)) await fs.mkdir(tempDir, { recursive: true });

  for (let i = 0; i < paths.length; i += chunkSize) {
    const chunk = paths.slice(i, i + chunkSize);

    const ps = chunk.map(async (imgPath, idx) => {
      const tempName = `${tempDir}/${i + idx}.png`;

      // 检查缓存
      const fileBuffer = await fs.readFile(imgPath);
      const md5Hash = crypto.createHash("md5").update(fileBuffer).digest("hex");
      const cachedFilePath = path.join(cacheDir, `${md5Hash}.png`);

      if (fsSync.existsSync(cachedFilePath)) {
        // 如果缓存文件存在，直接复制到目标路径
        await fs.copyFile(cachedFilePath, imgPath);
      } else {
        // 如果缓存文件不存在，执行压缩操作并缓存
        await fs.copyFile(imgPath, tempName);
        execSync(`"${pngquantPath}" ${compressOptions} "${tempName}"`);
        await fs.copyFile(tempName, imgPath);
        await fs.copyFile(tempName, cachedFilePath);
      }

      completed++;
      onProgress(completed, paths.length);
    });

    await Promise.all(ps);
  }

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

}
