<template>
  <div class="x6-vue-shape" ref="x6VueShapeRef">
    <div class="node-name" ref="nodeNameRef">
      <img :src="activeIconSrc" alt="" class="svg-img" />
      <div class="node-content">
        <div class="node-name-title">
          <a-tooltip placement="topLeft" :title="nameVal">
            <span class="x6-vue-shape-name-class">{{ nameVal }}</span>
          </a-tooltip>
        </div>
        <div class="node-main">
          <a-tooltip placement="top" v-if="fitName && fitName.length > 20">
            <template #title>
              <div v-html="fitName"></div>
            </template>
            <div :class="{ 'hint-title': fitName == '未设置此节点' }" v-html="fitName"></div>
          </a-tooltip>
          <div :class="{ 'hint-title': fitName == '未设置此节点' }" v-html="fitName" v-else></div>
        </div>
      </div>
    </div>
    <!-- 状态图片 -->
    <img src="@/assets/images/flow-base/wait.svg" alt="" class="flow-status-img" v-if="currentNodeStatus == 20" />
    <img src="@/assets/images/flow-base/completed.svg" alt="" class="flow-status-img" v-if="currentNodeStatus == 30" />
    <img src="@/assets/images/flow-base/rejected.svg" alt="" class="flow-status-img" v-if="currentNodeStatus == 50" />
    <!-- 加号 -->
    <div class="x6-shape-add" v-if="isShowAdd && nodeData2?.id && currentNodeData?.nodeId && currentNodeData.nodeId == nodeData2.id">
      <template v-for="item in addButtonList" :key="item.type">
        <div :class="item.class" v-if="currentNodeData.groupList.find(gItem => gItem.name == item.type)">
          <a-popover placement="right" style="border-radius: 5px">
            <template #content>
              <X6AddNode :type="item.type" :node="nodeData2" @addNode="addNode" />
            </template>
            <img src="@/assets/images/add.svg" alt="" class="shape-img" />
          </a-popover>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { defineComponent, ref, onMounted, inject, watch, computed } from 'vue';
import { useWorkflowStore } from '@/store/modules/workflow';
import X6ShapeUtil from '../utils/x6-shape-util';
import X6AddNode from './components/x6-add-node.vue';
import { Tooltip as ATooltip, Popover as APopover } from 'ant-design-vue';
import { getFlowBaseIcon } from '@/utils/common/util';

export default defineComponent({
  name: 'X6VueShape',
  props: {
    // 节点信息
    nodeData: {
      type: Object
    },
    isShowAdd: {
      type: Boolean,
      default: true
    }
  },
  components: { X6AddNode, ATooltip, APopover },
  setup(props) {
    // store
    const workflowStore = useWorkflowStore();

    const { canAdd, addNodeItem } = X6ShapeUtil();

    // 名称
    const nameVal = ref('');
    // 设置值的内容
    const fitName = ref('未设置此节点');
    // 流程图标class
    const iconClass = ref('');

    // dom
    const x6VueShapeRef = ref(null);

    const nodeData2 = ref({});

    // 当前node数据
    const currentNodeData = ref({
      nodeId: '',
      groupList: []
    });

    // 边框颜色
    const borderColor = ref('');

    //
    const graph = ref(null);

    // 当前节点类型
    const currentType = ref();

    // 添加按钮列表
    const addButtonList = ref([
      {
        type: 'top',
        class: 'shape-top'
      },
      {
        type: 'right',
        class: 'shape-right'
      },
      {
        type: 'bottom',
        class: 'shape-bottom'
      },
      {
        type: 'left',
        class: 'shape-left'
      }
    ]);

    // 图片列表
    const iconList = ref(getFlowBaseIcon());

    // 当前节点状态
    const currentNodeStatus = ref(0);

    /**
     * 图标
     */
    const activeIconSrc = computed(() => {
      const icon = iconList.value.find(t => t.name == iconClass.value);
      return icon ? icon.url : '';
    });

    onMounted(() => {
      const data = props.nodeData;
      graph.value = workflowStore.graph;

      if (data) {
        iconClass.value = data.icon;
        nameVal.value = data.name;
        return;
      }

      const node = inject('getNode');
      if (!node) return;

      nodeData2.value = node();
      const nodeData = node()?.data ? JSON.parse(node().data) : null;
      setNodeData(nodeData);

      node().on('change:data', ({ current }) => {
        const updatedNodeData = JSON.parse(current);
        setNodeData(updatedNodeData);
      });
    });

    const setNodeData = data => {
      if (!data) return;

      const { icon, type, data: nodeData } = data;
      setNodeShowName(data);
      iconClass.value = icon;
      currentType.value = type;
      nameVal.value = nodeData.nodeName;

      if (nodeData?.borderColor) {
        borderColor.value = nodeData.borderColor;
        x6VueShapeRef.value.style.borderColor = nodeData.borderColor;
        currentNodeStatus.value = nodeData.nodeStatus;

        if (nodeData.nodeStatus === 20) {
          x6VueShapeRef.value.style.animation = 'twinkle 1s infinite alternate';
        }
      }
    };

    // 添加节点
    const addNode = (type, nodeItem) => {
      if (canAdd(nodeItem)) {
        const position = nodeData2.value.position();
        let x = position.x;
        let y = position.y;
        if (type == 'top') {
          if ([50, 51].includes(nodeItem.type)) {
            x = x + 86;
            y = y - 200;
          } else if ([10, 11].includes(nodeItem.type)) {
            x = x + 80;
            y = y - 150;
          } else {
            y = y - 200;
          }
        } else if (type == 'right') {
          if ([50, 51].includes(nodeItem.type)) {
            y = y - 10;
          } else if ([10, 11].includes(nodeItem.type)) {
            y = y + 18;
          }
          x = x + 350;
        } else if (type == 'bottom') {
          if ([50, 51].includes(nodeItem.type)) {
            x = x + 88;
          } else if ([10, 11].includes(nodeItem.type)) {
            x = x + 80;
          }
          y = y + 200;
        } else if (type == 'left') {
          if ([50, 51].includes(nodeItem.type)) {
            y = y - 10;
            x = x - 230;
          } else if ([10, 11].includes(nodeItem.type)) {
            y = y + 20;
            x = x - 200;
          } else {
            x = x - 350;
          }
        }
        addNodeItem(nodeItem, x, y, type, currentNodeData.value, nodeData2.value);
      }
    };

    // 设置当前节点展示的内容
    const setNodeShowName = nodeData => {
      const content = nodeData.data.nodeData;
      fitName.value = '';
      switch (nodeData.type) {
        // 审批、抄送
        case 30:
        case 31:
        case 32:
          if (
            content?.approverConfig?.mainApprover?.nodeApproverFormList?.length > 0 ||
            content?.approverConfig?.mainApprover?.nodeApproverPersonList?.length > 0 ||
            content?.approverConfig?.mainApprover?.nodeApproverPolicyList?.length > 0 ||
            content?.approverConfig?.mainApprover?.nodeApproverPositionList?.length > 0 ||
            content?.approverConfig?.mainApprover?.nodeApproverRoleList?.length > 0 ||
            content?.approverConfig?.mainApprover?.nodeApproverVariableList?.length > 0 ||
            content?.approverConfig?.mainApprover?.nodeApproverCustom
          ) {
            const {
              nodeApproverFormList,
              nodeApproverPersonList,
              nodeApproverPolicyList,
              nodeApproverPositionList,
              nodeApproverRoleList,
              nodeApproverVariableList,
              nodeApproverCustom,
              submitterSelfFlag,
              approverType
            } = content?.approverConfig?.mainApprover;

            // 从组织库中获取
            if (approverType == 10) {
              // 人员
              if (nodeApproverPersonList?.length > 0) {
                let name = nodeApproverPersonList.map(item => item.name).join('；');
                fitName.value = `用户： ${name}<br>`;
              }
              // 部门
              if (nodeApproverPolicyList?.length > 0) {
                let name = nodeApproverPolicyList
                  .map(item => {
                    if (item.selectScope == 10) {
                      return '指定部门-' + item.orgName;
                    } else if (item.selectScope == 20) {
                      return '发起人所在部门';
                    } else if (item.selectScope == 30) {
                      return '发起人所在公司';
                    }
                  })
                  .join('；');
                fitName.value += `部门：${name}<br>`;
              }
              // 职位
              if (nodeApproverPositionList?.length > 0) {
                let name = nodeApproverPositionList
                  .map(item => {
                    let valueName = '';
                    if (item?.orgName) {
                      valueName = item.orgName + '-';
                    }
                    valueName += item.positionName;
                    return valueName;
                  })
                  .join('；');
                fitName.value += `职位：${name}<br>`;
              }
              // 角色
              if (nodeApproverRoleList?.length > 0) {
                let name = nodeApproverRoleList.map(item => item.roleName).join('；');
                fitName.value += `角色： ${name}<br>`;
              }
            }
            // 表单
            if (approverType == 20 && nodeApproverFormList?.length > 0) {
              fitName.value += '从表单中获取';
            }
            // 流程变量
            if (approverType == 30 && nodeApproverVariableList?.length > 0) {
              fitName.value += '从流程变量中获取';
            }
            // 发起人自己
            if (approverType == 40 && submitterSelfFlag) {
              fitName.value += '发起人自己';
            }
            // 自定义规则
            if (approverType == 50 && nodeApproverCustom?.customName) {
              fitName.value += '自定义规则';
            }
            // 自由选择
            if (approverType == 60) {
              fitName.value += '自由选择';
            }
          } else {
            fitName.value = '未设置此节点';
          }
          break;
        case 60:
          if (content?.nodeCondition?.expressionString) {
            fitName.value = content.nodeCondition.expressionString;
          } else {
            fitName.value = '未设置此节点';
          }
          break;
        default:
          fitName.value = '已设置';
      }
    };

    watch(
      () => workflowStore.nodeData,
      val => {
        currentNodeData.value = val;
      },
      { deep: true, immediate: true }
    );

    return {
      nodeData2,
      nameVal,
      addNode,
      graph,
      fitName,
      iconList,
      iconClass,
      currentType,
      borderColor,
      setNodeData,
      currentNodeStatus,
      x6VueShapeRef,
      activeIconSrc,
      currentNodeData,
      setNodeShowName,
      addButtonList
    };
  }
});
</script>

<style scoped lang="less">
.x6-vue-shape {
  cursor: move;
  width: 100%;
  height: 76px;
  padding: 12px 16px 12px 16px;
  box-sizing: border-box;
  background-color: #fff;
  border-radius: 8px;
  position: relative;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  border: 1px solid #c5cfd166;
  position: relative;
  .node-name {
    height: 100%;
    font-size: 14px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-box-pack: justify;
    -ms-flex-pack: justify;
    display: flex;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    color: #60666b;

    .svg-img {
      width: 52px;
      height: 52px;
      margin-right: 10px;
    }

    .node-content {
      flex: auto;
      height: 100%;
      overflow: hidden;
    }

    .node-name-title {
      color: #60666b;
      font-size: 16px;
      width: 100%;
      font-weight: 500;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      -o-text-overflow: ellipsis;
    }
  }
  .node-main {
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    border-top: none;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    white-space: nowrap;
    overflow: hidden;
    -o-text-overflow: ellipsis;
    text-overflow: ellipsis;
    color: #60666b;
    font-size: 14px;

    div {
      height: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      color: #60666b;
      font-size: 14px;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
        'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
    }

    .hint-title {
      color: #ff6a00;
    }
  }

  &:hover {
    box-shadow: 0px 4px 8px 0px #00000014;
  }

  .flow-status-img {
    position: absolute;
    right: 0px;
    top: -4px;
  }
}
.x6-shape-add {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  .shape-top,
  .shape-right,
  .shape-bottom,
  .shape-left {
    position: absolute;
    &::before {
      position: absolute;
      left: 18px;
      top: 33px;
      content: '';
      width: 1.5px;
      height: 45px;
      background: #ccc;
    }
  }
  .shape-top {
    left: 50%;
    margin-left: -35px;
    top: -78px;
  }
  .shape-right {
    right: -63px;
    top: 19px;
    &::before {
      width: 45px;
      height: 1.5px;
      top: 18px;
      left: -40px;
    }
  }
  .shape-bottom {
    left: 50%;
    top: 115px;
    margin-left: -35px;
    &::before {
      left: 18px;
      top: -40px;
    }
  }
  .shape-left {
    left: -94px;
    top: 19px;
    &::before {
      width: 45px;
      height: 1.5px;
      top: 18px;
      left: 33px;
    }
  }
  .shape-img {
    cursor: pointer;
    width: 38px;
  }
}

.ant-menu-vertical {
  border: 0px !important;
}
:deep(.ant-menu-item) {
  width: 240px !important;
  height: 40px;
  line-height: 40px;
  color: #000;
  font-size: 14px;
  margin-left: -16px !important;
  margin-right: -16px !important;
  margin-bottom: 0px !important;
  &:hover {
    background: #f5f5f5;
    color: #000;
  }
}
:deep(.ant-menu-title-content) {
  display: flex;
  align-items: center;
}
</style>
