<template>
  <div class="flow-app-container">
    <!-- 顶部 -->
    <top v-if="showTop && optionType !== 'view'" :title="title" :lf="lf" :flowDetail="flowDetail"></top>
    <div class="logic-flow-view">
      <!-- 工具栏 -->
      <Control v-if="showLf && optionType !== 'view'" class="demo-control" :lf="lf"></Control>
      <!-- 左侧面板 -->
      <NodePanel v-if="showLf && optionType !== 'view'" :lf="lf" :title="title"></NodePanel>
      <!-- 画布 -->
      <div id="LF-view" ref="container"></div>
      <!-- 属性面板 -->
      <PropertyDialog v-if="showAttribute" :title="title" :nodeData="nodeData" :flowDetail="flowDetail" :optionType="props.optionType" :lf="lf" @closed="showAttribute = false"> </PropertyDialog>
    </div>
  </div>
</template>
<script setup name="design">
import variables from '@/assets/styles/variables.module.scss'
import { ref, onMounted, reactive, watch, toRefs } from 'vue';
import LogicFlow from '@logicflow/core';
import { Menu, Snapshot, MiniMap } from '@logicflow/extension';
import '@logicflow/core/dist/style/index.css';
import '@logicflow/extension/lib/style/index.css';
import start from './registerNode/start/start.js';
import definevar from './registerNode/definevar/definevar.js';
import sql from './registerNode/sql/sql.js';

import audio from './registerNode/audio/audio.js';
import audiodtmf from './registerNode/audiodtmf/audiodtmf.js';
import branch from './registerNode/branch/branch.js';
import queue from './registerNode/queue/queue.js';
import wait from './registerNode/wait/wait.js';
import transferout from './registerNode/transferout/transferout.js';
import leaveword from './registerNode/leaveword/leaveword.js';
import hangup from './registerNode/hangup/hangup.js';
// import call from './registerNode/call/call.js';
// import know from './registerNode/know/know.js';
// import sms from './registerNode/sms/sms.js';
// import survey from './registerNode/survey/survey.js';
import registerBezier from './registerEdge/registerBezier.js';
import { getNodeOutputCount, getNodeInputCount } from '@/utils/index';
import PropertyDialog from './PropertySetting/PropertyDialog.vue';
import NodePanel from './LFComponents/NodePanel.vue';
import Control from './LFComponents/Control.vue';
import top from './LFComponents/top.vue';
import { ElMessage } from 'element-plus';
// import { getPageListData } from '@/api/main/system/system';

const props = defineProps({
  title: {
    type: String,
    default: '',
  },
  optionType: {
    type: String,
    default: '',
  },
  cycleId: {
    type: Number,
    default: 3,
  },
  successNodes: {
    type: Array,
    default: [],
  }
});

let { cycleId, successNodes } = toRefs(props);


let lf = reactive({});
let showAddPanel = ref(false);
let addPanelStyle = reactive({
  top: 0,
  left: 0,
});
let nodeData = ref(null);
let addClickNode = ref(null);
let showAttribute = ref(false);
let dataVisible = ref(false);
let config = reactive({
  background: {
    backgroundColor: variables.dragPanelBgColor,
  },
  grid: {
    size: 10,
    visible: false,
  },
  keyboard: {
    enabled: true,
  },
  adjustEdge: false, //允许调整边
  adjustEdgeStartAndEnd: false, //是否允许拖动边的端点来调整连线
  edgeSelectedOutline: true, //鼠标 hover 的时候显示边的外框
  // edgeTextDraggable: true,
  hoverOutline: false,
  nodeTextEdit: false, //节点是否可编辑。false不可编辑
  edgeTextEdit: false, //边是否可编辑。false不可编辑
  autoExpand: false, //点拖动靠近画布边缘时是否自动扩充画布
  textEdit: false, //是否开启文本编辑
  snapline: false, //对齐线。false不开启
});
let flowDetail = reactive({});
let container = ref(null);
let showLf = ref(false);
let showTop = ref(false);

const $_initLf = () => {
  // 画布配置
  const myLf = new LogicFlow({
    ...config,
    plugins: [Menu, MiniMap, Snapshot],
    container: container.value,
  });
  lf = myLf;
  showLf.value = true;
  // 设置主题
  lf.setTheme({
    baseNode: {
      fill: '#FFFFFF',
      stroke: '#000000',
      strokeWidth: 1,
    },
    circle: {
      stroke: '#000000',
      strokeWidth: 1,
    },
    rect: {
      fill: '#FFFFFF',
      stroke: '#000000',
      outlineColor: '#88f',
      strokeWidth: 1,
    },
    polygon: {
      strokeWidth: 1,
    },
    polyline: {
      stroke: '#000000',
      hoverStroke: '#000000',
      selectedStroke: '#000000',
      strokeWidth: 1,
    },
    nodeText: {
      color: '#000000',
      overflowMode: 'ellipsis', //超出显示省略号
      padding: '0 15px',
      fontSize: 14,
    },
    edgeText: {
      color: '#000000',
      background: {
        fill: variables.dragPanelBgColor,
      },
    },
  });
  lf.setDefaultEdgeType('myBezier'); //线类型，贝塞尔曲线

  $_registerNode();
};

// 自定义
const $_registerNode = () => {
  start(lf);
  definevar(lf);
  audio(lf);
  audiodtmf(lf);
  branch(lf);
  queue(lf);
  wait(lf);
  transferout(lf);
  leaveword(lf);
  hangup(lf);
  sql(lf);
  // 'start', 'definevar', 'sql', 'audio', 'audiodtmf', 'branch', 'queue', 'wait', 'transferout', 'leaveword', 'hangup'
  
  lf.register(registerBezier);
  $_render();
};

const $_render = async () => {

  let flowJson = {};
  if (cycleId.value) {
    // 获取数据
    const result = null;//await getPageListData(`/cycle/cycleplan/${cycleId.value}`);
    console.log(result)
    if (result && result.data?.planDetails) {
      const details = JSON.parse(result.data.planDetails);
      // successNodes
      if (details.nodes && successNodes.value && successNodes.value.length > 0) {
        details.nodes = details.nodes.map((item) => {
          if (successNodes.value.includes(item.id)) {
            item.properties['success'] = 1
          }
          return item;
        })
      }
      flowJson = details;

      flowDetail = {
        flowName: result.name,
        flowId: cycleId.value,
        flowJson,
      }
    }
    
  }

  console.log(flowJson, 'flowJson')

  showTop.value = true;
  lf.render(flowJson); //回显
  $_LfEvent();
};

const $_LfEvent = () => {
  lf.on('node:dbclick', ({ data }) => {
    nodeData.value = data;
    if (['start', 'definevar', 'sql', 'audio', 'audiodtmf', 'branch', 'queue', 'wait', 'transferout', 'leaveword', 'hangup'].includes(data.type)) {
      showAttribute.value = true;
    }
  });
  lf.on('node:delete', ({ data }) => {
    // nodeData.value = data;
    // if (['start', 'call', 'know', 'sms', 'survey'].includes(data.type)) {
    //   showAttribute.value = true;
    // }

    if (data.type === 'start') return false;

    console.log(data, 'delete');
  });
  lf.on('edge:dbclick', ({ data }) => {
    nodeData.value = data;
    // showAttribute.value = true;
  });
  //来自边的事件中心发出的事件
  lf.on('edge:app-config', (res) => {
    nodeData.value = res;
    // showAttribute.value = true;
  });
  lf.on('element:click', () => {
    hideAddPanel();
  });
  lf.on('blank:click', () => {
    hideAddPanel();
  });
  lf.on('connection:not-allowed', (data) => {
    if (data.msg) {
      console.log(data.msg)
      ElMessage({
        type: 'error',
        message: data.msg,
        duration: 8000,
      });
    }
  });

  lf.on('edge:add', ({ data }) => {
    console.log(data, 'edge:add');
    setEdgeType(data);
    setStartParallelStatus(data);
    setEndParallelStatus(data);
  });

  lf.on('edge:delete', ({ data }) => {
    setStartParallelStatus(data);
    setEndParallelStatus(data);
  });
};

const hideAddPanel = () => {
  showAddPanel.value = false;
  addPanelStyle.top = 0;
  addPanelStyle.left = 0;
  addClickNode.value = null;
};

//设置边类型
const setEdgeType = (data) => {
  let sourceNode = lf.getGraphData().nodes.filter((i) => {
    return i.id === data.sourceNodeId;
  })[0];
  if (sourceNode.type == 'start') {
    lf.setProperties(data.id, {
      edgeType: 'start',
    });
  } else if (sourceNode.type == 'assignment') {
    lf.setProperties(data.id, {
      edgeType: 'nextStep',
    });
  } else if (sourceNode.type == 'decision') {
    lf.setProperties(data.id, {
      type: 'normal', //边类型
      edgeType: '',
    });
  } else {
    lf.setProperties(data.id, {
      edgeType: 'nextStep',
    });
  }
};

//设置并行开始节点状态
const setStartParallelStatus = (data) => {
  let graphData = lf.getGraphData();
  graphData.nodes.forEach((i) => {
    if (i.type == 'startParallel') {
      if (i.id == data.sourceNodeId) {
        let count = getNodeOutputCount(graphData, i);
        if (count >= 2) {
          lf.setProperties(data.sourceNodeId, {
            frontend_status: '1', //0配置错误，1配置正常
          });
        } else {
          lf.setProperties(data.sourceNodeId, {
            frontend_status: '0', //0配置错误，1配置正常
          });
        }
      }
    }
  });
};

//设置并行结束节点状态
const setEndParallelStatus = (data) => {
  let graphData = lf.getGraphData();
  graphData.nodes.forEach((i) => {
    if (i.type == 'endParallel') {
      if (i.id == data.targetNodeId) {
        let count = getNodeInputCount(graphData, i);
        if (count >= 2) {
          lf.setProperties(data.targetNodeId, {
            frontend_status: '1', //0配置错误，1配置正常
          });
        } else {
          lf.setProperties(data.targetNodeId, {
            frontend_status: '0', //0配置错误，1配置正常
          });
        }
      }
    }
  });
};

watch(() => cycleId.value, (newVal) => {
  console.log('watch');
  $_initLf();
},() => successNodes.value, (newVal) => {
  console.log('watch2');
  $_initLf();
})


onMounted(() => {
  $_initLf();
});

const change = (id, successNodes) => {
  $_initLf();
}

defineExpose({
  change,
})

</script>
<style lang="scss">
@import '@/assets/styles/variables.module.scss';
.logic-flow-view {
  height: 86vh;
  position: relative;
}
.demo-title {
  text-align: center;
  margin: 20px;
}
.demo-control {
  position: absolute;
  top: 15px;
  right: 100px;
  z-index: 2;
}
#LF-view {
  width: 100%;
  height: 100%;
  outline: none;
}
.time-plus {
  cursor: pointer;
}
.add-panel {
  position: absolute;
  z-index: 11;
  background-color: white;
  padding: 10px 5px;
}
.el-drawer__body {
  height: 80%;
  overflow: auto;
  margin-top: -30px;
  z-index: 3;
}

.lf-node-text-auto-wrap {
  cursor: pointer;
}

/* 适应节点图标 */
.lf-node-text-ellipsis-content {
  padding: 0 8px 0 34px !important;
}
.node-title {
  height: 40px;
  width: 100%;
  background: #fff;
  border: 1px solid #e6f7ff;
  box-sizing: border-box;
  padding: 10px 10px 10px 6px;
  border-radius: 8px;
  cursor: pointer;
}
.node-icon {
  width: 26px;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 18px;
}
.node-name > span {
  border: none !important;
}

//logicflow小地图
.lf-mini-map {
  border-radius: $appRadius;
  border: none !important;
  box-shadow: 3px 0 10px 1px rgb(228, 224, 219);
}

.lf-mini-map-header {
  border: none !important;
  font-size: 13px;
  height: 24px !important;
  line-height: 24px !important;
  // color: #fff;
  background-color: #ecf5ff !important;
  background-image: none !important;
}

.lf-mini-map-close {
  top: 2px !important;
}

@keyframes lf_animate_dash {
  to {
    stroke-dashoffset: 0;
  }
}
</style>
