// import { getTimeoutPromise } from './promise.util'

// 创建 SVG 元素
export const createSvgElement = (attr?: Record<string, string | number>) => {
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
  svg.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");

  if (attr) {
    Object.keys(attr).forEach(key => {
      svg.setAttribute(key, `${attr[key]}`);
    });
  }

  return svg;
};

// 创建隐藏元素并挂载到容器上
export const createHiddenWrapper = (tagName: string, wrapper: HTMLElement) => {
  const hiddenWrapper = document.createElement(tagName);
  hiddenWrapper.style.position = "absolute";
  hiddenWrapper.style.top = "-10000px";
  hiddenWrapper.style.left = "-10000px";
  hiddenWrapper.style.width = "1px";
  hiddenWrapper.style.height = "1px";
  hiddenWrapper.style.overflow = "hidden";

  wrapper.appendChild(hiddenWrapper);
  return hiddenWrapper;
};

// 创建有形容器元素并挂载到容器上
export const createStyleWrapper = (
  tagName: string,
  wrapper: HTMLElement,
  options: Record<string, string>
) => {
  const hiddenWrapper = document.createElement(tagName);
  Object.keys(options).forEach(key => {
    hiddenWrapper.setAttribute(key, options[key]);
  });

  wrapper.appendChild(hiddenWrapper);
  return hiddenWrapper;
};

// 使用容器大小更新模版元素大小
export const updateElementSizeWithWrapper = (element: SVGElement, wrapper: HTMLElement) => {
  const { width, height } = wrapper.getBoundingClientRect();
  element.setAttribute("width", `${width}`);
  element.setAttribute("height", `${height}`);
  element.style.width = `${width}px`;
  element.style.height = `${height}px`;
};

// 转换字符串编码到 base64
export const base64EncodeUnicode = (str: string) => {
  // 创建一个TextEncoder实例
  const encoder = new TextEncoder();
  // 将字符串转换为UTF-8编码的Uint8Array
  const uint8Array = encoder.encode(str);
  // 将Uint8Array转换为字符字符串
  const binaryString = uint8Array.reduce((acc, byte) => acc + String.fromCharCode(byte), "");
  // 最后将该字符串进行Base64编码
  const base64Encoded = btoa(binaryString);

  return base64Encoded;
};

// SVG 元素转为 PNG DataURL
export const svgToPng = async (svg: SVGElement) => {
  const svgXML = new XMLSerializer().serializeToString(svg);
  // // 转换成blob数据
  const blob = new Blob([svgXML], {
    type: "image/svg+xml",
  });
  // 转换成data:url数据
  const svgUrl: any = await blobToUrl(blob);
  // // 绘制到canvas上
  const imgData: any = await drawToCanvas(svgUrl);
  // 下载
  downloadFile(imgData, "图片.png");

  // 2. 通过 Canvas 导出 base64
  // canvas 有报错..
  // 为SVG字符串创建Blob对象
  // const blob = new Blob([svgXML], { type: 'image/svg+xml;charset=utf-8' });
  // const url = URL.createObjectURL(blob); // 创建一个临时URL，指向Blob对象

  // const img = new Image();
  // img.crossOrigin = 'anonymous';
  // for test
  // document.body.append(img);
  // img.src = data64blob;
  // const { promise, resolve } = getTimeoutPromise<string, any>();

  // img.onerror = (e: any) => {
  //   console.error('load svg img error', e)
  //   resolve('');
  // };

  // img.onload = () => {
  //   const canvas = document.createElement('canvas');
  //   const ctx = canvas.getContext('2d');
  //   if (!ctx) {
  //     resolve('');
  //     return;
  //   }
  //   canvas.width = img.width;
  //   canvas.height = img.height;
  //   ctx.drawImage(img, 0, 0);
  //   const dataURL = canvas.toDataURL('image/png');
  //   resolve(dataURL);

  //   URL.revokeObjectURL(url)
  // };
  // img.src = url;
  // return promise;
};

export const blobToUrl = (blob: Blob) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (evt: any) => {
      resolve(evt.target.result);
    };
    reader.onerror = err => {
      reject(err);
    };
    reader.readAsDataURL(blob);
  });
};

export const drawToCanvas = (svgUrl: string) => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    // 跨域图片需要添加这个属性，否则画布被污染了无法导出图片
    img.setAttribute("crossOrigin", "anonymous");

    img.onload = async () => {
      try {
        const ratio = 2;
        const canvas: any = document.createElement("canvas");
        canvas.width = img.width * ratio;
        canvas.height = img.height * ratio;
        const ctx: CanvasRenderingContext2D = canvas.getContext("2d");
        ctx.fillStyle = "#fff"; // 背景
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img, 0, 0, img.width * ratio, img.height * ratio);
        ctx.scale(ratio, ratio);
        resolve(canvas.toDataURL());
      } catch (error) {
        console.error(error);
        throw error;
      }
    };
    img.onerror = e => {
      reject(e);
    };
    img.src = svgUrl;
  });
};

export const downloadFile = (file: string, fileName: string) => {
  const a = document.createElement("a");
  a.href = file;
  a.download = fileName;
  a.click();
};
