import { ref } from "vue";

export type IconItem = {
  type: 'iconfont'|'image'|'svg'|'none',
  value: string,
  rawSvg?: string,
  fontFamily?: string,
};
type IconMap = Record<string, IconItem>;


//图标集
const iconMap = {} as IconMap;

export const IconUtils = {
  iconCount: ref(0),
  /**
   * 设置 Icon 组件的图标名称映射。
   * 如果已存在同名数据，则会覆盖之前的。
   *
   * key是图标的名字，value 可以是以下几种情况：
   * * 是一个 iconfont:name 字符，则会渲染为字体形式的图标，通过 : 分割，前面是字体名称，后面是图标名称。
   * * 是一个 `data:***` 或者 http/https URL，则会尝试使用 Image 渲染为图片
   * * 是一个 `&lt;svg` 开头的字符串，会渲染为 svg
   * * 否则，作为默认字体 iconfont 渲染为字体形式的图标。
   */
  configIconMap(map: Record<string, string>) {
    for (const key in map) {
      let result : IconItem;
      const v = map[key];
      if (v.startsWith('http') || v.startsWith('data:') || v.startsWith('/')) {
        result = {
          type: 'image',
          value: v,
        }
      } else if (v.startsWith('<svg') || v.includes('<svg')) {
        result = {
          type: 'svg',
          rawSvg: v,
          value: toDataSvg(v),
        }
      } else if (v.includes(':')) {
        const vv = v.split(':');
        result = {
          type: 'iconfont',
          value: vv[1],
          fontFamily: vv[0],
        }
      } else {
        result = {
          type: 'iconfont',
          value: v,
        }
      } 
      iconMap[key] = result;
    }
    this.iconCount.value = Object.keys(iconMap).length;
  },
  getColoredSvg(svg: string, color: string) {
    return toDataSvg(
      svg.includes('fill=') ? svg : svg.replace(/<path /g, `<path fill="${color}" `)
    );
  },
  /**
   * 获取图标名称映射集
   * @returns
   */
  getIconMap() {
    return iconMap;
  },
  /**
   * 从图标名称映射中获取指定名称的图标数据。
   * @param key 图标名称
   * @returns 返回图标数据，如果找不到，返回 undefined。
   */
  getIconDataFromMap(key: string) {
    return iconMap[key];
  },
  /**
   * 加载默认图标。可选从本地或者网络加载。
   * @param urlOrJson 图标URL或者JSON字符串
   */
  loadDefaultIcons(urlOrJson: string | Record<string, string>) {
    if (typeof urlOrJson === 'object') {
      this.configIconMap(urlOrJson);
      return;
    }
    if (urlOrJson.startsWith('http') || urlOrJson.startsWith('https')) {
      uni.request({
        url: urlOrJson,
        method: 'GET',
        success: (res) => {
          this.configIconMap(typeof res.data === 'string' ? JSON.parse(res.data) : res.data);
        },
        fail: (err) => {
          console.error('加载默认图标失败', err);
        },
      });
    } else {
      this.configIconMap(JSON.parse(urlOrJson));
    }
  },
}

function toDataSvg(str: string) {
  if (!str.includes('xmlns'))
    str = str.replace("<svg ", "<svg xmlns='http://www.w3.org/2000/svg' ");
  return `data:image/svg+xml,${encodeURIComponent(str.replace(/\'/g, '"'))}`.replace(/\#/g, '%23');
}
