<template>
  <div style="width: 100%; height: 100vh">
    <div class="top"></div>
    <div class="left">
      <el-card
        class="moduleCard"
        shadow="never"
        :draggable="true"
        @dragstart="onDragStart($event, 'line', {})"
        :style="{ display: 'inline-block', margin: '0 4px 4px 0' }"
        :body-style="{ padding: '4px 0' }"
      >
        <template #header>
          <div style="position: absolute; top: 50%; transform: translateY(-50%); width: 64px; height: 1px; background-color: #0002"></div>
        </template>
        <div class="moduleText">线</div>
      </el-card>
      <el-card
        class="moduleCard"
        shadow="never"
        :draggable="true"
        @dragstart="onDragStart($event, 'text1', {})"
        :style="{ display: 'inline-block', margin: '0 4px 4px 0' }"
        :body-style="{ padding: '4px 0' }"
      >
        <template #header>
          <div style="position: absolute; top: 50%; transform: translateY(-50%); width: 64px; height: 1px; background-color: #0002"></div>
        </template>
        <div class="moduleText">文字</div>
      </el-card>
      <el-card
        class="moduleCard"
        shadow="never"
        :draggable="true"
        @dragstart="onDragStart($event, 'circuitComponent', { type: 1 })"
        :style="{ display: 'inline-block', margin: '0 4px 4px 0' }"
        :body-style="{ padding: '4px 0' }"
      >
        <template #header>
          <el-image style="width: 100%; height: 100%" :src="img1" fit="contain" />
        </template>
        <div class="moduleText">元件1</div>
      </el-card>
      <el-card
        class="moduleCard"
        shadow="never"
        :draggable="true"
        @dragstart="onDragStart($event, 'circuitComponent', { type: 2 })"
        :style="{ display: 'inline-block', margin: '0 4px 4px 0' }"
        :body-style="{ padding: '4px 0' }"
      >
        <template #header>
          <el-image style="width: 100%; height: 100%" :src="img2" fit="contain" />
        </template>
        <div class="moduleText">元件2</div>
      </el-card>
    </div>
    <div class="right" ref="rightRef" @drop="onDrop">
      <VueFlow
        class="flow"
        id="flowA"
        :min-zoom="0.01"
        ref="flowRef"
        :zoom-on-double-click="false"
        :snapToGrid="isSnapToGrid"
        :panOnDrag="false"
        :zoomOnScroll="false"
        :autoPanSpeed="0"
        :snapGrid="[10, 10]"
        v-model:nodes="nodes"
        v-model:edges="edges"
        fit-view-on-init
        default-marker-color="#409EFF"
        @node-click="logEvent('click', $event)"
        @pane-click="logEvent('paneClick', $event)"
        @node-drag-start="logEvent('nodeDrag', $event)"
        @node-contextMenu="logEvent('contextmenu', $event)"
        @node-double-click="logEvent('dblclick', $event)"
        @dragover="onDragOver"
      >
        <Background :size="1" :gap="20" pattern-color="#BDBDBD" style="background-color: #fff" />

        <template #node-area="props">
          <AreaNode v-bind="props" :pageData="{ width: '960px', height: '540px' }"></AreaNode>
        </template>
        <template #node-circuitComponent="props">
          <CircuitComponentNode :monitorType="monitorType" v-bind="props" :networkData="dataTest" />
        </template>
        <template #node-deviceDataList="props">
          <DeviceDataListNode :monitorType="monitorType" v-bind="props" :networkData="dataTest" :pNode="findNode(props.parentNodeId)" />
        </template>
        <template #node-line="props">
          <LineNode :monitorType="monitorType" v-bind="props" />
        </template>
        <template #node-text1="props">
          <TextNode :monitorType="monitorType" v-bind="props" :networkData="dataTest" />
        </template>
      </VueFlow>
    </div>

    <el-dialog draggable v-model="nodeOptionVisible" title="节点配置" width="500">
      <el-form :model="nodeData">
        <el-form-item label="网络地址" label-width="120px" v-if="[].includes(nodeType)">
          <el-input v-model="nodeData.network" autocomplete="off" />
        </el-form-item>
        <el-form-item label="节点id" label-width="120px" v-if="['circuitComponent', 'text1'].includes(nodeType)">
          <el-input v-model="nodeData.id" autocomplete="off" />
        </el-form-item>
        <el-form-item label="节点内容" label-width="120px" v-if="['text1'].includes(nodeType)">
          <el-input v-model="nodeData.value" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="nodeOptionVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog :modal="false" :modal-penetrable="true" draggable v-model="nodeStyleVisible" title="节点配置" width="500">
      <el-form :model="nodeStyle">
        <el-form-item label="对齐方式" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'align')">
          <el-select v-model="nodeStyle.align" placeholder="Select">
            <el-option label="左对齐" value="left" />
            <el-option label="居中" value="center" />
            <el-option label="右对齐" value="right" />
          </el-select>
        </el-form-item>
        <el-form-item label="颜色" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'color')">
          <el-color-picker v-model="nodeStyle.color" show-alpha />
        </el-form-item>
        <el-form-item label="是否允许换行" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'whiteSpace')">
          <el-switch v-model="nodeStyle.whiteSpace" active-value="nowrap" inactive-value="normal" />
        </el-form-item>
        <el-form-item label="线类型" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'lineType')">
          <el-select v-model="nodeStyle.lineType" placeholder="Select">
            <el-option label="横线" :value="0" />
            <el-option label="竖线" :value="1" />
          </el-select>
        </el-form-item>
        <el-form-item label="宽度" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'width')">
          <el-input-number v-model="nodeStyle.width" :min="1" />
        </el-form-item>
        <el-form-item label="旋转角度" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'rotate')">
          <el-input-number v-model="nodeStyle.rotate" :min="-360" :max="360" />
        </el-form-item>
        <el-form-item label="旋转中心" label-width="120px" v-if="Object.hasOwn(nodeStyle, 'transformOrigin1')">
          <el-select v-model="nodeStyle.transformOrigin1" placeholder="Select" style="width: calc(50% - 20px); margin-right: 20px">
            <el-option label="左" value="left" />
            <el-option label="中" value="center" />
            <el-option label="右" value="right" />
          </el-select>
          <el-select v-model="nodeStyle.transformOrigin2" placeholder="Select" style="width: calc(50% - 20px)">
            <el-option label="上" value="top" />
            <el-option label="中" value="center" />
            <el-option label="下" value="bottom" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="nodeStyleVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { v4 as uuidv4 } from 'uuid';
import img1 from '@/assets/electronicComponents/1.png';
import img2 from '@/assets/electronicComponents/2.png';
import AreaNode from './nodes/area.vue';
import CircuitComponentNode from './nodes/circuitComponent.vue';
import DeviceDataListNode from './nodes/deviceDataList.vue';
import LineNode from './nodes/line.vue';
import TextNode from './nodes/text.vue';
import { MarkerType, useVueFlow, VueFlow } from '@vue-flow/core';
import { Background } from '@vue-flow/background';
import tool from './tool.js';

const rightRef = ref();
const flowRef = ref();

const pid = ref(`area_${uuidv4().replaceAll('-', '_')}`);
const nodes = ref([
  {
    id: pid.value,
    name: 'area',
    type: 'area',
    position: {
      x: 0,
      y: 0
    },
    selectable: false,
    draggable: false,
    data: {}
  }
]);
const edges = ref([]);
const isSnapToGrid = ref(true);
const nodeOptionVisible = ref(false);
const nodeStyleVisible = ref(false);
const nodeType = ref('');
const nodeData = ref({});
const nodeStyle = ref({});
const dataTest = ref([
  {
    id: 'test-1',
    options: {
      tem: 30,
      a: 10,
      v: 20
    }
  },
  {
    id: 'test-2',
    options: {
      tem: 20,
      a: 20,
      v: 10
    }
  }
]);

const monitorType = ref([
  { label: '温度', value: 'tem' },
  { label: '字段1', value: 'a' },
  { label: '字段2', value: 'v' }
]);

const { onDragStart, onDrop, onDragOver } = tool();
const { addEdges, updateNode, removeNodes, addNodes, onNodesChange, findNode } = useVueFlow({ id: 'flowA' });

const logEvent = async (eventname, event) => {
  switch (eventname) {
    case 'paneClick':
      break;
    case 'click':
      break;
    case 'nodeDrag':
      break;
    case 'dblclick':
      event.event.preventDefault();
      nodeStyleVisible.value = true;
      nodeType.value = event.node.type;
      nodeStyle.value = event.node.data.style;
      break;
    case 'contextmenu':
      event.event.preventDefault();
      nodeOptionVisible.value = true;
      nodeType.value = event.node.type;
      nodeData.value = event.node.data.options;
      break;
  }
};
onNodesChange((changes) => {
  changes.forEach((e) => {
    if (e.type === 'remove') {
      const ids = nodes.value.filter((node) => node.parentNode === e.id).map((node) => node.id);
      removeNodes(ids);
    }
  });
});
onMounted(() => {
  let scale = 0;
  const width = rightRef.value.getBoundingClientRect().width;
  rightRef.value.style.width = width + 'px';
  rightRef.value.style.height = (width * 540) / 960 + 'px';
  scale = width / 960;

  flowRef.value.onInit(() => {
    flowRef.value.setTransform({
      x: 0,
      y: 0,
      zoom: scale
    });
  });
  nextTick(() => {
    let NODES = JSON.parse(localStorage.getItem('NODES') || '[]');
    if (NODES.length > 0) {
      nodes.value = NODES;
    }
  });
});
watch(
  nodes,
  () => {
    if (nodes.value.length > 1) {
      localStorage.setItem('NODES', JSON.stringify(nodes.value));
    }
  },
  { deep: true }
);
</script>
<style lang="scss" scoped>
.top {
  width: 100%;
  height: 50px;
}

.left {
  display: inline-block;
  width: 200px;
  height: 100%;
  vertical-align: top;

  .moduleCard {
    width: calc(50% - 4px);
    display: inline-block;
    height: 150px;

    :deep(.el-card__header) {
      width: 100%;
      height: 100px;
      position: relative;
    }

    :deep(.el-card__body) {
      padding: 0 20px 0 20px !important;

      .moduleText {
        line-height: 50px;
      }
    }
  }
}

.right {
  display: inline-block;
  width: calc(100% - 200px - 20px);
  height: 100%;
  position: absolute;
  left: 200px;
}
</style>
