<template>
  <MDialog ref="editDialog" v-bind="$attrs" @sure="handleSaveEdit">
    <MForm ref="editForm" :items="editForm" v-model="editValues">
      <template #parentId>
        <el-popover
          placement="bottom"
          width="600"
          trigger="click">
          <div class="popover-tree">
            <el-tree
              :data="itemsParents"
              node-key="id"
              ref="tree"
              highlight-current
              auto-expand-parent
              :expand-on-click-node="false"
              :default-expanded-keys="[0]"
              @node-click="nodeClick"
              :props="{
                children: 'children',
                label: 'label'
              }">
            </el-tree>
          </div>

          <el-input
            slot="reference"
            v-model="currentNodeName"
            placeholder="请选择根菜单"
            readonly
          ></el-input>
        </el-popover>
      </template>
    </MForm>
  </MDialog>
</template>

<script>
import { MENU_TYPE } from '@/utils/dict'
export default {
  name: 'menu-edit',
  data () {
    return {
      itemsParents: [],
      editValues: {},
      currentNodeName: null,
      isEdit: null
    }
  },
  computed: {
    editForm () {
      const type = this.editValues.type
      return [
        {
          label: '上级菜单',
          prop: 'parentId',
          rules: [{ required: true, message: '请选择上级菜单', trigger: 'change' }]
        },
        {
          label: '菜单名称',
          prop: 'label',
          type: 'input',
          options: { placeholder: '请输入菜单名称' },
          rules: [{ required: true, message: '请输入菜单名称', trigger: 'change' }]
        },
        {
          label: '菜单类型',
          prop: 'type',
          type: 'radioGroup',
          button: true,
          options: {
            size: 'small',
            items: [
              { text: '目录', label: MENU_TYPE.DIRECTORY },
              { text: '菜单', label: MENU_TYPE.MENU },
              { text: '按钮', label: MENU_TYPE.BUTTON },
              { text: '组件', label: MENU_TYPE.COMPONENT }
            ]
          }
        },
        {
          label: '菜单图标',
          prop: 'icon',
          hidden: [MENU_TYPE.BUTTON].includes(type),
          type: 'input',
          options: { placeholder: '请输入菜单图标' }
        },
        {
          label: '路由地址',
          prop: 'path',
          hidden: [MENU_TYPE.BUTTON, MENU_TYPE.COMPONENT].includes(type),
          type: 'input',
          options: { placeholder: '请输入路由地址' },
          rules: [{ required: true, message: '请输入路由地址', trigger: 'change' }]
        },
        {
          label: '组件地址',
          prop: 'component',
          hidden: [MENU_TYPE.BUTTON].includes(type),
          type: 'input',
          options: { placeholder: '请输入组件地址' },
          rules: [{ required: type !== 0, message: '请输入组件地址', trigger: 'change' }]
        },
        {
          label: '组件名称',
          prop: 'name',
          hidden: [MENU_TYPE.BUTTON].includes(type),
          type: 'input',
          options: { placeholder: '请输入组件名称' },
          rules: [{ required: true, message: '请输入组件名称', trigger: 'change' }]
        },
        {
          label: '权限标识',
          prop: 'code',
          hidden: [MENU_TYPE.DIRECTORY, MENU_TYPE.MENU, MENU_TYPE.COMPONENT].includes(type),
          type: 'input',
          options: { placeholder: '请输入权限标识' },
          rules: [{ required: true, message: '请输入权限标识', trigger: 'change' }]
        },
        {
          label: '显示排序',
          prop: 'sort',
          type: 'number',
          options: { placeholder: '显示排序' },
          rules: [{ required: true, message: '请输入排序序号', trigger: 'change' }]
        },
        {
          label: '显示状态',
          prop: 'hidden',
          type: 'radioGroup',
          options: {
            items: [
              { text: '显示', label: 1 },
              { text: '隐藏', label: 0 }
            ]
          }
        },
        {
          label: '缓存状态',
          prop: 'keepAlive',
          type: 'radioGroup',
          hidden: [MENU_TYPE.DIRECTORY, MENU_TYPE.BUTTON, MENU_TYPE.COMPONENT].includes(type),
          options: {
            items: [
              { text: '缓存', label: true },
              { text: '不缓存', label: false }
            ]
          }
        },
        {
          label: '开启新窗口',
          prop: 'window',
          type: 'radioGroup',
          hidden: [MENU_TYPE.DIRECTORY, MENU_TYPE.BUTTON, MENU_TYPE.COMPONENT].includes(type),
          options: {
            items: [
              { text: '开启', label: true },
              { text: '关闭', label: false }
            ]
          }
        },
        {
          label: '全景视图',
          prop: 'panorama',
          type: 'radioGroup',
          hidden: [MENU_TYPE.BUTTON].includes(type),
          options: {
            items: [
              { text: '加入', label: true },
              { text: '不加入', label: false }
            ]
          }
        }
      ]
    }
  },
  methods: {
    open (val, items, isEdit) {
      this.isEdit = isEdit
      this.editValues = val
      this.itemsParents = [{ label: '根菜单', id: 0, children: items }]
      this.$refs.editDialog.open()
      this.$nextTick(() => {
        this.$refs.tree.setChecked(val.parentId, true)
        const data = this.$refs.tree.getNode(val.parentId)
        this.currentNodeName = data.label
        this.$refs.editForm.clearValidate()
      })
    },
    handleSaveEdit () {
      this.$refs.editForm.validate(async (valid) => {
        if (!valid) {
          return
        }
        const metaProp = ['keepAlive', 'window', 'panorama']
        const obj = this.editForm.reduce((res, item) => {
          if (item.hidden) {
            return res
          }
          if (metaProp.includes(item.prop)) {
            res.meta = res.meta || {}
            res.meta[item.prop] = this.editValues[item.prop]
            return res
          }
          res[item.prop] = this.editValues[item.prop]
          return res
        }, { id: this.isEdit ? this.isEdit : undefined })
        try {
          await this.$store.dispatch('menu/saveMenu', obj)
          this.$refs.editDialog.close()
          this.$emit('refresh')
        } catch (error) {
          this.$message.error(error.message)
        }
      })
    },
    nodeClick (v) {
      this.currentNodeName = v.label
      this.editValues.parentId = v.id
    }
  }
}
</script>

<style lang="scss" scoped>
.popover-tree {
  max-height: 500px;
  overflow: auto;
}

</style>
