<template>
  <div class="meta2d">
    <div class="tools">
      <t-tooltip content="新建" placement="bottom">
        <a><t-icon name="add" @click="newFile" /></a>
      </t-tooltip>
      <t-tooltip content="保存" placement="bottom">
        <a>
          <t-badge dot :showZero="false" :count="dot ? 1 : 0">
            <t-icon name="save" @click="save(SaveType.Save)" /></t-badge
        ></a>
      </t-tooltip>
      <t-tooltip content="保存为我的组件" placement="bottom">
        <a><t-icon name="layers" @click="save(SaveType.Save, true)" /></a>
      </t-tooltip>
      <t-tooltip content="格式化（双击可连续使用）" placement="bottom">
        <a
          @click="oneFormat"
          @dblclick="alwaysFormat"
          :style="{
            color: one || always ? ' #1677ff' : '',
          }"
        >
          <svg
            width="1em"
            height="1em"
            viewBox="0 0 256 256"
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
          >
            <defs>
              <path id="77456364" d="M0 0h256v256H0z"></path>
            </defs>
            <g fill="none" fill-rule="evenodd">
              <mask id="3804093554b" fill="#fff">
                <use xlink:href="#77456364"></use>
              </mask>
              <path
                d="M213 77c0 14.36-11.64 26-26 26H69c-14.36 0-26-11.64-26-26V51c0-14.36 11.64-26 26-26h118c14.36 0 26 11.64 26 26v2h9.125c9.83 0 17.82 7.88 17.997 17.67l.003.33v50c0 9.83-7.88 17.82-17.67 17.997l-.33.003h-84.626v18H139c9.83 0 17.82 7.88 17.997 17.67l.003.33v35c0 16.016-12.984 29-29 29-15.856 0-28.74-12.725-28.996-28.52L99 210v-35c0-9.83 7.88-17.82 17.67-17.997L117 157h.499l.001-20c0-9.83 7.88-17.82 17.67-17.997l.33-.003h84.625V73H213Zm-76 100h-18v33a9 9 0 0 0 8.471 8.985l.264.011.265.004a9 9 0 0 0 8.996-8.735L137 210v-33Zm50-132H69a6 6 0 0 0-6 6v26a6 6 0 0 0 6 6h118a6 6 0 0 0 6-6V51a6 6 0 0 0-6-6Z"
                fill="currentColor"
                fill-rule="nonzero"
                mask="url(#3804093554b)"
              ></path>
            </g>
          </svg>
        </a>
      </t-tooltip>
      <t-tooltip content="清除格式" placement="bottom">
        <a @click="clearFormat">
          <svg
            width="1em"
            height="1em"
            viewBox="0 0 1024 1024"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              d="M889.186 384.07 677.671 172.56c-53.063-53.063-139.094-53.063-192.157 0L134.617 523.457c-53.063 53.063-53.063 139.099 0 192.158l170.196 170.2a41.354 41.354 0 0 0 29.243 12.11h215.001a41.354 41.354 0 0 0 29.184-12.05L889.155 576.26c53.094-53.09 53.094-139.126.031-192.19zM830.7 442.558c20.48 20.472 20.764 53.492.855 74.319l-.961.984-298.618 297.358H351.185l-158.09-158.086c-20.76-20.763-20.76-54.43 0-75.193l350.901-350.897c20.764-20.764 54.43-20.764 75.193 0l211.515 211.511z"
              fill="currentColor"
            ></path>
            <path
              d="m685.505 678.754-58.19 58.77-317.587-314.43 58.191-58.774zm197.55 136.508c23.46 0 42.483 18.514 42.483 41.353 0 22.45-18.38 40.724-41.294 41.338l-1.19.016h-454.6c-23.462 0-42.485-18.514-42.485-41.354 0-22.449 18.381-40.723 41.295-41.338l1.19-.015h454.6z"
              fill="currentColor"
            ></path>
          </svg>
        </a>
      </t-tooltip>
      <div class="flex-grow"></div>

      <t-tooltip content="直线" placement="bottom">
        <a
          :draggable="true"
          @dragstart="onAddShape($event, 'line')"
          @click.stop="onAddShape($event, 'line')"
          ><t-icon name="slash"
        /></a>
      </t-tooltip>
      <t-tooltip content="文字" placement="bottom">
        <a
          :draggable="true"
          @dragstart="onAddShape($event, 'text')"
          @click.stop="onAddShape($event, 'text')"
          >T</a
        >
      </t-tooltip>
      <t-tooltip content="连线（双击可连续使用）" placement="bottom">
        <a
          @click="oneDraw"
          @dblclick="alwaysDraw"
          :style="{
            color: oneD || alwaysD ? ' #1677ff' : '',
          }"
        >
          <svg
            width="1em"
            height="1em"
            viewBox="0 0 1024 1024"
            xmlns="http://www.w3.org/2000/svg"
          >
            <path
              d="M192 64a128 128 0 0 1 123.968 96H384a160 160 0 0 1 159.68 149.504L544 320v384a96 96 0 0 0 86.784 95.552L640 800h68.032a128 128 0 1 1 0 64.064L640 864a160 160 0 0 1-159.68-149.504L480 704V320a96 96 0 0 0-86.784-95.552L384 224l-68.032 0.064A128 128 0 1 1 192 64z m640 704a64 64 0 1 0 0 128 64 64 0 0 0 0-128zM192 128a64 64 0 1 0 0 128 64 64 0 0 0 0-128z"
              fill="currentColor"
            ></path>
          </svg>
        </a>
      </t-tooltip>
      <!-- <t-tooltip content="连线" placement="top"> -->
      <t-dropdown
        :minColumnWidth="200"
        :maxHeight="560"
        :delay2="[10, 150]"
        overlayClassName="header-dropdown"
      >
        <a>
          <svg class="l-icon" aria-hidden="true">
            <use
              :xlink:href="
                lineTypes.find((item) => item.value === currentLineType)?.icon
              "
            ></use>
          </svg>
        </a>
        <t-dropdown-menu>
          <t-dropdown-item v-for="item in lineTypes">
            <div class="flex middle" @click="changeLineType(item.value)">
              {{ item.name }} <span class="flex-grow"></span>
              <!-- <t-icon v-show="item.value === currentLineType" name="check" /> -->
              <svg class="l-icon" aria-hidden="true">
                <use :xlink:href="item.icon"></use>
              </svg>
            </div>
          </t-dropdown-item>
        </t-dropdown-menu>
      </t-dropdown>
      <t-dropdown
        :minColumnWidth="200"
        :maxHeight="560"
        :delay2="[10, 150]"
        overlayClassName="header-dropdown"
      >
        <a>
          <svg class="l-icon" aria-hidden="true">
            <use
              :xlink:href="
                fromArrows.find((item) => item.value === fromArrow)?.icon
              "
            ></use>
          </svg>
        </a>
        <t-dropdown-menu>
          <t-dropdown-item v-for="item in fromArrows">
            <div
              class="flex middle"
              style="height: 30px"
              @click="changeFromArrow(item.value)"
            >
              <svg class="l-icon" aria-hidden="true">
                <use :xlink:href="item.icon"></use>
              </svg>
            </div>
          </t-dropdown-item>
        </t-dropdown-menu>
      </t-dropdown>
      <t-dropdown
        :minColumnWidth="200"
        :maxHeight="560"
        :delay2="[10, 150]"
        overlayClassName="header-dropdown"
      >
        <a>
          <svg class="l-icon" aria-hidden="true">
            <use
              :xlink:href="
                toArrows.find((item) => item.value === toArrow)?.icon
              "
            ></use>
          </svg>
        </a>
        <t-dropdown-menu>
          <t-dropdown-item v-for="item in toArrows">
            <div
              class="flex middle"
              style="height: 30px"
              @click="changeToArrow(item.value)"
            >
              <svg class="l-icon" aria-hidden="true">
                <use :xlink:href="item.icon"></use>
              </svg>
            </div>
          </t-dropdown-item>
        </t-dropdown-menu>
      </t-dropdown>
      <!-- </t-tooltip> -->
      <t-tooltip content="视图大小" placement="bottom">
        <div style="line-height: 40px; margin-left: 8px">{{ scale }}%</div>
      </t-tooltip>

      <t-tooltip content="100%视图" placement="bottom">
        <a @click="onScaleView"><t-icon name="refresh" /></a>
      </t-tooltip>
      <t-tooltip content="窗口大小" placement="bottom">
        <a @click="onScaleWindow"><t-icon name="minus-rectangle" /></a>
      </t-tooltip>
      <t-tooltip content="数据源" placement="bottom">
        <a @click="connectShow"><t-icon name="server" /></a>
      </t-tooltip>

      <div class="flex-grow"></div>
      <t-tooltip
        :content="isLock === 2 ? '锁定' : isLock === 1 ? '预览' : '编辑'"
        placement="bottom"
      >
        <a>
          <!-- <t-icon name="caret-right" /> -->
          <svg
            v-if="isLock === 1"
            class="l-icon"
            aria-hidden="true"
            @click="onLock"
          >
            <use xlink:href="#l-lock"></use>
          </svg>
          <svg
            v-else-if="isLock === 2"
            class="l-icon"
            aria-hidden="true"
            @click="onLock"
          >
            <use xlink:href="#l-wufayidong"></use>
          </svg>
          <svg v-else class="l-icon" aria-hidden="true" @click="onLock">
            <use xlink:href="#l-unlock"></use>
          </svg>
        </a>
      </t-tooltip>
      <t-tooltip content="运行（在新页面全屏查看）" placement="bottom">
        <a @click="preview"><t-icon name="caret-right" /></a>
      </t-tooltip>

      <t-tooltip content="手机查看" placement="bottom">
        <a><t-icon name="qrcode" /></a>
      </t-tooltip>
      <t-tooltip content="分享" placement="bottom">
        <a><t-icon name="share" /></a>
      </t-tooltip>
      <t-tooltip content="发布" placement="bottom">
        <a><t-icon name="cloud" /></a>
      </t-tooltip>
    </div>
    <div id="meta2d"></div>
    <ContextMenu
      :style="{
        left: contextMenuValue.left,
        top: contextMenuValue.top,
      }"
      v-show="contextMenuVisible"
      :type="contextMenuType"
      @changeVisible="changeContextMenuVisible"
    />
    <t-dialog
      width="800px"
      header="数据源管理"
      v-model:visible="connectVisible"
      :footer="false"
    >
      <t-tabs :default-value="1">
        <t-tab-panel :value="1" label="通信" :destroy-on-hide="false">
          <template #panel>
            <div v-show="comShow">
              <t-row class="mt-8" justify="end">
                <t-space :size="8">
                  <t-select-input
                    placeholder="搜索我的数据源"
                    allow-input
                    clearable
                    :popup-visible="popupVisible"
                    :popup-props="{ overlayInnerStyle: { padding: '6px' } }"
                    @input-change="onInputChange"
                    @popup-visible-change="onPopupVisibleChange"
                  >
                    <template #panel>
                      <ul>
                        <li
                          style="line-height: 14px; margin: 8px 4px"
                          v-for="item in comOptions"
                          :key="item.url"
                          @click="() => onOptionClick(item)"
                        >
                          名称: {{ item.name }}<br />
                          地址: {{ item.url }}
                        </li>
                      </ul>
                    </template>
                    <template #suffixIcon>
                      <t-icon name="search"></t-icon
                    ></template>
                  </t-select-input>
                  <t-button style="height: 30px" @click="addCom"
                    >添加数据源</t-button
                  >
                </t-space>
              </t-row>
              <t-table
                class="mt-8"
                row-key="id"
                :data="comData"
                :columns="comColumns"
              >
                <template #operation="{ row, rowIndex }">
                  <t-link theme="primary" hover="color" @click="editCom(row)">
                    编辑
                  </t-link>
                  <t-divider layout="vertical" />
                  <t-popconfirm
                    content="确认删除吗"
                    @confirm="deleteCom(rowIndex)"
                  >
                    <t-link theme="primary" hover="color"> 删除 </t-link>
                  </t-popconfirm>
                </template>
              </t-table>
            </div>
            <div v-show="!comShow">
              <t-row class="mt-8">
                <t-col :span="4">
                  <t-button
                    theme="primary"
                    variant="text"
                    ghost
                    @click="comBack"
                  >
                    <template #icon>
                      <t-icon name="rollback"></t-icon>
                    </template>
                    返回
                  </t-button>
                </t-col>
                <t-col :span="4" :offset="4">
                  <t-button @click="saveForCurrent" theme="primary"
                    >仅当前页面使用</t-button
                  >
                  <t-button @click="saveToServer" theme="primary" class="ml-4"
                    >保存到服务器</t-button
                  >
                </t-col>
              </t-row>
              <div class="form-item mt-16">
                <label>名称</label>
                <t-input v-model="com.name" style="width: 200px" />
              </div>

              <div class="form-item">
                <label>连接类型</label>
                <t-select
                  v-model="com.type"
                  placeholder="请选择"
                  style="width: 200px"
                  :popup-props="{ overlayInnerStyle: { width: '200px' } }"
                  :disabled="comType === 'edit'"
                  @change="comTypeChange"
                >
                  <t-option key="mqtt" value="mqtt" class="overlay-options">
                  </t-option>
                  <t-option
                    key="websocket"
                    value="websocket"
                    class="overlay-options"
                  >
                  </t-option>
                  <t-option key="http" value="http" class="overlay-options">
                  </t-option>
                </t-select>
              </div>
              <template v-if="com.type === 'mqtt'">
                <div class="form-item">
                  <label>接口地址</label>
                  <t-input v-model="com.url" style="width: 200px" />
                </div>
                <div class="form-item">
                  <label>Client Id</label>
                  <t-input
                    v-model="com.options.clientId"
                    style="width: 200px"
                  />
                </div>
                <div class="form-item">
                  <label>关闭自动生成</label>
                  <t-switch v-model="com.options.customClientId" />
                </div>
                <div class="form-item">
                  <label>用户名</label>
                  <t-input
                    v-model="com.options.username"
                    style="width: 200px"
                  />
                </div>
                <div class="form-item">
                  <label>密码</label>
                  <t-input
                    v-model="com.options.password"
                    style="width: 200px"
                  />
                </div>
                <div class="form-item">
                  <label>Topics</label>
                  <t-input v-model="com.topics" style="width: 200px" />
                </div>
              </template>
              <template v-else-if="com.type === 'http'">
                <div class="form-item">
                  <label>请求方式</label>
                  <t-select
                    v-model="com.method"
                    placeholder="请选择"
                    style="width: 200px"
                    :popup-props="{ overlayInnerStyle: { width: '200px' } }"
                    @change="comHttpMethodChange"
                  >
                    <t-option key="GET" value="GET"> </t-option>
                    <t-option key="POST" value="POST"> </t-option>
                  </t-select>
                </div>
                <div class="form-item">
                  <label>请求头</label>
                  <t-textarea
                    v-model="com.httpHeaders"
                    placeholder="请输入请求头"
                    name="description"
                    :autosize="{ minRows: 3, maxRows: 5 }"
                  />
                </div>
                <div v-if="com.method === 'POST'" class="form-item">
                  <label>请求体</label>

                  <t-textarea
                    v-model="com.body"
                    placeholder="请输入请求体"
                    name="description"
                    :autosize="{ minRows: 3, maxRows: 5 }"
                  />
                </div>
              </template>
              <template v-else>
                <div class="form-item">
                  <label>protocol</label>
                  <t-input v-model="com.protocols" style="width: 200px" />
                </div>
              </template>
            </div>
          </template>
        </t-tab-panel>
        <t-tab-panel :value="2" :destroy-on-hide="false">
          <template #label
            >数据集 <span><label class="vip-label">VIP</label></span></template
          >
          <template #panel>
            <t-row class="mt-8" style="height: 32px; line-height: 32px">
              <t-col flex="60px"> 网络接口 </t-col>
              <t-col flex="auto">
                <t-input class="ml-8" style="width: 200px" />
              </t-col>
            </t-row>
            <t-row class="mt-8">
              <t-col flex="60px">自定义</t-col>
              <t-col flex="auto">
                <t-button
                  @click="importDataSet"
                  class="ml-8"
                  style="height: 30px"
                  >从Excel导入</t-button
                >
                <t-button @click="downloadDataSet" variant="text">
                  <template #icon><t-icon name="download"></t-icon> </template>
                  下载示例
                </t-button>
              </t-col>
            </t-row>
            <t-table
              class="mt-8"
              row-key="id"
              :data="dsData"
              :columns="dsColumns"
            >
              <template #label="{ row }">
                {{ `${row.label}(${row.key})` }}
              </template>
              <template #operation="{ row }"> </template>
            </t-table>
          </template>
        </t-tab-panel>
      </t-tabs>
    </t-dialog>
  </div>
</template>

<script lang="ts" setup>
import {
  Meta2d,
  Options,
  Pen,
  deepClone,
  LockState,
  PenType,
  HoverType,
} from "@meta2d/core";
import { onMounted, onUnmounted, watch, ref, reactive } from "vue";
import { registerBasicDiagram } from "@/services/register";
import { useRouter, useRoute } from "vue-router";
import { useUser } from "@/services/user";
import { getLe5le2d } from "@/services/api";
import { useDot } from "@/services/common";
import {
  save,
  newFile,
  SaveType,
  onScaleView,
  onScaleWindow,
} from "@/services/common";
import { useSelection, SelectionMode } from "@/services/selections";
import { defaultFormat } from "@/services/defaults";
import { MessagePlugin } from "tdesign-vue-next";
import { localMeta2dDataName } from "@/services/utils";
import localforage from "localforage";
import { checkData, Meta2dBackData } from "@/services/utils";
import { cdn } from "@/services/api";
import dayjs from "dayjs";
import ContextMenu from "./ContextMenu.vue";
import { importExcel, saveAsExcel } from "@/services/excel";
import { it } from "node:test";

const router = useRouter();
const route = useRoute();
const { user, message, getUser, getMessage, signout } = useUser();
const { dot, setDot, getDot } = useDot();
const { select } = useSelection();

const meta2dOptions: Options = {
  cdn,
  rule: true,
  background: "#1e2430",
  x: 32,
  y: 32,
  width: 1920,
  height: 1080,
  color: "#bdc7db",
  disableAnchor: true,
  defaultFormat: { ...defaultFormat },
};
onMounted(() => {
  meta2d = new Meta2d("meta2d", meta2dOptions);
  registerBasicDiagram();
  open();
  // @ts-ignore
  meta2d.on("active", active);
  // @ts-ignore
  meta2d.on("inactive", inactive);
  // @ts-ignore
  meta2d.on("scale", scaleListener);
  // @ts-ignore
  meta2d.on("add", lineAdd);
  meta2d.on("opened", openedListener);

  meta2d.on("undo", autoSave);
  meta2d.on("redo", autoSave);
  meta2d.on("add", autoSave);
  meta2d.on("delete", autoSave);
  meta2d.on("rotatePens", autoSave);
  meta2d.on("translatePens", autoSave);

  //TODO所有编辑栏所做修改
  meta2d.on("components-update-value", autoSave);
  // @ts-ignore
  meta2d.on("contextmenu", contextmenu);
  meta2d.on("click", canvasClick);

  meta2d.on("opened", dataSourceManage);
});

const watcher = watch(
  () => route.query,
  async () => {
    open();
  }
);

const open = async () => {
  if (route.query.id) {
    const ret: any = getLe5le2d(route.query.id + "");
    ret && meta2d.open(ret);
  } else {
    meta2d.open();
  }
  meta2d.store.data.x = meta2d.store.options.x || 0;
  meta2d.store.data.y = meta2d.store.options.y || 0;
};

const openedListener = () => {
  const {
    locked,
    scale: canvasScale,
    fromArrow: canvasFromArrow,
    toArrow: canvasToArrow,
  } = meta2d.store.data;
  isLock.value = locked || 0;
  scale.value = Math.round(canvasScale * 100);
  fromArrow.value = canvasFromArrow || "";
  toArrow.value = canvasToArrow || "";
};

onUnmounted(() => {
  watcher();
  if (meta2d) {
    // @ts-ignore
    meta2d.off("active", active);
    // @ts-ignore
    meta2d.off("inactive", inactive);
    // @ts-ignore
    meta2d.off("scale", scaleListener);
    // @ts-ignore
    meta2d.off("add", lineAdd);
    meta2d.on("opened", openedListener);

    meta2d.off("undo", autoSave);
    meta2d.off("redo", autoSave);
    meta2d.off("add", autoSave);
    meta2d.off("delete", autoSave);
    meta2d.off("rotatePens", autoSave);
    meta2d.off("translatePens", autoSave);
    meta2d.off("components-update-value", autoSave);
    // @ts-ignore
    meta2d.off("contextmenu", contextmenu);
    meta2d.off("click", canvasClick);

    meta2d.off("opened", dataSourceManage);
    meta2d.destroy();
  }
});

let localSaveTimer: any = 0;
let saveTimer: any = 0;
const autoSave = () => {
  setDot(true);
  localSaveTimer && clearTimeout(localSaveTimer);
  localSaveTimer = setTimeout(() => {
    const data: Meta2dBackData = meta2d.data();
    let _localMeta2dDataName = data._id
      ? localMeta2dDataName + "-" + data._id
      : localMeta2dDataName;
    (data as any).localSaveAt = dayjs().format();
    localforage.setItem(_localMeta2dDataName, JSON.stringify(data));
    localSaveTimer = undefined;
  }, 3000);
  autoSaveServer();
};
//运行 在新标签页查看
function autoSaveServer() {
  //会员享受自动保存
  if (saveTimer) {
    return;
  }
  saveTimer = setTimeout(() => {
    const data: Meta2dBackData = meta2d.data();
    if (
      user &&
      user.id &&
      user.vipExpired &&
      data._id &&
      !data.component &&
      data.owner &&
      data.owner?.id === user.id
    ) {
      save(SaveType.Save);
    }
    saveTimer = null;
  }, 60000);
}

const inactive = () => {
  select();
};

const active = (pens: Pen[]) => {
  select(pens);

  //格式刷处理
  if (one.value || always.value) {
    meta2d.formatPainter();
    one.value = false;
  }
};

const one = ref(false);
const always = ref(false);

const oneFormat = () => {
  if (one.value) {
    one.value = false;
  } else {
    one.value = true;
    meta2d.setFormatPainter();
  }
  if (always.value) {
    always.value = false;
    one.value = false;
  }
};

const alwaysFormat = () => {
  always.value = true;
};

const clearFormat = () => {
  always.value = false;
  one.value = false;
  meta2d.clearFormatPainter();
};

const scale = ref(100);
function scaleListener(newScale: number) {
  scale.value = Math.round(newScale * 100);
}

const connectVisible = ref(false);
const connectShow = () => {
  connectVisible.value = true;
};

const currentLineType = ref("curve");
const lineTypes = reactive([
  { name: "曲线", icon: "#l-curve2", value: "curve" },
  { name: "线段", icon: "#l-polyline", value: "polyline" },
  { name: "直线", icon: "#l-line", value: "line" },
  { name: "脑图曲线", icon: "#l-mind", value: "mind" },
]);

const changeLineType = (value: string) => {
  currentLineType.value = value;
  if (meta2d) {
    meta2d.store.options.drawingLineName = value;
    meta2d.canvas.drawingLineName && (meta2d.canvas.drawingLineName = value);
    meta2d.store.active?.forEach((pen) => {
      meta2d.updateLineType(pen, value);
    });
  }
};

const fromArrow = ref("");
const fromArrows = [
  { icon: "#l-line", value: "" },
  { icon: "#l-from-triangle", value: "triangle" },
  { icon: "#l-from-diamond", value: "diamond" },
  { icon: "#l-from-circle", value: "circle" },
  { icon: "#l-from-lineDown", value: "lineDown" },
  { icon: "#l-from-lineUp", value: "lineUp" },
  { icon: "#l-from-triangleSolid", value: "triangleSolid" },
  { icon: "#l-from-diamondSolid", value: "diamondSolid" },
  { icon: "#l-from-circleSolid", value: "circleSolid" },
  { icon: "#l-from-line", value: "line" },
];
const toArrow = ref("");
const toArrows = [
  { icon: "#l-line", value: "" },
  { icon: "#l-to-triangle", value: "triangle" },
  { icon: "#l-to-diamond", value: "diamond" },
  { icon: "#l-to-circle", value: "circle" },
  { icon: "#l-to-lineDown", value: "lineDown" },
  { icon: "#l-to-lineUp", value: "lineUp" },
  { icon: "#l-to-triangleSolid", value: "triangleSolid" },
  { icon: "#l-to-diamondSolid", value: "diamondSolid" },
  { icon: "#l-to-circleSolid", value: "circleSolid" },
  { icon: "#l-to-line", value: "line" },
];

const changeFromArrow = (value: string) => {
  fromArrow.value = value;
  // 画布默认值
  meta2d.store.data.fromArrow = value;
  // 活动层的箭头都变化
  if (meta2d.store.active) {
    meta2d.store.active.forEach((pen: Pen) => {
      if (pen.type === PenType.Line) {
        pen.fromArrow = value;
        meta2d.setValue(
          {
            id: pen.id,
            fromArrow: pen.fromArrow,
          },
          {
            render: false,
          }
        );
      }
    });
    meta2d.render();
  }
};

const changeToArrow = (value: string) => {
  toArrow.value = value;
  // 画布默认值
  meta2d.store.data.toArrow = value;
  // 活动层的箭头都变化
  if (meta2d.store.active) {
    meta2d.store.active.forEach((pen: Pen) => {
      if (pen.type === PenType.Line) {
        pen.toArrow = value;
        meta2d.setValue(
          {
            id: pen.id,
            toArrow: pen.toArrow,
          },
          {
            render: false,
          }
        );
      }
    });
    meta2d.render();
  }
};

const oneD = ref<boolean>(false);
const alwaysD = ref<boolean>(false);
const oneDraw = () => {
  if (oneD.value) {
    oneD.value = false;
    if (!alwaysD.value) {
      meta2d.finishDrawLine();
      meta2d.drawLine();
      meta2d.store.options.disableAnchor = true;
    }
  } else {
    oneD.value = true;
    meta2d.drawLine(meta2d.store.options.drawingLineName);
    meta2d.store.options.disableAnchor = false;
  }
  if (alwaysD.value) {
    meta2d.finishDrawLine();
    meta2d.drawLine();
    oneD.value = false;
    alwaysD.value = false;
    meta2d.store.options.disableAnchor = true;
  }
};
const alwaysDraw = () => {
  alwaysD.value = true;
  meta2d.drawLine(meta2d.store.options.drawingLineName);
  meta2d.store.options.disableAnchor = false;
};

const lineAdd = (pens: Pen[]) => {
  if (pens.length === 1 && pens[0].name === "line") {
    //连线类型
    if (oneD.value && !alwaysD.value) {
      if (meta2d.canvas.drawingLineName) {
        oneD.value = false;
        setTimeout(() => {
          meta2d.finishDrawLine();
          meta2d.drawLine();
          meta2d.store.options.disableAnchor = true;
        }, 100);
      }
    }
  }
};

const onAddShape = (event: DragEvent | MouseEvent, name: string) => {
  let data: any;
  if (name === "text") {
    data = {
      text: "text",
      width: 100,
      height: 20,
      name: "text",
    };
  } else if (name === "line") {
    data = {
      anchors: [
        { id: "0", x: 0, y: 0.5 },
        { id: "1", x: 1, y: 0.5 },
      ],
      width: 100,
      height: 1,
      name: "line",
      lineName: "line",
      type: 1,
    };
  }
  if (!(event as DragEvent).dataTransfer) {
    meta2d.canvas.addCaches = deepClone([data]);
  } else {
    (event as DragEvent).dataTransfer?.setData("Meta2d", JSON.stringify(data));
  }
  event.stopPropagation();
};

const isLock = ref(0);
function onLock() {
  !isLock.value && (isLock.value = 0);
  if (isLock.value === LockState.DisableMove) {
    isLock.value = LockState.None;
  } else {
    isLock.value++;
  }
  meta2d.lock(isLock.value);
  meta2d.hideInput();
}

const preview = async () => {
  meta2d.stopAnimate();
  // @ts-ignore
  const data: Meta2dBackData = meta2d.data();
  checkData(data);
  if (dot && user && data._id) {
    // 有 id ，是修改后保存
    await save(SaveType.Save);
  }
  if (!data._id) {
    await localforage.setItem(localMeta2dDataName, JSON.stringify(data));
  }
  router.push({
    path: "/preview",
    query: {
      r: Date.now() + "",
      id: data._id,
    },
  });
};

const contextMenuVisible = ref(false);
const contextMenuValue = ref({
  left: "0px",
  top: "0px",
});
const contextMenuType = ref("");

const contextmenu = ({ e, rect }: { e: any; rect: any }) => {
  contextMenuType.value = "";
  contextMenuValue.value.left = e.clientX + "px";
  contextMenuValue.value.top = e.clientY + "px";
  if (
    meta2d.store.hoverAnchor &&
    meta2d.canvas.hoverType === HoverType.LineAnchor
  ) {
    contextMenuType.value = "anchor";
  } else {
    //其他右键菜单
  }

  if (!contextMenuVisible.value && contextMenuType.value) {
    contextMenuVisible.value = true;
  }
  if (!contextMenuType.value) {
    contextMenuVisible.value = false;
  }
};

const canvasClick = () => {
  contextMenuVisible.value = false;
};

const changeContextMenuVisible = (e: boolean) => {
  contextMenuVisible.value = e;
};

// const comConfirm = () => {
//   connectVisible.value = false;
// };

interface Com {
  name?: string;
  type: "mqtt" | "websocket" | "http";
  url?: string;
  //websocket
  protocols?: string;
  //mqtt
  topics?: string;
  options?: {
    clientId?: string;
    username?: string;
    password?: string;
    customClientId?: boolean;
  };
  //http
  http?: string; // http 请求 Url
  httpTimeInterval?: number; // http 请求间隔
  httpHeaders?: HeadersInit; //请求头
  method?: string;
  body?: BodyInit | null;
}

const comData = ref<Com[]>([
  {
    name: "连接1",
    type: "mqtt",
    url: "wss://1",
    topics: "",
    options: {
      clientId: "",
      username: "",
      password: "",
      customClientId: false,
    },
  },
  {
    name: "连接2",
    type: "websocket",
    url: "wss://2",
  },
  {
    name: "连接3",
    type: "http",
    url: "wss://3",
  },
]);
const comColumns = ref([
  {
    colKey: "name",
    title: "名称",
    ellipsis: true,
  },
  {
    colKey: "type",
    title: "类型",
    ellipsis: true,
  },
  {
    colKey: "url",
    title: "接口地址",
    ellipsis: true,
  },
  { colKey: "operation", title: "操作", width: 120, foot: "-" },
]);

const comOptions = ref<Com[]>([
  {
    name: "连接A",
    type: "mqtt",
    url: "ws://A",
  },
  {
    name: "连接B",
    type: "mqtt",
    url: "ws://B",
  },
  {
    name: "连接C",
    type: "mqtt",
    url: "ws://C",
  },
  {
    name: "连接D",
    type: "mqtt",
    url: "ws://D",
  },
  {
    name: "连接E",
    type: "mqtt",
    url: "ws://E",
  },
]);

const dataSourceManage = () => {
  comData.value = (meta2d.store.data as any).comData; //确定字段
  dsData.value = (meta2d.store.data as any).dsData;
};

const onOptionClick = (item: Com) => {
  comData.value.push(item);
  popupVisible.value = false;
};

const popupVisible = ref(false);
const onInputChange = (e) => {
  console.log("change", e);
};
const onPopupVisibleChange = (val: boolean) => {
  popupVisible.value = val;
};

const comType = ref("add"); //or edit

const addCom = () => {
  comType.value = "add";
  com.value = {
    name: "",
    type: "mqtt", //默认
    url: "",
    options: {
      clientId: "",
      username: "",
      password: "",
      customClientId: false,
    },
  };
  comShow.value = false;
};
const editCom = (row: Com) => {
  comType.value = "edit";
  com.value = row;
  comShow.value = false;
};

const deleteCom = (index: number) => {
  comData.value.splice(index, 1);
  dataToCom(comData.value);
};

//将配置的通信列表转成核心库能识别的格式
const dataToCom = (data: Com[]) => {
  const mqtts: any = [];
  const https: any = [];
  const websockets: any = [];
  data.forEach((item) => {
    if (item.type === "http") {
      https.push({
        http: item.http,
        httpTimeInterval: item.httpTimeInterval,
        httpHeaders: item.httpHeaders,
        method: item.method,
        body: item.body,
      });
    } else if (item.type === "mqtt") {
      mqtts.push({
        url: item.url,
        options: {
          clientId: item.options?.clientId,
          username: item.options?.username,
          password: item.options?.password,
          customClientId: item.options?.customClientId,
        },
        topics: item.topics,
      });
    } else if (item.type === "websocket") {
      websockets.push({
        url: item.url,
        protocols: item.protocols,
      });
    }
  });
  meta2d.store.data.mqtts = mqtts;
  meta2d.store.data.https = https;
  meta2d.store.data.websockets = websockets;
  //TODO 建立通信连接
  meta2d.connectSocket();
};
const comShow = ref(true);

const comBack = () => {
  comShow.value = true;
};

const com = ref<Com>({
  name: "连接E",
  type: "mqtt",
  url: "ws://E",
  options: {
    clientId: "",
    username: "",
    password: "",
    customClientId: false,
  },
});

const comTypeChange = (e: string) => {
  console.log(e, com.value.type);
  if (e === "mqtt") {
    Object.assign(com.value, {
      options: {
        clientId: "",
        username: "",
        password: "",
        customClientId: false,
      },
    });
  } else if (e === "websocket") {
    Object.assign(com.value, {
      protocols: "",
    });
  } else {
    Object.assign(com.value, {
      http: "",
      httpTimeInterval: 1000,
      httpHeaders: "",
      method: "GET",
      body: "",
    });
  }
};

const comHttpMethodChange = (e: string) => {
  if (e === "GET") {
    com.value.body = null;
  }
};

const dsData = ref([
  {
    label: "数据点1",
    key: "a-1",
    value: "12",
    type: "number/select/bool/color",
  },
  {
    label: "数据点2",
    key: "a-2",
    value: "12",
    type: "number/select/bool/color",
  },
  {
    label: "数据点3",
    key: "a-3",
    value: "12",
    type: "number/select/bool/color",
  },
]);

const dsColumns = ref([
  {
    colKey: "label",
    title: "名称（数据点ID）",
    ellipsis: true,
  },
  {
    colKey: "type",
    title: "类型",
    ellipsis: true,
  },
  {
    colKey: "value",
    title: "值",
    ellipsis: true,
  },
]);

const saveForCurrent = () => {
  comData.value.push(com.value);
  comShow.value = true;
  dataToCom(comData.value);
};

const saveToServer = () => {
  //TODO 将com保存到服务器
  comData.value.push(com.value);
  comShow.value = true;
  dataToCom(comData.value);
};

const importDataSet = async () => {
  let columns: any = [
    {
      header: "名称",
      key: "label",
    },
    {
      header: "数据ID",
      key: "key",
    },
    {
      header: "类型",
      key: "type",
    },
    {
      header: "值",
      key: "value",
    },
  ];
  // dsData.value = [];
  let data = await importExcel(columns);
  console.log("data", data);
  // setTimeout(() => {
  dsData.value = data;
  // }, 2000);
};

const downloadDataSet = () => {
  let name = "数据集示例";
  let columns = [
    {
      header: "名称",
      key: "label",
    },
    {
      header: "数据ID",
      key: "id",
    },
    {
      header: "类型",
      key: "type",
    },
    {
      header: "值",
      key: "value",
    },
  ];
  let data = [
    ["数据集1", "dataId-1", "string", "zzz"],
    ["数据集2", "dataId-2", "boolean", true],
    ["数据集3", "dataId-3", "number", 12],
  ];
  saveAsExcel(name, columns, data);
};
</script>
<style lang="postcss" scoped>
.meta2d {
  display: flex;
  flex-direction: column;
  background-color: var(--color-background-editor);
  border-left: 1px solid var(--color-border);

  .tools {
    display: flex;
    font-size: 12px;
    background-color: var(--color-background);
    height: 40px;
    flex-shrink: 0;
    padding: 0 12px;

    a {
      display: flex;
      align-items: center;
      height: 100%;
      padding: 0 10px;
      color: var(--color);
      text-decoration: none;

      .l-icon {
        width: 16px;
        height: 16px;
      }

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

    .t-icon {
      font-size: 16px;
    }
  }

  #meta2d {
    border-top: 1px solid var(--color-background-input);
    height: calc(100vh - 81px);

    :deep(.meta2d-map) {
      background: var(--color-background);
    }
  }
}
</style>

<style lang="postcss">
.t-dialog {
  .t-dialog__body {
    height: 450px;
    /* overflow: auto; */
  }

  .form-item {
    display: flex;
    margin-bottom: 8px;

    label {
      width: 100px;
    }
  }
  .t-textarea {
    width: calc(100% - 150px);
  }

  .vip-label {
    font-size: 10px;
    background-color: #ff400030;
    color: var(--color-bland);
    padding: 0 6px;
    margin-left: 4px;
    border-radius: 2px;
  }
  .t-tab-panel {
    overflow: auto;
    height: 395px;
  }
}
</style>
