<template>
<div>
  <el-dialog
    :title="display ? '工艺详情' : '新建工艺'"
    width="70%"
    :close-on-click-modal="false"
    :visible.sync="visible">
    <el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="auto">
      <el-row class="my-row">
        <el-col :span="8">
          <el-form-item label="工艺名称" prop="techName">
            <el-input v-model="dataForm.techName" :disabled="display" placeholder="工艺名称"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="工艺版本" prop="techVersion">
            <el-input v-model="dataForm.techVersion" :disabled="display" placeholder="工艺版本"></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="产品" prop="productId">
            <el-select
              v-model="dataForm.productId"
              :disabled="display"
              remote
              placeholder="请选择">
              <el-option
                v-for="item in optionLevel"
                :key="item.productId"
                :label="item.productName"
                :value="item.productId">
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-form-item label="备注说明">
        <el-input v-model="dataForm.notes" :disabled="display" placeholder="备注说明"></el-input>
      </el-form-item>
      <el-form-item label="" label-width="0px">
        <upload-component :display="display" :title="'附件'" :accept="'*'" :file-obj-list="fileList" @uploadSuccess="uploadSuccess"/>
      </el-form-item>

      <!-- <div class="super-flow-demo1">
        <div class="node-container">
          <span
              class="node-item"
              v-for="item in nodeItemList"
              @mousedown="evt => nodeItemMouseDown(evt, item.value)">
            {{ item.label }}
          </span>
        </div>
        <div
            class="flow-container"
            ref="flowContainer">
          <super-flow
              ref="superFlow"
              :graph-menu="graphMenuList"
              :node-menu="nodeMenuList"
              :link-menu="linkMenuList"
              :link-base-style="linkBaseStyle"
              :link-style="linkStyle"
              :link-desc="linkDesc">
            <template v-slot:node="{meta}">
              <div
                  @mouseup="nodeMouseUp"
                  @click="nodeClick"
                  class="flow-node ellipsis">
                {{ meta.name }}
              </div>
            </template>
          </super-flow>
        </div>
      </div> -->

      <el-form-item label="工艺步骤" prop="nodeList">
      </el-form-item>
      <el-row class="my-row" style="height: 350px; background-color: #efefef;">
        <super-flow
          v-if="visible"
          ref="superFlow"
          :node-list="nodeList"
          :link-list="linkList"
          :graph-menu="graphMenuList"
          :node-menu="nodeMenuList"
          :link-menu="linkMenuList"
          :link-desc="linkDesc">
          <!-- <template v-slot="node">
            <div class="flow-node ellipsis">
              {{ node }}
            </div>
          </template> -->
        </super-flow>
      </el-row>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="visible = false">取消</el-button>
      <el-button v-if="!display" type="primary" @click="dataFormSubmit()">确定</el-button>
    </span>
  </el-dialog>

  <el-dialog
        :title="drawerConf.title"
        :visible.sync="drawerConf.visible"
        :close-on-click-modal="false"
        width="500px">
      <el-form
          @keyup.native.enter="settingSubmit"
          @submit.native.prevent
          v-show="drawerConf.type === drawerType.node"
          ref="nodeSetting"
          :rules="dataRule1"
          :model="nodeSetting">
        <el-row class="my-row">
          <el-col :span="24">
            <el-form-item
                label="节点名称"
                prop="name">
              <el-input
                  v-model="nodeSetting.name"
                  placeholder="请输入节点名称"
                  maxlength="30">
              </el-input>
            </el-form-item>
          </el-col>
          <el-col v-if="drawerConf.prop !== 'start' && drawerConf.prop !== 'end'" :span="12">
            <el-form-item
                label="节点类型"
                prop="type">
                <el-select
                  v-model="nodeSetting.type"
                  placeholder="请选择">
                <el-option
                  v-for="item in optionsType"
                  :key="item.value"
                  :label="item.name"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col v-if="drawerConf.prop !== 'end'" :span="12">
            <el-form-item
              label="工种"
              prop="workTypeId">
              <el-select
                v-model="nodeSetting.workTypeId"
                placeholder="请选择">
                <el-option
                  v-for="item in optionsType1"
                  :key="item.typeId"
                  :label="item.name"
                  :value="item.typeId">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item
                label="节点备注"
                prop="desc">
              <el-input
                  v-model="nodeSetting.desc"
                  placeholder="请输入节点备注"
                  maxlength="30">
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <!-- <el-form
          @keyup.native.enter="settingSubmit"
          @submit.native.prevent
          v-show="drawerConf.type === drawerType.link"
          ref="linkSetting"
          :model="linkSetting">
        <el-form-item
            label="连线描述"
            prop="desc">
          <el-input
              v-model="linkSetting.desc"
              placeholder="请输入连线描述">
          </el-input>
        </el-form-item>
      </el-form> -->
      <span
          slot="footer"
          class="dialog-footer">
        <el-button
            @click="drawerConf.cancel">
          取 消
        </el-button>
        <el-button
            type="primary"
            @click="settingSubmit">
          确 定
        </el-button>
      </span>
    </el-dialog>
</div>
</template>

<script>
  import { getInfo, getProduct, getWorkType, getStepId } from '@/api/crafts'
  import { uuid } from '../common/vue-super-flow/utils'
  import UploadComponent from '../common/upload-component'
  const drawerType = {
    node: 0,
    link: 1
  }
  export default {
    name: 'add-or-update',
    components: {UploadComponent},
    computed: {
      orgId: {
        get () { return this.$store.state.user.orgId }
      }
    },
    data () {
      return {
        drawerType,
        optionsType: [{value: '1', name: '生产'}, {value: '2', name: '检验'}],
        optionsType1: [],
        drawerConf: {
          title: '',
          visible: false,
          prop: '',
          type: null,
          info: null,
          open: (type, info) => {
            const conf = this.drawerConf
            conf.visible = true
            conf.type = type
            conf.info = info
            if (conf.type === drawerType.node) {
              conf.title = '节点'
              conf.prop = info.meta.prop
              if (this.$refs.nodeSetting) this.$refs.nodeSetting.resetFields()
              this.$set(this.nodeSetting, 'name', info.meta.name)
              this.$set(this.nodeSetting, 'desc', info.meta.desc)
              this.$set(this.nodeSetting, 'type', info.meta.type)
              this.$set(this.nodeSetting, 'workTypeId', info.meta.workTypeId)
            } else {
              conf.title = '连线'
              if (this.$refs.linkSetting) this.$refs.linkSetting.resetFields()
              // this.$set(this.linkSetting, 'desc', info.meta ? info.meta.desc : '')
            }
          },
          cancel: () => {
            this.drawerConf.visible = false
            if (this.drawerConf.type === drawerType.node) {
              this.$refs.nodeSetting.clearValidate()
            } else {
              this.$refs.linkSetting.clearValidate()
            }
          }
        },
        linkSetting: {
          desc: ''
        },
        nodeSetting: {
          name: '',
          desc: '',
          type: 1,
          workTypeId: ''
        },
        nodeList: [],
        linkList: [],
        datas: {},
        graphMenuList: [
          [
            {
              label: '开始节点',
              disable (graph) {
                return !!graph.nodeList.find(node => node.meta.prop === 'start')
              },
              selected: async (graph, coordinate) => {
                const start = graph.nodeList.find(node => node.meta.prop === 'start')
                let id = ''
                await getStepId().then(({ data }) => {
                  id = data.data.stepId
                })
                if (!start) {
                  graph.addNode({
                    width: 90,
                    height: 50,
                    coordinate: coordinate,
                    id: id,
                    meta: {
                      prop: 'start',
                      name: '开始节点'
                    }
                  })
                }
              }
            },
            {
              label: '节点',
              disable: false,
              selected: async (graph, coordinate) => {
                let id = ''
                await getStepId().then(({ data }) => {
                  id = data.data.stepId
                })
                graph.addNode({
                  width: 120,
                  height: 70,
                  coordinate: coordinate,
                  id: id,
                  meta: {
                    prop: 'condition',
                    name: '节点名称'
                  }
                })
              }
            },
            {
              label: '结束节点',
              disable (graph) {
                return !!graph.nodeList.find(point => point.meta.prop === 'end')
              },
              selected: async (graph, coordinate) => {
                let id = ''
                await getStepId().then(({ data }) => {
                  id = data.data.stepId
                })
                graph.addNode({
                  width: 90,
                  height: 50,
                  coordinate: coordinate,
                  id: id,
                  meta: {
                    prop: 'end',
                    name: '结束节点'
                  }
                })
              }
            }
          ],
          [
            {
              label: '完成',
              selected: (graph, coordinate) => {
                graph.selectAll()
                this.datas = graph
                console.log(graph)
              }
            }
          ]
        ],
        nodeMenuList: [
          [
            {
              label: '删除',
              disable: false,
              hidden (node) {
                return node.meta.prop === 'start'
              },
              selected (node, coordinate) {
                node.remove()
              }
            }
          ],
          [
            {
              label: '编辑',
              selected: (node, coordinate) => {
                this.drawerConf.open(drawerType.node, node)
              }
            }
          ]
        ],
        linkMenuList: [
          [
            {
              label: '删除',
              selected: (link, coordinate) => {
                link.remove()
              }
            }
          ]
          // [
          //   {
          //     label: '编辑',
          //     selected: (link, coordinate) => {
          //       this.drawerConf.open(drawerType.link, link)
          //     }
          //   }
          // ]
        ],
        visible: false,
        display: false,
        fileList: [],
        dataList: [],
        id: 0,
        dataForm: {
          techName: '',
          techVersion: '',
          productId: '',
          notes: ''
        },
        previewPath: '',
        previewName: '',
        previewVisible: false,
        optionsProducts: [],
        optionLevel: [],
        nodeItemList: [
          {
            label: '开始节点',
            value: () => ({
              width: 120,
              height: 40,
              meta: {
                prop: 'start',
                name: '开始节点'
              }
            })
          },
          {
            label: '节点',
            value: () => ({
              width: 120,
              height: 40,
              meta: {
                prop: 'condition',
                name: '节点'
              }
            })
          },
          {
            label: '结束节点',
            value: () => ({
              width: 120,
              height: 40,
              meta: {
                prop: 'end',
                name: '结束节点'
              }
            })
          }
        ],
        dragConf: {
          isDown: false,
          isMove: false,
          offsetTop: 0,
          offsetLeft: 0,
          clientX: 0,
          clientY: 0,
          ele: null,
          info: null
        },
        linkBaseStyle: {
          color: '#666666',           // line 颜色
          hover: '#FF0000',           // line hover 的颜色
          textColor: '#666666',       // line 描述文字颜色
          textHover: '#FF0000',       // line 描述文字 hover 颜色
          font: '14px Arial',         // line 描述文字 字体设置 参考 canvas font
          dotted: false,              // 是否是虚线
          lineDash: [4, 4],           // 虚线时生效
          background: 'rgba(255,255,255,0.6)'    // 描述文字背景色
        },
        dataRule: {
          techName: [{ required: true, message: '工艺名称不能为空', trigger: 'blur' }],
          techVersion: [{ required: true, message: '工艺版本不能为空', trigger: 'blur' }],
          productId: [{ required: true, message: '产品不能为空', trigger: 'change' }]
        },
        dataRule1: {
          name: [{ required: true, message: '节点名称不能为空', trigger: 'blur' }],
          type: [{ required: true, message: '节点类型不能为空', trigger: 'change' }],
          workTypeId: [{ required: true, message: '工种不能为空', trigger: 'change' }]
        }
      }
    },
    created () {
      this.getWorkType()
    },
    methods: {
      async init (id, display) {
        this.nodeList = []
        this.linkList = []
        this.dataForm = {
          techName: '',
          techVersion: '',
          productId: '',
          notes: ''
        }
        this.visible = true
        this.display = display
        await getProduct({ current: 1, size: 20000 }).then(({data}) => {
          if (data && data.code === '200') {
            this.optionLevel = data.data.records
          }
        })
        if (!id) return
        await getInfo(id).then(async ({data}) => {
          if (data && data.code === '200') {
            this.dataForm = data.data
            // 图纸
            if (data.data.proTechnologyStepLists) {
              const dataline = []
              const datanode = []
              await data.data.proTechnologyStepLists.forEach((v, i) => {
                // eslint-disable-next-line no-unused-vars
                const sortNo = []
                const datas = v.sort((a, b) => Number(a['sortNo']) - Number(b['sortNo']))
                datas.forEach((item, index) => {
                  const find = datanode.find(map => map.id === item.stepId)
                  if (!find) {
                    datanode.push({
                      id: item.stepId,
                      width: (index === 0 || item.workTypeId === '0') ? 90 : 120,
                      height: (index === 0 || item.workTypeId === '0') ? 50 : 70,
                      coordinate: item.coordinate.split(','),
                      meta: {
                        name: item.stepName,
                        notes: item.notes || '',
                        workTypeId: item.workTypeId || '',
                        type: item.type || ''
                      }
                    })
                  }
                  const id = item.stepId
                  if ((index + 1) < datas.length) {
                    if (datas[index + 1]) {
                      dataline.push({
                        id: uuid('link'),
                        startId: id,
                        endId: datas[index + 1].stepId,
                        meta: '',
                        startAt: [(index === 0 || item.workTypeId === '0') ? 90 : 120, (index === 0 || item.workTypeId === '0') ? 25 : 35],
                        endAt: [0, (index === 0 || item.workTypeId === '0') ? 25 : 35]
                      })
                    }
                  }
                })
              })
              this.$nextTick(() => {
                setTimeout(() => {
                  this.nodeList = datanode
                  this.linkList = dataline
                }, 200)
              })
            }
          }
        })
      },
      getWorkType () {
        getWorkType().then(({data}) => {
          if (data && data.code === '200') {
            this.optionsType1 = data.data
          }
        })
      },
      handleRemove (file, fileList) {
        this.fileList = fileList
      },
      handleChange (file, fileList) {
        this.fileList = fileList
      },
      handleExceed (files, fileList) {
        this.$message.warning(`当前限制选择 5 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`)
      },
      validateField (type) {
        this.$refs.dataForm.validateField(type)
      },
      getLineData (dataAll, dList, lList, id, sortNo) {
        debugger
        const _l = []
        lList.forEach(l => {
          if (l.start.id === id) {
            _l.push(l.end.id)
          }
        })
        if (!sortNo) {
          const data = dList.filter(v => v.meta.prop === 'start')[0]
          _l.forEach(item => {
            dataAll.push([{
              'notes': data.meta.desc || '',
              'sortNo': 0,
              'stepId': data.id,
              'stepName': data.meta.name,
              'workTypeId':  v.meta.prop === 'end' ? '4' : (data.meta.workTypeId || null),
              'type': data.meta.type || null,
              'coordinate': data.coordinate.join(',')
            }])
          })
        }
        dList.forEach(v => {
          const _i = _l.indexOf(v.id)
          if (_i > -1) {
            if (!v.meta.workTypeId && v.meta.prop !== 'end') {
              this.$message.error('完善节点工种')
              return
            }
            if (!sortNo) {
              dataAll[_i].push({
                'notes': v.meta.desc || '',
                'sortNo': (sortNo + 1),
                'stepId': v.id,
                'stepName': v.meta.name,
                'workTypeId': v.meta.prop === 'end' ? '4' : (v.meta.workTypeId || null),
                'type': v.meta.type || null,
                'coordinate': v.coordinate.join(',')
              })
              this.getLineData(dataAll[_i], dList, lList, v.id, (sortNo + 1))
            } else {
              let _has = false
              dataAll.forEach(items => {
                if (items.stepId === v.id) {
                  _has = true
                }
              })
              if (!_has) {
                dataAll.push({
                  'notes': v.meta.desc || '',
                  'sortNo': (sortNo + 1),
                  'stepId': v.id,
                  'stepName': v.meta.name,
                  'workTypeId': v.meta.prop === 'end' ? 4 : (v.meta.workTypeId || ''),
                  'type': v.meta.type || '',
                  'coordinate': v.coordinate.join(',')
                })
              }
              this.getLineData(dataAll, dList, lList, v.id, (sortNo + 1))
            }
          }
        })
      },
      // 表单提交
      dataFormSubmit () {
        if (!this.datas.nodeList) {
          this.$message.error('请先完成流程图！')
          return
        }
        if (this.datas.nodeList.length <= 2) {
          this.$message.error('请先完成流程图！')
          return
        }

        this.$refs['dataForm'].validate((valid) => {
          if (valid) {
            const proTechnologyStepLists = []
            let has = false
            let has1 = false
            this.datas.nodeList.forEach(v => {
              if (v.meta.prop === 'start') {
                has = true
                this.getLineData(proTechnologyStepLists, this.datas.nodeList, this.datas.linkList, v.id, 0)
              }
              if (v.meta.prop === 'end') {
                has1 = true
              }
            })
            if (!has) {
              this.$message.error('成流程图没有开始结点！')
              return
            }
            if (!has1) {
              this.$message.error('成流程图没有结束结点！')
              return
            }
            if (proTechnologyStepLists.length === 0) {
              this.$message.error('请先完成流程图！')
              return
            }

            // 填充附件
            let fList = this.fileList
            if (fList.length > 0) {
              this.dataForm.attachList = []
              for (let i = 0; i < fList.length; i++) {
                this.dataForm.attachList.push({
                  fileName: fList[i].name,
                  url: fList[i].url
                })
              }
            }

            this.$http({
              url: this.$http.adornUrl(`/biz-service/technology/submit`),
              method: 'post',
              data: this.$http.adornData({...this.dataForm, proTechnologyStepLists: proTechnologyStepLists})
            }).then(({data}) => {
              if (data && data.code === '200') {
                this.$message({
                  message: '操作成功',
                  type: 'success',
                  duration: 1500,
                  onClose: () => {
                    this.$emit('refreshDataList')
                    this.visible = false
                  }
                })
              } else {
                this.$message.error(data.msg)
              }
            })
          }
        })
      },
      enterIntercept (formNode, toNode, graph) {
        const formType = formNode.meta.prop
        switch (toNode.meta.prop) {
          case 'start':
            return false
          case 'approval':
            return [
              'start',
              'approval',
              'condition',
              'cc'
            ].includes(formType)
          case 'condition':
            return [
              'start',
              'approval',
              'condition',
              'cc'
            ].includes(formType)
          case 'end':
            return [
              'approval',
              'cc'
            ].includes(formType)
          default:
            return true
        }
      },
      outputIntercept (node, graph) {
        return !(node.meta.prop === 'end')
      },
      linkDesc (link) {
        return link.meta ? link.meta.desc : ''
      },
      settingSubmit () {
        this.$refs['nodeSetting'].validate((valid) => {
          if (valid) {
            const conf = this.drawerConf
            // 节点
            if (this.drawerConf.type === drawerType.node) {
              if (!conf.info.meta) conf.info.meta = {}
              Object.keys(this.nodeSetting).forEach(key => {
                this.$set(conf.info.meta, key, this.nodeSetting[key])
              })
              this.$refs.nodeSetting.resetFields()
            } else {
              // 连线
              if (!conf.info.meta) conf.info.meta = {}
              Object.keys(this.linkSetting).forEach(key => {
                this.$set(conf.info.meta, key, this.linkSetting[key])
              })
              this.$refs.linkSetting.resetFields()
            }
            conf.visible = false
          }
        })
      },
      uploadSuccess (fileList) {
        this.fileList = fileList
      },
      docMousemove ({ clientX, clientY }) {
        const conf = this.dragConf

        if (conf.isMove) {
          conf.ele.style.top = clientY - conf.offsetTop + 'px'
          conf.ele.style.left = clientX - conf.offsetLeft + 'px'
        } else if (conf.isDown) {
          // 鼠标移动量大于 5 时 移动状态生效
          conf.isMove =
              Math.abs(clientX - conf.clientX) > 5 || Math.abs(clientY - conf.clientY) > 5
        }
      },
      docMouseup ({ clientX, clientY }) {
        const conf = this.dragConf
        conf.isDown = false

        if (conf.isMove) {
          const {
            top,
            right,
            bottom,
            left
          } = this.$refs.flowContainer.getBoundingClientRect()

          // 判断鼠标是否进入 flow container
          if (clientX > left && clientX < right && clientY > top && clientY < bottom) {
            // 获取拖动元素左上角相对 super flow 区域原点坐标
            const coordinate = this.$refs.superFlow.getMouseCoordinate(
                clientX - conf.offsetLeft,
                clientY - conf.offsetTop
            )

            // 添加节点
            this.$refs.superFlow.addNode({
              coordinate,
              ...conf.info
            })
          }

          conf.isMove = false
        }

        if (conf.ele) {
          conf.ele.remove()
          conf.ele = null
        }
      },
      nodeItemMouseDown (evt, infoFun) {
        const {
          clientX,
          clientY,
          currentTarget
        } = evt

        const {
          top,
          left
        } = evt.currentTarget.getBoundingClientRect()

        const conf = this.dragConf
        const ele = currentTarget.cloneNode(true)

        Object.assign(this.dragConf, {
          offsetLeft: clientX - left,
          offsetTop: clientY - top,
          clientX: clientX,
          clientY: clientY,
          info: infoFun(),
          ele,
          isDown: true
        })

        ele.style.position = 'fixed'
        ele.style.margin = '0'
        ele.style.top = clientY - conf.offsetTop + 'px'
        ele.style.left = clientX - conf.offsetLeft + 'px'

        this.$el.appendChild(this.dragConf.ele)
      },
      linkStyle (link) {
        if (link.meta && link.meta.desc === '1') {
          return {
            color: 'red',
            hover: '#FF00FF',
            dotted: true
          }
        } else {
          return {}
        }
      },
      nodeMouseUp (evt) {
        evt.preventDefault()
      },
      nodeClick () {
        console.log(arguments)
      }
    }
  }
</script>

<style lang="less" scoped>
.super-flow__node {
    .flow-node {
      > header {
        font-size   : 14px;
        height      : 32px;
        line-height : 32px;
        padding     : 0 12px;
        color       : #ffffff;
      }

      > section {
        text-align  : center;
        line-height : 20px;
        overflow    : hidden;
        padding     : 6px 12px;
        word-break  : break-all;
      }

      &.flow-node-start {
        > header {
          background-color : #55abfc;
        }
      }

      &.flow-node-condition {
        > header {
          background-color : #BC1D16;
        }
      }

      &.flow-node-approval {
        > header {
          background-color : rgba(188, 181, 58, 0.76);
        }
      }

      &.flow-node-cc {
        > header {
          background-color : #30b95c;
        }
      }

      &.flow-node-end {
        > header {
          height           : 50px;
          line-height      : 50px;
          background-color : rgb(0, 0, 0);
        }
      }
    }
  }
</style>
