import { reactive } from "vue";

let imageCache: Record<string, Promise<HTMLImageElement>>;
export let imageInfo: Record<string, Record<'width' | 'height', number>> = reactive({})
export let getImage = (url: string): Promise<HTMLImageElement> => {
  imageCache = {};
  getImage = (url: string) => {
    if (url in imageCache) {
      return imageCache[url];
    } else {
      return (imageCache[url] = new Promise((resolve, reject) => {
        const image = new Image();
        image.onload = () => {
          resolve(image);
					imageInfo[url] = {
						width: image.width,
						height: image.height
					}
        };
        image.onerror = (e) => {
          reject(e);
        };
        image.src = url;
      }));
    }
  };
  return getImage(url);
};

export const isSvgString = (str: string) => {
  // 检查字符串是否以 <svg> 标签开头
  const svgRegex = /^<svg[^>]*>.*<\/svg>$/is;
  return svgRegex.test(str);
}

let svgContentCache: Record<string, Promise<string>>;
export let getSvgContent = (url: string): Promise<string> => {
  svgContentCache = {};
  getSvgContent = async (url: string) => {
    if (isSvgString(url)) {
      return url;
    }
    if (url in svgContentCache) {
      return svgContentCache[url];
    } else {

      const res = await fetch(url);
      return (svgContentCache[url] = res.text());
    }
  };
  return getSvgContent(url);
};

export type SVGPath = {
  fill?: string;
  stroke?: string;
  strokeWidth?: number;
  data: string;
};
export type SVGParseResult = {
  paths: SVGPath[];
  width: number;
  height: number;
  x: number;
  y: number;
};
let svgParseCache: Record<string, SVGParseResult>;
let helpDOM: HTMLDivElement;
export let parseSvgContent = (svgContent: string): SVGParseResult => {
  svgParseCache = {};
  helpDOM = document.createElement("div");
  helpDOM.style.position = "absolute";
  helpDOM.style.left = "-99999px";
  helpDOM.style.top = "-99999px";

  parseSvgContent = (svgContent: string) => {
    if (svgContent in svgParseCache) return svgParseCache[svgContent];
    helpDOM.innerHTML = svgContent;
    document.body.appendChild(helpDOM);

    let width = 0;
    let height = 0;
    let x = Number.MAX_VALUE;
    let y = Number.MAX_VALUE;
    const svgPaths = Array.from(helpDOM.querySelectorAll("path"));
    const paths = svgPaths.map((path) => {
      const box = path.getBBox();
      x = Math.min(box.x, x);
      y = Math.min(box.y, y);
      width = Math.max(width, box.width);
      height = Math.max(height, box.height);

      const fill = path.getAttribute("fill")!;
      const data = path.getAttribute("d")!;
      const stroke = path.getAttribute("stroke")!;
      const strokeWidth = path.getAttribute("stroke-width")!;
      return {
        fill,
        data,
        stroke,
        strokeWidth: (strokeWidth && Number(strokeWidth)) || 1,
      };
    });

    helpDOM.innerHTML = "";
    document.body.removeChild(helpDOM);
    return (svgParseCache[svgContent] = { paths, width, height, x, y });
  };
  return parseSvgContent(svgContent);
};
