<template>
  <DesignFixedLayout rightWidth="560px" v-if="state.show">
    <template #head>
      <Head
        @save="save"
        @close="close"
        :title="state.editData.id ? '编辑规则流程设计' : '新增规则流程设计'"
      />
    </template>
    <template #left>
      <div class="containers">
        <Sidebar />
      </div>
    </template>
    <template #right>
      <NodeElement
        :nodes="state.nodes"
        :edges="state.edges"
        :viewport="state.viewport"
        @node-click="nodeClick"
        @edge-click="edgeClick"
        :key="renderKey"
      />
    </template>
  </DesignFixedLayout>
</template>
<script setup lang="ts">
  import { onMounted, reactive, ref } from 'vue';
  import { message, notification } from 'ant-design-vue';
  import DesignFixedLayout from './../DesignFixedLayout.vue';
  import Head from './layout/Head.vue';
  import NodeElement from './nodes/Index.vue';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { useVueFlow } from '@vue-flow/core';
  import { useRuleProcessStore } from './store';
  import { defaultProcessInfo, StartId, startNodeItem, defaultNodes } from './config';
  import { storeToRefs } from 'pinia';
  import { RuleProcessListModel } from '/@/api/ruleProcess/model';
  import type { Node, Edge } from '@vue-flow/core';
  import Sidebar from './nodes/components/Sidebar.vue';
  import { cloneDeep } from 'lodash-es';

  const props = defineProps({
    treeData: Array,
    editData: Object,
  });
  const { t } = useI18n();
  const store = useRuleProcessStore();
  const {
    initStartProperties,
    setProcessInfoProperties,
    setProperties,
    setLastEdgeId,
    setLastNodeId,
    setCateGorytreeData,
    setEdgeId,
    setInfoId,
  } = store;
  const { toObject } = useVueFlow();
  const emit = defineEmits(['close', 'save']);
  const renderKey = ref(0);
  let canvas = ref(null);
  let state = reactive({
    editData: cloneDeep(defaultProcessInfo) as RuleProcessListModel,
    nodes: [] as Array<Node>,
    edges: [] as Array<Edge>,
    viewport: { x: 0, y: 0, zoom: 1 } as { x: number; y: number; zoom: number },
    show: false,
  });
  onMounted(() => {
    setCateGorytreeData(props.treeData ?? []);
    let processInfoProperties = cloneDeep(defaultProcessInfo);
    if (props.editData && props.editData.id) {
      state.editData = props.editData as RuleProcessListModel;
      processInfoProperties.id = state.editData.id ?? '';
      processInfoProperties.name = state.editData.name ?? '';
      processInfoProperties.code = state.editData.code ?? '';
      processInfoProperties.itemId = state.editData.itemId ?? '';
      processInfoProperties.remark = state.editData.remark ?? '';

      let jsonContent = JSON.parse(state.editData.jsonContent);

      if (jsonContent.processParamConfigs) {
        processInfoProperties.processParamConfigs = jsonContent.processParamConfigs;
      }
      if (jsonContent.elValue) {
        processInfoProperties.elValue = jsonContent.elValue;
      }
      setProcessInfoProperties(processInfoProperties);

      if (jsonContent.lastEdgeId) {
        setLastEdgeId(jsonContent.lastEdgeId);
      }
      if (jsonContent.lastNodeId) {
        setLastNodeId(jsonContent.lastNodeId);
      }

      if (jsonContent.nodes && Array.isArray(jsonContent.nodes) && jsonContent.nodes.length > 0) {
        state.nodes = jsonContent.nodes;
        state.nodes.forEach((item) => {
          setProperties(item.id, item.data);
        });
      }
      if (jsonContent.edges && Array.isArray(jsonContent.edges) && jsonContent.edges.length > 0) {
        state.edges = jsonContent.edges;
        state.edges.forEach((item) => {
          setProperties(item.id, item.data);
        });
      }
      if (jsonContent.viewport) {
        state.viewport = jsonContent.viewport;
      }
      renderKey.value++;
      state.show = true;
    } else {
      setProcessInfoProperties(processInfoProperties);
      init();
      state.show = true;
    }
  });

  function nodeClick(nodeInfo) {
    let item = nodeInfo.data;
    setInfoId(item.id);
    setEdgeId('');
  }
  function edgeClick(edgeInfo) {
    let item = edgeInfo.data;
    setEdgeId(item.id);
    setInfoId('');
  }

  function init() {
    // 新增
    initStartProperties(StartId, startNodeItem);
    state.nodes = defaultNodes;
  }
  function save() {
    const { processInfo, lastEdgeId, lastNodeId } = storeToRefs(store);
    // 必须填写模板编码 模板名称 模板分类
    if (!processInfo.value.name) {
      notification.error({
        message: t('提示'),
        description: t('模板名称不能为空'),
      }); //提示消息
      return false;
    }
    if (!processInfo.value.code) {
      notification.error({
        message: t('提示'),
        description: t('模板编码不能为空'),
      }); //提示消息
      return false;
    }
    if (!processInfo.value.itemId) {
      notification.error({
        message: t('提示'),
        description: t('模板分类不能为空'),
      }); //提示消息
      return false;
    }
    let jsonContent = JSON.stringify({
      ...toObject(),
      lastEdgeId: lastEdgeId.value,
      lastNodeId: lastNodeId.value,
      processParamConfigs: processInfo.value.processParamConfigs,
      elValue: processInfo.value.elValue,
    });
    emit('save', { ...processInfo.value, jsonContent });
    message.success(t('保存成功'));
  }
  function close() {
    canvas.value = null;
    emit('close');
  }
</script>

<style lang="less" scoped>
  .containers {
    width: 100%;
    height: 100%;
    position: relative;
  }

  /* 画布 */
  .canvas {
    width: 100%;
    height: 100%;
  }

  .property-panel {
    width: 100%;
    height: 100%;
  }

  svg.new-parent {
    background: #000 !important;
  }

  :deep(.djs-palette-entries) {
    display: flex;
    margin-left: 18vw;
  }

  :deep(.group[data-group='none']) {
    display: none;
  }

  :deep(.group[data-group='tools']),
  :deep(.group[data-group='event']) {
    display: flex;
    box-shadow: 0 2px 2px 2px rgb(0 0 0 / 4%);
    border-radius: 4px;
    padding: 4px;
    margin-right: 10px;
  }

  :deep(.djs-palette .entry, .djs-palette .djs-palette-toggle) {
    width: 36px;
    height: 36px;
    line-height: 30px;
    font-size: 26px;
  }

  :deep(.djs-selection-outline) {
    opacity: 0.1;
  }

  :deep(.djs-context-pad.open) {
    box-shadow: 0 2px 2px 2px rgb(0 0 0 / 4%);
    border-radius: 4px;
    background-color: #fff;
  }

  :deep(.group[data-group='event1']) {
    display: flex;
    flex-wrap: wrap;
    width: 102px;
    margin-top: 6px;
    margin-left: 6px;
    margin-right: 6px;
  }

  :deep(.group[data-group='event2']) {
    margin: 6px;
  }

  :deep(.djs-context-pad .entry) {
    border: none;
    margin: 6px;
  }

  :deep(.djs-context-pad .entry.bpmn-icon-trash) {
    color: @clear-color;
  }

  :deep(.bjs-align-elements-menu-entry img) {
    width: 10px;
    height: 10px;
  }

  :deep(.group[data-group='align']),
  :deep(.group[data-group='distribute']) {
    width: 75px;
    display: flex;
    flex-wrap: wrap;
  }

  :deep(.icon-custom-context-pad),
  :deep(.djs-overlay-context-pad) {
    color: #000;
  }

  :deep(.bjs-powered-by) {
    display: none !important;
  }

  :deep(.djs-direct-editing-content) {
    color: #000;
  }

  :deep(.djs-palette) {
    border: none;
    width: 0;
    height: 0;
  }

  /* 按钮（放大 发小 清除） */
  .fixed-bottom {
    position: absolute;
    top: 22px;
    left: calc(20vw + 420px);
    display: flex;
  }

  .fixed-refresh-box {
    background-color: @clear-color;
    box-shadow: 0 2px 2px 2px @clear-color;
    border-radius: 4px;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 36px;
    height: 36px;
  }

  .fixed-refresh {
    font-size: 20px;
    color: #fff;
    cursor: pointer;
  }

  :deep(.ant-table-cell) {
    padding: 0;
  }

  :deep(.ant-table.ant-table-middle .ant-table-thead > tr > th) {
    &:first-child {
      border-top-left-radius: 0 !important;
    }

    &:last-child {
      border-top-right-radius: 0 !important;
    }
  }
</style>
