import {promises as fs} from "fs";
import SvgaDescriptor from "./SvgaDescriptor";
import {compressAllImage} from "./ImageCompress";

import * as pako from "pako";
import protobuf from "protobufjs";
import chalk from "chalk";
import * as Os from "node:os";
import * as path from "node:path";

const ProtoMovieEntity = protobuf.Root
  .fromJSON(SvgaDescriptor)
  .lookupType('com.opensource.svga.MovieEntity');


/**
 * 压缩Svga
 * @author haiyoucuv
 * @param {string}svga
 * @return {Promise<boolean|ArrayBuffer>}
 */
export async function compressSvga(svga: string): Promise<Uint8Array> {
  try {

    const buffer = await fs.readFile(svga);

    // 解析svga
    const data = ProtoMovieEntity.decode(pako.inflate(buffer)).toJSON();

    const {images} = data;

    let tempDir = svga.replace(/\.svga/, '') + "__temp__/";

    // if (Os.platform() == "win32") {
    //   const now = Date.now();
    //   tempDir = `C:\\Temp\\duiba\\${now}`
    //
    //   if (!fs.existsSync("C:\\Temp")) fs.mkdirSync("C:\\Temp");
    //   if (!fs.existsSync("C:\\Temp\\duiba")) fs.mkdirSync("C:\\Temp\\duiba");
    //   if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir);
    // }

    await fs.mkdir(tempDir);
    const ps1 = Object.keys(images).map(async (name) => {
      const path = `${tempDir}${name}.png`;
      await fs.writeFile(path, Buffer.from(images[name], 'base64'));
      return path;
    });

    // 保存图片
    const imgPaths = await Promise.all(ps1);

    // 压缩图片
    await compressAllImage(imgPaths);

    // 读取图片，还原到data
    const ps2 = Object.keys(images).map(async (name) => {
      const path = `${tempDir}${name}.png`;
      const buffer = await fs.readFile(path);
      data.images[name] = buffer.toString('base64');
    });

    await Promise.all(ps2);

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

    // 压缩buffer
    return pako.deflate(ProtoMovieEntity.encode(data).finish());
  } catch (e) {
    console.log(e);
    return null;
  }
}

export async function compressAllSvga(
  paths = [],
  onProgress: (cur?: number, total?: number) => void = () => void 0,
) {


  for (let i = 0; i < paths.length; i++) {
    const svga = paths[i];
    const fileName = path.basename(svga);

    try {
      const sizePre = (await fs.stat(svga)).size;
      const result = await compressSvga(svga);
      if (result) {
        await fs.writeFile(svga, result);
        const sizeOp = (await fs.stat(svga)).size;
        const radio = ((1 - sizeOp / sizePre) * 100).toFixed(2);
        console.log(chalk.green("压缩Svga成功:" + fileName, `，压缩率：${radio}`));
      }
    } catch (e) {
      console.log(chalk.red("压缩Svga失败:" + fileName));
    }

    onProgress(i + 1, paths.length);
  }

  // let completed = 0;
  // const svgaPArr = paths.map((svga) => {
  //   return (async () => {
  //     const fileName = path.basename(svga);
  //     try {
  //       const sizePre = (await fs.stat(svga)).size;
  //       const result = await compressSvga(svga);
  //       if (result) {
  //         await fs.writeFile(svga, result);
  //         const sizeOp = (await fs.stat(svga)).size;
  //         const radio = ((1 - sizeOp / sizePre) * 100).toFixed(2);
  //         console.log(chalk.green("压缩Svga成功:" + fileName, `，压缩率：${radio}`));
  //       }
  //     } catch (e) {
  //       console.log(chalk.red("压缩Svga失败:" + fileName));
  //     }
  //
  //     onProgress(completed++, paths.length);
  //   })();
  // });
  //
  // await Promise.all(svgaPArr);
}
