<template>
  <div class="app-header">
    <a class="logo" href="https://le5le.com" target="_blank">
      <img src="/favicon.ico" />
      <span>乐吾乐</span>
    </a>
    <t-dropdown
      :minColumnWidth="200"
      :maxHeight="560"
      :delay2="[10, 150]"
      overlayClassName="header-dropdown"
    >
      <a> 文件 </a>
      <t-dropdown-menu>
        <t-dropdown-item @click="newFile">
          <a>新建文件</a>
        </t-dropdown-item>
        <t-dropdown-item @click="openFile">
          <a>打开文件</a>
        </t-dropdown-item>
        <t-dropdown-item divider="true" @click="loadFile">
          <a>导入文件</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="save()">保存</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="save(SaveType.SaveAs)">另保存</a>
        </t-dropdown-item>
        <t-dropdown-item divider="true">
          <a @click="downloadJson">下载JSON文件</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="downloadZip">
            <div class="flex">
              导出为ZIP文件 <span class="flex-grow"></span>
              <span><label>VIP</label></span>
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="downloadHtml">
            <div class="flex">
              导出为HTML <span class="flex-grow"></span>
              <span><label>VIP</label></span>
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="downloadVue3">
            <div class="flex">
              导出为Vue3组件 <span class="flex-grow"></span>
              <span><label>VIP</label></span>
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="downloadVue2">
            <div class="flex">
              导出为Vue2组件 <span class="flex-grow"></span>
              <span><label>VIP</label></span>
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item divider="true">
          <a @click="downloadReact">
            <div class="flex">
              导出为React组件 <span class="flex-grow"></span>
              <span><label>VIP</label></span>
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="downloadPng">下载为PNG</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="downloadSvg">下载为SVG</a>
        </t-dropdown-item>
      </t-dropdown-menu>
    </t-dropdown>
    <t-dropdown
      :minColumnWidth="180"
      :maxHeight="500"
      :delay2="[10, 150]"
      overlayClassName="header-dropdown"
    >
      <a> 编辑 </a>
      <t-dropdown-menu>
        <t-dropdown-item>
          <a @click="onUndo">
            <div class="flex">
              撤销 <span class="flex-grow"></span> Ctrl + Z
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item divider="true">
          <a @click="onRedo">
            <div class="flex">
              恢复 <span class="flex-grow"></span> Ctrl + Y
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onCut">
            <div class="flex">
              剪切 <span class="flex-grow"></span> Ctrl + X
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onCopy">
            <div class="flex">
              复制 <span class="flex-grow"></span> Ctrl + C
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item divider="true">
          <a @click="onPaste">
            <div class="flex">
              粘贴 <span class="flex-grow"></span> Ctrl + V
            </div>
          </a>
        </t-dropdown-item>
        <!-- <t-dropdown-item>
          <a @click="onAddAnchorHand">
            <div class="flex">添加手柄 <span class="flex-grow"></span> H</div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onRemoveAnchorHand">
            <div class="flex">删除手柄 <span class="flex-grow"></span> D</div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onToggleAnchorHand">
            <div class="flex">
              切换手柄 <span class="flex-grow"></span> Shift
            </div>
          </a>
        </t-dropdown-item> -->
      </t-dropdown-menu>
    </t-dropdown>
    <t-dropdown
      :minColumnWidth="180"
      :maxHeight="500"
      :delay2="[10, 150]"
      overlayClassName="header-dropdown"
    >
      <a> 工具 </a>
      <t-dropdown-menu>
        <t-dropdown-item>
          <a @click="onScaleWindow">窗口大小</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onScaleUp">放大</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onScaleDown">缩小</a>
        </t-dropdown-item>
        <t-dropdown-item divider="true">
          <a @click="onScaleView">100%视图</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="showMap">
            <div class="flex middle">
              鹰眼地图 <span class="flex-grow"></span>
              <t-icon v-show="map" name="check" />
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item divider="true">
          <a @click="showMagnifier">
            <div class="flex middle">
              放大镜 <span class="flex-grow"></span>
              <t-icon v-show="magnifier" name="check" />
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onAutoAnchor">
            <div class="flex middle">
              自动锚点 <span class="flex-grow"></span>
              <t-icon v-show="autoAnchor" name="check" />
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item divider="true">
          <a @click="onDisableAnchor">
            <div class="flex middle">
              显示锚点 <span class="flex-grow"></span>
              <t-icon v-show="showAnchor" name="check" />
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="onToggleAnchor">
            <div class="flex"  :style="{
              color:showAnchor?'':'#4f5b75'}
              ">
              添加/删除锚点 <span class="flex-grow"></span> A
            </div>
          </a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="switchTheme('light')">明亮主题</a>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="switchTheme('dark')">暗黑主题</a>
        </t-dropdown-item>
      </t-dropdown-menu>
    </t-dropdown>
    <t-dropdown
      :minColumnWidth="180"
      :maxHeight="500"
      :delay2="[10, 150]"
      overlayClassName="header-dropdown"
    >
      <a> 帮助 </a>
      <t-dropdown-menu>
        <t-dropdown-item v-for="item in helpList" :divider="item.divider">
          <a :href="item.url" :target="item.target">{{ item.name }}</a>
        </t-dropdown-item>
      </t-dropdown-menu>
    </t-dropdown>
    <input v-model="data.name" @input="inputMeta2dName" />

    <div style="width: 290px; flex-shrink: 0"></div>
    <t-dropdown
      v-if="user.id"
      :minColumnWidth="200"
      :maxHeight="500"
      :delay2="[10, 150]"
      overlayClassName="custom-dropdown header"
    >
      <a style="margin-left: 32px; margin-right: 0">
        <t-avatar
          size="small"
          :image="user.avatarUrl ? user.avatarUrl : baseUrl + 'img/avatar.png'"
        />
      </a>
      <t-dropdown-menu>
        <t-dropdown-item>
          <router-link to="/account/info">
            {{ user.username }}
          </router-link>
        </t-dropdown-item>
        <t-dropdown-item>
          <router-link to="/account/info">我的图纸</router-link>
        </t-dropdown-item>
        <t-dropdown-item>
          <router-link to="/account/teams">我的团队</router-link>
        </t-dropdown-item>
        <t-dropdown-item>
          <router-link to="/account/info">账号信息</router-link>
        </t-dropdown-item>
        <t-dropdown-item :divider="true">
          <router-link to="/account/security"> 安全设置 </router-link>
        </t-dropdown-item>
        <t-dropdown-item>
          <a @click="signout">退出</a>
        </t-dropdown-item>
      </t-dropdown-menu>
    </t-dropdown>
    <div class="flex middle" v-else>
      <a class="button primary solid" style="width: 80px" :href="login()"
        >登录</a
      >
    </div>
  </div>
</template>

<script lang="ts" setup>
import { reactive, ref, onMounted, onUnmounted, nextTick } from "vue";
import { useRouter, useRoute } from "vue-router";
import { useUser } from "@/services/user";
import { NotifyPlugin, MessagePlugin } from "tdesign-vue-next";
import {
  showNotification,
  Meta2dBackData,
  dealwithFormatbeforeOpen,
  gotoAccount,
  checkData,
} from "@/services/utils";
import { readFile, upload, dataURLtoBlob } from "@/services/file";
import { compareVersion, baseVer, upgrade } from "@/services/upgrade";
import { parseSvg } from "@meta2d/svg";
import { Pen, Rect, getGlobalColor, isShowChild } from "@meta2d/core";
import localforage from "localforage";
import {
  delImage,
  getFolders,
  addCollection,
  updateCollection,
  updateFolders,
  cdn,
  upCdn,
} from "@/services/api";
import JSZip from "jszip";
import axios from "axios";
import { switchTheme } from "@/services/theme";
import { noLoginTip, localMeta2dDataName } from "@/services/utils";
import { useDot, notificFn } from "@/services/common";
import {
  save,
  newFile,
  SaveType,
  onScaleView,
  onScaleWindow,
  showMagnifier,
  showMap,
  newfile,
  title,
  drawPen,
  map,
  magnifier
} from "@/services/common";

const router = useRouter();
const route = useRoute();

const market = import.meta.env.VITE_MARKET;
const baseUrl = import.meta.env.BASE_URL || "/";

const { user, message, getUser, getMessage, signout } = useUser();
const { dot } = useDot();
const data = reactive({
  name: "空白文件",
});

const inputMeta2dName = () => {
  (meta2d.store.data as Meta2dBackData).name = data.name;
};

const initMeta2dName = () => {
  data.name = (meta2d.store.data as Meta2dBackData).name || "";
};

nextTick(() => {
  meta2d.on("opened", initMeta2dName);
});

onUnmounted(() => {
  meta2d.off("opened", initMeta2dName);
});

function login() {
  //TODO 临时地址
  return `https://account.le5le.com/?cb=${encodeURIComponent(location.href)}`;
  // if (market) {
  //       return `/account/login?cb=${encodeURIComponent(location.href)}`;
  //     } else {
  //       let arr = location.host.split('.');
  //       arr[0] = 'http://account';
  //       let accountUrl = arr.join('.');
  //       return `${
  //         loginUrl ? loginUrl : accountUrl
  //       }?cb=${encodeURIComponent(location.href)}`;
  //     }
}

function load(newT: boolean = false) {
  const input = document.createElement("input");
  input.type = "file";
  input.onchange = (event) => {
    const elem = event.target as HTMLInputElement;
    if (elem.files && elem.files[0]) {
      newT && newfile(true);
      // 路由跳转 可能在 openFile 后执行
      if (elem.files[0].name.endsWith(".json")) {
        openJson(elem.files[0], newT);
      } else if (elem.files[0].name.endsWith(".svg")) {
        MessagePlugin.info(
          "可二次编辑但转换存在损失，若作为图片使用，请使用右侧属性面板的上传图片功能"
        );
        openSvg(elem.files[0]);
      } else if (elem.files[0].name.endsWith(".zip")) {
        openZip(elem.files[0], newT);
      } else {
        MessagePlugin.info("打开文件只支持 json，svg，zip 格式");
      }
    }
  };
  input.click();
}

const openJson = async (file: File, isNew: boolean = false) => {
  const text = await readFile(file);
  try {
    let data: Meta2dBackData = JSON.parse(text);
    if (!data.name) {
      data.name = file.name.replace(".json", "");
    }
    if (!data.version || compareVersion(data.version, baseVer) === -1) {
      // 如果版本号不存在或者版本号 version < 1.0.0
      data = upgrade(data, baseVer);
    }
    dealwithFormatbeforeOpen(data);
    data._id = undefined;
    if (!isNew) {
      delete data.owner;
      delete data.editor;
      delete data.username;
      delete data.editorId;
      delete data.editorName;
    }
    // if (!(window as any).meta2dFolder?.includes(data.folder)) {
    //   delete data.folder;
    // }
    meta2d.open(data);
  } catch (e) {
    console.log(e);
  }
};

const openSvg = async (file: File) => {
  const text = await readFile(file);
  const pens: Pen[] = parseSvg(text);
  meta2d.canvas.addCaches = pens;
  MessagePlugin.info("svg转换成功，请点击画布决定放置位置");
};

const openZip = async (file: File, isNew: boolean = false) => {
  if (!(user && user.id)) {
    MessagePlugin.warning(noLoginTip);
    return;
  }

  if (!user.vipExpired) {
    // vipVisible.value = true;
    gotoAccount();
    return;
  }

  const { default: JSZip } = await import("jszip");
  const zip = new JSZip();
  await zip.loadAsync(file);

  let dataStr = "";
  for (const key in zip.files) {
    if (zip.files[key].dir) {
      continue;
    }
    if (key.endsWith(".json")) {
      // 认为只有一个 json 文件
      // dataStr = await zip.file(key).async('string');
      break;
    }
  }

  if (!dataStr) {
    return false;
  }

  for (const key in zip.files) {
    if (zip.files[key].dir) {
      continue;
    }
    // let _png = key.indexOf('/png');
    // let _img = key.indexOf('/img');
    // let _image = key.indexOf('/image');
    // let _file = key.indexOf('/file');
    let _keyLower = key.toLowerCase();
    // if (!key.endsWith('.json') && (_png !== -1 || _img !== -1 || _image !== -1 || _file !== -1)) {
    if (
      _keyLower.endsWith(".png") ||
      _keyLower.endsWith(".svg") ||
      _keyLower.endsWith(".gif") ||
      _keyLower.endsWith(".jpg") ||
      _keyLower.endsWith(".jpeg")
    ) {
      let filename = key.substr(key.lastIndexOf("/") + 1);
      const extPos = filename.lastIndexOf(".");
      let ext = "";
      if (extPos > 0) {
        ext = filename.substr(extPos);
      }
      filename = filename.substring(0, extPos > 8 ? 8 : extPos);

      // 上传文件
      const result: any = {};
      //   await upload(
      //   // await zip.file(key).async('blob'),
      //   true,
      //   filename + ext,
      //   "/2D/未分类"
      // );
      let _key = key;
      // if (_png) {
      //   _key = key.substring(_png);
      // } else if (_image) {
      //   _key = key.substring(_png);
      // } else if (_img) {
      //   _key = key.substring(_img);
      // } else if (_file) {
      //   _key = key.substring(_file);
      // }
      if (result) {
        if (dataStr.replaceAll) {
          //'le5le.meta2d'
          dataStr = dataStr.replaceAll(_key.slice(12), result.url);
        } else {
          while (dataStr.includes(_key)) {
            dataStr = dataStr.replace(_key.slice(12), result.url);
            // 正则 gm 在特殊情况下报错，例如如下场景
            /**
                 *    
      const data = '{"image":"/image/materials/IoT-Chemical(化学)/Air stripper 2(汽提塔2).svg"}';
      const key = '/image/materials/IoT-Chemical(化学)/Air stripper 2(汽提塔2).svg';
      data.replace(key, '123');
      data.replaceAll(key, '123')
      data.replace(new RegExp(key, 'gm'), '123');
      data.replace(new RegExp(key, 'g'), '123');
                 */
          }
        }
      }
    }
  }

  try {
    let data: Meta2dBackData = JSON.parse(dataStr);
    if (data) {
      if (!data.name) {
        data.name = file.name.replace(".zip", "");
      }
      if (!data.version || compareVersion(data.version, baseVer) === -1) {
        // 如果版本号不存在或者版本号 version < 1.0.0
        data = upgrade(data, baseVer);
      }
      dealwithFormatbeforeOpen(data);
      data._id = undefined;
      if (!isNew) {
        delete data.owner;
        delete data.editor;
        delete data.username;
        delete data.editorId;
        delete data.editorName;
      }
      if (!(window as any).meta2dFolder?.includes(data.folder)) {
        delete data.folder;
      }
      meta2d.open(data);
    }
  } catch (e) {
    return false;
  }
};

async function loadFile(newT: boolean = false) {
  // if (dot.value) {
  //   if (await showNotification(title)) {
  //     load(newT);
  //   }
  // } else {
  //   load(newT);
  // }
  //默认 导入新建项目
  notificFn(load, newT);
}

async function openFile() {
  loadFile(true);
}

const downloadJson = () => {
  const data: Meta2dBackData = meta2d.data();
  if (data._id) delete data._id;
  checkData(data);
  import("file-saver").then(({ saveAs }) => {
    saveAs(
      new Blob(
        [JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")],
        {
          type: "text/plain;charset=utf-8",
        }
      ),
      `${data.name || "le5le.meta2d"}.json`
    );
  });
};

const downloadZip = async () => {
  if (!(user && user.id)) {
    MessagePlugin.warning(noLoginTip);
    return;
  }

  if (!user.vipExpired) {
    gotoAccount();
    return;
  }

  MessagePlugin.info("正在下载打包中，可能需要几分钟，请耐心等待...");
  const [{ default: JSZip }, { saveAs }] = await Promise.all([
    import("jszip"),
    import("file-saver"),
  ]);

  const zip: any = new JSZip();
  const data: Meta2dBackData = meta2d.data();
  let _fileName =
    (data.name && data.name.replace(/\//g, "_").replace(/:/g, "_")) ||
    "le5le.meta2d";
  const _zip = zip.folder(`${_fileName}`);
  if (data._id) delete data._id;
  checkData(data);
  _zip.file(
    `${_fileName}.json`,
    JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")
  );
  await zipImages(_zip, meta2d.store.data.pens);

  const blob = await zip.generateAsync({ type: "blob" });
  saveAs(blob, `${_fileName}.zip`);
};

const downloadHtml = async () => {
  if (!(user && user.id)) {
    MessagePlugin.warning(noLoginTip);
    return;
  }

  if (!user.vipExpired) {
    gotoAccount();
    return;
  }

  MessagePlugin.info("正在下载打包中，可能需要几分钟，请耐心等待...");

  const data: Meta2dBackData = meta2d.data();
  if (data._id) delete data._id;
  checkData(data);
  const [{ default: JSZip }, { saveAs }] = await Promise.all([
    import("jszip"),
    import("file-saver"),
  ]);
  const zip = new JSZip();
  let _fileName =
    (data.name && data.name.replace(/\//g, "_").replace(/:/g, "_")) ||
    "le5le.meta2d";

  //处理cdn图片地址
  const _zip: any = zip.folder(`${_fileName}`);
  _zip.file(
    "data.json",
    JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")
  );
  await Promise.all([zipImages(_zip, meta2d.store.data.pens), zipFiles(_zip)]);
  const blob = await zip.generateAsync({ type: "blob" });
  saveAs(blob, `${_fileName}.zip`);
};

enum Frame {
  vue2,
  vue3,
  react,
}

const downloadVue3 = async () => {
  downloadAsFrame(Frame.vue3);
};

const downloadVue2 = async () => {
  downloadAsFrame(Frame.vue2);
};

const downloadReact = async () => {
  downloadAsFrame(Frame.react);
};

async function downloadAsFrame(type: Frame) {
  if (!(user && user.id)) {
    MessagePlugin.warning(noLoginTip);
    return;
  }

  if (!user.vipExpired) {
    gotoAccount();
    return;
  }

  MessagePlugin.info("正在下载打包中，可能需要几分钟，请耐心等待...");

  const data: Meta2dBackData = meta2d.data();
  if (data._id) delete data._id;
  checkData(data);
  const [{ default: JSZip }, { saveAs }] = await Promise.all([
    import("jszip"),
    import("file-saver"),
  ]);
  const zip = new JSZip();
  let _fileName =
    (data.name && data.name.replace(/\//g, "_").replace(/:/g, "_")) ||
    "le5le.meta2d";
  const _zip: any = zip.folder(`${_fileName}`);
  _zip.file(
    "data.json",
    JSON.stringify(data).replaceAll(cdn, "").replaceAll(upCdn, "")
  );
  await Promise.all([
    zipImages(_zip, meta2d.store.data.pens),
    type === Frame.vue3
      ? zipVue3Files(_zip)
      : type === Frame.vue2
      ? zipVue2Files(_zip)
      : zipReactFiles(_zip),
  ]);
  const blob = await zip.generateAsync({ type: "blob" });
  saveAs(blob, `${_fileName}.zip`);
}

async function zipVue3Files(zip: JSZip) {
  const files = [
    "/view/js/marked.min.js",
    "/view/js/lcjs.iife.js",
    "/view/vue3/Meta2d.vue",
    "/view/index.html",
    "/view/js/meta2d.js",
    "/view/使用说明.md",
  ] as const;
  // 文件同时加载
  await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
}

async function zipVue2Files(zip: JSZip) {
  const files = [
    "/view/js/marked.min.js",
    "/view/js/lcjs.iife.js",
    "/view/vue2/Meta2d.vue",
    "/view/index.html",
    "/view/js/meta2d.js",
    "/view/使用说明.md",
  ] as const;
  // 文件同时加载
  await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
}

async function zipReactFiles(zip: JSZip) {
  const files = [
    "/view/js/marked.min.js",
    "/view/js/lcjs.iife.js",
    "/view/react/Meta2d.jsx",
    "/view/react/Meta2d.css",
    "/view/index.html",
    "/view/js/meta2d.js",
    "/view/使用说明.md",
  ] as const;
  // 文件同时加载
  await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
}

async function zipFiles(zip: JSZip) {
  const files = [
    "/view/js/marked.min.js",
    "/view/js/lcjs.iife.js",
    "/view/js/index.js",
    "/view/js/meta2d.js",
    "/view/index.html",
    "/view/index.css",
    "/view/favicon.ico",
    "/view/使用说明.pdf",
  ] as const;
  // 文件同时加载
  await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
}

async function zipFile(zip: JSZip, filePath: string) {
  const res: Blob = await axios.get(cdn + "/2d" + filePath, {
    responseType: "blob",
  });
  zip.file(filePath.replace("/view", ""), res, { createFolders: true });
}

/**
 * 图片放到 zip 里
 * @param pens 可以是非具有 calculative 的 pen
 */
async function zipImages(zip: JSZip, pens: Pen[]) {
  if (!pens) {
    return;
  }

  // 不止 image 上有图片， strokeImage ，backgroundImage 也有图片
  const imageKeys = [
    {
      string: "image",
    },
    { string: "strokeImage" },
    { string: "backgroundImage" },
  ] as const;
  const images: string[] = [];
  for (const pen of pens) {
    for (const i of imageKeys) {
      const image = pen[i.string];
      if (image) {
        // HTMLImageElement 无法精确控制图片格式
        if (
          image.startsWith("/") ||
          image.startsWith(cdn) ||
          image.startsWith(upCdn)
        ) {
          // 只考虑相对路径下的 image ，绝对路径图片无需下载
          if (!images.includes(image)) {
            images.push(image);
          }
        }
      }
    }
    // 无需递归遍历子节点，现在所有的节点都在外层
  }
  await Promise.all(images.map((image) => zipImage(zip, image)));
}

async function zipImage(zip: JSZip, image: string) {
  const res: Blob = await axios.get(image, {
    responseType: "blob",
    params: {
      isZip: true,
    },
  });
  zip.file(cdn ? image.replace(cdn, "").replace(upCdn, "") : image, res, {
    createFolders: true,
  });
}

const downloadImageTips =
  "无法下载，宽度不合法，画布可能没有画笔/画布大小超出浏览器最大限制";

const downloadPng = () => {
  const name = (meta2d.store.data as Meta2dBackData).name;
  try {
    meta2d.downloadPng(name ? name + ".png" : undefined);
  } catch (e) {
    MessagePlugin.warning(downloadImageTips);
  }
};

async function getIconDefs(url: string) {
  let res: any = await axios.get(url);
  let str = res.match(/@font-face([\s\S]*?)\}/)[1];
  str = `@font-face ${str} }`;
  return str;
}

const downloadSvg = async () => {
  await import("@/assets/canvas2svg");
  if (!C2S) {
    MessagePlugin.error("请先加载乐吾乐官网下的canvas2svg.js");
    return;
  }

  const rect: any = meta2d.getRect();
  if (!isFinite(rect.width)) {
    MessagePlugin.error(downloadImageTips);
    return;
  }
  rect.x -= 10;
  rect.y -= 10;
  const ctx = new C2S(rect.width + 20, rect.height + 20);
  ctx.textBaseline = "middle";
  ctx.strokeStyle = getGlobalColor(meta2d.store);
  for (const pen of meta2d.store.data.pens) {
    // 不使用 calculative.inView 的原因是，如果 pen 在 view 之外，那么它的 calculative.inView 为 false，但是它的绘制还是需要的
    if (!isShowChild(pen, meta2d.store) || pen.visible == false) {
      continue;
    }
    meta2d.renderPenRaw(ctx, pen, rect);
  }

  let mySerializedSVG = ctx.getSerializedSvg();
  let icon_pens = meta2d.store.data.pens.filter(
    (item) => item.iconFamily && item.icon
  );
  if (icon_pens && icon_pens.length > 0) {
    let iconList = [
      "/icon/国家电网/iconfont.css",
      "/icon/电气工程/iconfont.css",
      "/icon/通用图标/iconfont.css",
    ];
    let defsList: any = await Promise.all(
      iconList.map((item) => getIconDefs(item))
    );
    mySerializedSVG = mySerializedSVG.replace(
      "<defs/>",
      `<defs>
    <style type="text/css">
${defsList.join("\n")}
</style>
{{bk}}
  </defs>
{{bkRect}}`
    );
  }
  /*  mySerializedSVG = mySerializedSVG.replace(
        '<defs/>',
        `<defs>
    <style type="text/css">
  @font-face {
    font-family: 'ticon';
    src: url('icon/通用图标/iconfont.ttf') format('truetype');
  }
</style>
{{bk}}
  </defs>
{{bkRect}}`
      );
*/
  if (meta2d.store.data.background) {
    mySerializedSVG = mySerializedSVG.replace("{{bk}}", "");
    mySerializedSVG = mySerializedSVG.replace(
      "{{bkRect}}",
      `<rect x="0" y="0" width="100%" height="100%" fill="${meta2d.store.data.background}"></rect>`
    );
  } else {
    mySerializedSVG = mySerializedSVG.replace("{{bk}}", "");
    mySerializedSVG = mySerializedSVG.replace("{{bkRect}}", "");
  }

  mySerializedSVG = mySerializedSVG.replace(/--le5le--/g, "&#x");

  const urlObject: any = (window as any).URL || window;
  const export_blob = new Blob([mySerializedSVG]);
  const url = urlObject.createObjectURL(export_blob);

  const a = document.createElement("a");
  a.setAttribute(
    "download",
    `${(meta2d.store.data as Meta2dBackData).name || "le5le.meta2d"}.svg`
  );
  a.setAttribute("href", url);
  const evt = document.createEvent("MouseEvents");
  evt.initEvent("click", true, true);
  a.dispatchEvent(evt);
};

const onUndo = () => {
  meta2d.undo();
};

const onRedo = () => {
  meta2d.redo();
};

const onCut = () => {
  meta2d.cut();
};

const onCopy = () => {
  meta2d.copy();
};

const onPaste = () => {
  meta2d.paste();
};

const onToggleAnchor = () => {
  //取消连线状态
  // meta2d.store.options.disableAnchor = false;
  if (!meta2d.store.options.disableAnchor) {
    meta2d.canvas.drawingLineName && drawPen();
    meta2d.toggleAnchorMode();
  }
};

const onAddAnchorHand = () => {
  meta2d.addAnchorHand();
};

const onRemoveAnchorHand = () => {
  meta2d.removeAnchorHand();
};

const onToggleAnchorHand = () => {
  meta2d.toggleAnchorHand();
};

const onScaleUp = () => {
  const _scale = meta2d.store.data.scale + 0.1;
  meta2d.scale(_scale);
};

const onScaleDown = () => {
  const _scale = meta2d.store.data.scale - 0.1;
  meta2d.scale(_scale);
};

const autoAnchor = ref(true);
const onAutoAnchor = () => {
  meta2d.store.options.autoAnchor = !meta2d.store.options.autoAnchor;
  autoAnchor.value = meta2d.store.options.autoAnchor;
};

const showAnchor = ref(false);
const onDisableAnchor = () => {
  meta2d.store.options.disableAnchor = !meta2d.store.options.disableAnchor;
  changeDisableAnchor();
};

const changeDisableAnchor = () => {
  const { disableAnchor, autoAnchor } =
    meta2d.store.options;
    showAnchor.value = (!disableAnchor) || false;
  if (disableAnchor && autoAnchor) {
    // 禁用瞄点开了，需要关闭自动瞄点
    onAutoAnchor();
  }
};


const helpList = [
  {
    name: "产品介绍",
    url: "https://doc.le5le.com/document/118756411",
    target: "_blank",
  },
  {
    name: "快速上手",
    url: "https://doc.le5le.com/document/119363000",
    target: "_blank",
  },
  {
    name: "使用手册",
    url: "https://doc.le5le.com/document/118764244",
    target: "_blank",
  },
  {
    name: "快捷键",
    url: "https://doc.le5le.com/document/119620214",
    target: "_blank",
    divider: true,
  },
  {
    name: "企业服务与支持",
    url: "https://doc.le5le.com/document/119296274",
    target: "_blank",
    divider: true,
  },
  {
    name: "关于我们",
    url: "https://le5le.com/about.html",
    target: "_blank",
  },
];
</script>
<style lang="postcss" scoped>
.app-header {
  display: flex;
  height: 40px;

  .logo {
    display: flex;
    padding: 0 16px;
    align-items: center;
    font-size: 14px;
    font-weight: 500;

    img {
      height: 20px;
      margin-right: 6px;
    }
  }

  a {
    display: flex;
    padding: 0 8px;
    margin: 0 8px;
    align-items: center;
    color: var(--color);
    text-decoration: none;

    &:hover {
      color: var(--color-primary);
    }
  }

  input {
    font-size: var(--font-size);
    flex-grow: 1;
    background: none;
    outline: none;
    border: none;
    text-align: center;
    color: var(--color-title);
  }
}
</style>
