<template>
  <div class="menu">
    <el-row :gutter="10">
      <el-col :sm="6" :xs="24">
        <div class="app-container">
          <div class="filter-container">
            <el-input
              v-model="label" :placeholder="$t('table.menu.label')" class="filter-item search-item"
              clearable @keyup.enter.native="search"
            />
            <el-tooltip class="item" content="新增/删除时，请先勾选菜单" effect="dark" placement="right">
              <el-dropdown
                v-has-any-permission="['menu:add','menu:delete','menu:export']" class="filter-item"
                trigger="click"
              >
                <el-button>
                  {{ $t('table.more') }}
                  <i class="el-icon-arrow-down el-icon--right"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item v-has-permission="['menu:add']" @click.native="add">
                    {{ $t('table.add') }}
                  </el-dropdown-item>
                  <el-dropdown-item v-has-permission="['menu:delete']" @click.native="deleteMenu">
                    {{ $t('table.delete') }}
                  </el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </el-tooltip>
          </div>
          <commonTree ref="menuTree" :tree-data="menuTree" @nodeClick="nodeClick">
            <template scope="treeNode">
              <span class="tree-icon">
                <i :class="treeNode.data.icon ? treeNode.data.icon : 'el-icon-document'"></i>
              </span>
              <span class="tree-icon">
                <el-badge :type="treeNode.data.isEnable ? 'success' :'danger'" class="status-item" is-dot />
              </span>
            </template>
          </commonTree>
        </div>
      </el-col>
      <el-col :sm="8" :xs="24">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>{{ menu.id === '' ? this.$t('common.add') : this.$t('common.edit') }}</span>
          </div>
          <div>
            <el-form
              ref="form" :model="menu" :rules="rules"
              label-position="right"
              label-width="100px"
            >
              <el-form-item :label="$t('table.menu.parentId')" prop="parentId">
                <el-tooltip :content="$t('tips.topId')" class="item" effect="dark" placement="right">
                  <el-input v-model="menu.parentId" readonly />
                </el-tooltip>
              </el-form-item>
              <el-form-item :label="$t('table.menu.label')" prop="label">
                <el-input v-model="menu.label" />
              </el-form-item>
              <!-- <el-form-item :label='$t("table.menu.type")' prop='type'>
                <el-radio-group v-model='menu.type'>
                  <el-radio label='DIR'>目录</el-radio>
                  <el-radio label='MENU'>菜单</el-radio>
                </el-radio-group>
              </el-form-item>-->
              <el-form-item :label="$t('table.menu.path')" prop="path">
                <el-input v-model="menu.path" @keyup.native="menuPath" />
              </el-form-item>
              <el-form-item :label="$t('table.menu.component')" prop="component">
                <el-input v-model="menu.component" />
                <span>{{ menuComponent }}</span>
              </el-form-item>
              <el-form-item :label="$t('table.menu.icon')" prop="icon">
                <el-input v-model="menu.icon">
                  <el-button slot="append" icon="el-icon-brush" style="padding-left: 0;" @click="chooseIcons" />
                </el-input>
              </el-form-item>
              <el-row>
                <el-col :span="12">
                  <el-form-item :label="$t('table.status')" prop="isEnable">
                    <el-switch
                      v-model="menu.isEnable" :active-text="$t('common.status.valid')"
                      :inactive-text="$t('common.status.invalid')"
                    />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item :label="$t('table.menu.isPublic')" prop="isPublic">
                    <el-switch
                      v-model="menu.isPublic" :active-text="$t('common.yes')"
                      :inactive-text="$t('common.no')"
                    />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-form-item :label="$t('table.menu.sortValue')" prop="sortValue">
                <el-input-number v-model="menu.sortValue" :max="100" :min="0" @change="handleNumChange" />
              </el-form-item>
              <el-form-item :label="$t('table.menu.group')" prop="group">
                <el-tooltip class="item" content="用于区分多组菜单" effect="dark" placement="right">
                  <el-input v-model="menu.group" />
                </el-tooltip>
              </el-form-item>
              <el-form-item :label="$t('table.menu.describe')" prop="describe">
                <el-input v-model="menu.describe" />
              </el-form-item>
            </el-form>
          </div>
        </el-card>
        <el-card class="box-card" style="margin-top: -2rem;">
          <el-row>
            <el-col :span="24" style="text-align: right">
              <el-button plain type="primary" @click="submit">{{ menu.id === '' ? this.$t('common.add') :
                this.$t('common.edit') }}
              </el-button>
            </el-col>
          </el-row>
        </el-card>
      </el-col>

      <el-col :sm="10" :xs="24">
        <el-card class="box-card">
          <div class="app-container">
            <div class="filter-container">
              <el-input
                v-model="resourceQueryParams.model.code" :placeholder="$t('table.resource.code')" class="filter-item search-item"
                clearable
              />
              <el-input
                v-model="resourceQueryParams.model.name" :placeholder="$t('table.resource.name')" class="filter-item search-item"
                clearable
              />
              <el-button class="filter-item" plain type="primary" @click="resourceSearch">{{ $t('table.search') }}
              </el-button>
              <el-dropdown
                v-has-any-permission="['resource:add','resource:delete']" class="filter-item"
                trigger="click"
              >
                <el-button>
                  {{ $t('table.more') }}
                  <i class="el-icon-arrow-down el-icon--right"></i>
                </el-button>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item
                    v-has-permission="['resource:add']" :disabled="!menu.id"
                    @click.native="resourceAdd"
                  >{{ $t('table.add') }}
                  </el-dropdown-item>
                  <el-dropdown-item v-has-permission="['resource:delete']" @click.native="resourceBatchDelete">{{
                    $t('table.delete') }}
                  </el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </div>

            <el-table
              :key="resourceTableKey"
              ref="resourceTable"
              v-loading="resourceLoading"
              :data="resourceTableData.records"
              border
              fit
              style="width: 100%;"
              @selection-change="onResourceSelectChange"
              @sort-change="resourceSortChange"
              @filter-change="resourceFilterChange"
            >
              <el-table-column align="center" type="selection" width="40px" />
              <el-table-column
                :label="$t('table.resource.code')" :show-overflow-tooltip="true" align="center"
                prop="code"
              >
                <template slot-scope="scope">
                  <span>{{ scope.row.code }}</span>
                </template>
              </el-table-column>
              <el-table-column
                :label="$t('table.resource.name')" :show-overflow-tooltip="true" align="center"
                prop="name"
              >
                <template slot-scope="scope">
                  <span>{{ scope.row.name }}</span>
                </template>
              </el-table-column>
              <el-table-column
                :label="$t('table.operation')" align="center" class-name="small-padding fixed-width"
                width="100px"
              >
                <template slot-scope="{row}">
                  <i
                    v-hasPermission="['resource:update']" class="el-icon-edit table-operation" style="color: #2db7f5;"
                    @click="resourceEdit(row)"
                  ></i>
                  <i
                    v-hasPermission="['resource:delete']" class="el-icon-delete table-operation" style="color: #f50;"
                    @click="resourceSingleDelete(row)"
                  ></i>
                  <el-link v-has-no-permission="['resource:update','resource:delete']" class="no-perm">{{
                    $t('tips.noPermission') }}
                  </el-link>
                </template>
              </el-table-column>
            </el-table>
            <pagination
              v-show="resourceTableData.total>0"
              :limit.sync="resourceQueryParams.size"
              :page.sync="resourceQueryParams.current"
              :total="Number(resourceTableData.total)"
              @pagination="resourceFetch"
            />
          </div>
        </el-card>
      </el-col>
    </el-row>
    <Icons :dialog-visible="iconVisible" @choose="chooseIcon" @close="iconVisible = false" />
    <resource-edit
      ref="resourceEdit" :dialog-visible="dialog.isVisible" :type="dialog.type"
      @close="resourceEditClose" @success="resourceEditSuccess"
    />
    <el-dialog
      v-el-drag-dialog
      :close-on-click-modal="false"
      :close-on-press-escape="true"
      title="预览"
      width="80%"
      top="50px"
      :visible.sync="preview.isVisible"
    >
      <el-scrollbar>
        <div v-html="preview.context"></div>
      </el-scrollbar>
    </el-dialog>
  </div>
</template>
<script>
import commonTree from '@/components/ceres/CommonTree.vue'
import Icons from './Icons'
import ResourceEdit from './Edit'
import Pagination from '@/components/Pagination'
import elDragDialog from '@/directive/el-drag-dialog'
import menuApi from '@/api/Menus.js'
import resourceApi from '@/api/Resource.js'
import { initQueryParams } from '@/utils/commons'

export default {
  name: 'MenuManage',
  directives: { elDragDialog },
  components: { Icons, commonTree, Pagination, ResourceEdit },
  data() {
    return {
      dialog: {
        isVisible: false,
        type: 'add'
      },
      preview: {
        isVisible: false,
        context: ''
      },
      iconVisible: false,
      menuTree: [],
      label: '',
      menu: this.initMenu(),
      resourceQueryParams: initQueryParams({
        model: {
          menuId: null
        }
      }),
      resourceTableKey: 0,
      resourceLoading: false,
      resourceSelection: [],
      resourceTableData: {
        total: 0
      },
      rules: {
        label: [
          { required: true, message: this.$t('rules.require'), trigger: 'blur' },
          { min: 1, max: 255, message: this.$t('rules.range2to10'), trigger: 'blur' }
        ],
        path: [{ max: 255, message: this.$t('rules.noMoreThan100'), trigger: 'blur' },
          { required: true, message: this.$t('rules.require'), trigger: 'blur' },
          {
            validator: (rule, value, callback) => {
              const isUrl = this.isUrl(this.menu.path)

              if (value === '/' || (!isUrl && value.endsWith('/'))) {
                callback('请填写有效的路由地址')
              } else {
                callback()
              }
            }, trigger: 'blur'
          }]
      }
    }
  },
  computed: {
    menuComponent() {
      let comp = ''
      if (this.menu.path && this.menu.path !== '/') {
        const isUrl = this.isUrl(this.menu.path)
        if (isUrl) {
          comp = `跳转地址：${this.menu.path}`
        } else {
          // comp = `前端组件：src/views/ceres${this.menu.path}/Index.vue`
          comp = `组件路径：src/views/${this.menu.component}.vue`
        }
      } else {
        comp = `组件路径：src/views/ceres/Index.vue`
      }
      return comp
    }
  },
  watch: {
    'menu.path': function () {
      this.computedComponent()
    }
  },
  mounted() {
    this.initMenuTree()
  },
  methods: {
    isUrl(path) {
      const urls = ['http://', '/http://', 'https://', '/https://', 'www.', '/www.']
      const urlIndex = urls.findIndex(item => {
        return path.startsWith(item)
      })
      return urlIndex >= 0
    },
    menuPath() {
      const isUrl = this.isUrl(this.menu.path)
      if (!isUrl && !this.menu.path.startsWith('/')) {
        this.menu.path = '/' + this.menu.path
      } else if (isUrl) {
        if (this.menu.path.startsWith('/')) {
          this.menu.path = this.menu.path.substr(1)
        }
      }
    },
    computedComponent() {
      const isUrl = this.isUrl(this.menu.path)
      if (isUrl) {
        this.menu.component = 'Layout'
      } else {
        if (this.menu.path) {
          this.menu.component = `ceres${this.menu.path}/Index`
        } else {
          this.menu.component = `ceres/Index`
        }
      }
    },
    initMenuTree() {
      menuApi.allTree().then((response) => {
        console.log(res,'redsadfewfdsfds')
        const res = response.data
        this.menuTree = res.data
      })
    },
    initMenu() {
      return {
        id: '',
        label: '',
        describe: '',
        code: '',
        isPublic: false,
        path: '',
        component: '',
        isEnable: true,
        sortValue: '',
        parentId: 0,
        icon: '',
        group: ''
      }
    },
    nodeClick(data) {
      this.menu = { ...data }
      this.$refs.form.clearValidate()

      this.resourceQueryParams.model.menuId = data.id
      this.resourceSearch()
    },
    handleNumChange(val) {
      this.menu.sortValue = val
    },
    chooseIcons() {
      this.iconVisible = true
    },
    chooseIcon(icon) {
      this.menu.icon = icon
      this.iconVisible = false
    },
    submit() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          this.menu.createTime = this.menu.updateTime = null
          if (this.menu.id) {
            this.update()
          } else {
            this.save()
          }
        } else {
          return false
        }
      })
    },
    save() {
      console.log(this.menu.component)
      menuApi.save(this.menu)
        .then((response) => {
          const res = response.data
          if (res.isSuccess) {
            this.$message({
              message: this.$t('tips.createSuccess'),
              type: 'success'
            })
          }
          this.reset()
        })
    },
    update() {
      console.log(this.menu)
      menuApi.update(this.menu)
        .then((response) => {
          const res = response.data
          if (res.isSuccess) {
            this.$message({
              message: this.$t('tips.updateSuccess'),
              type: 'success'
            })
          }
          this.reset()
        })
    },
    reset() {
      this.initMenuTree()
      this.label = ''
      this.resetForm()
    },
    search() {
      this.$refs.menuTree.$refs.treeRef.filter(this.label)
    },
    add() {
      this.resetForm()
      const checked = this.$refs.menuTree.$refs.treeRef.getCheckedKeys()
      if (checked.length > 1) {
        this.$message({
          message: this.$t('tips.onlyChooseOne'),
          type: 'warning'
        })
      } else if (checked.length > 0) {
        this.menu.parentId = checked[0]
      } else {
        this.menu.parentId = 0
      }
      this.resourceQueryParams.model.menuId = null
      this.resourceReset()
    },
    deleteMenu() {
      const checked = this.$refs.menuTree.$refs.treeRef.getCheckedKeys()
      if (checked.length === 0) {
        this.$message({
          message: this.$t('tips.noNodeSelected'),
          type: 'warning'
        })
      } else {
        this.$confirm(this.$t('tips.confirmDeleteNode'), this.$t('common.tips'), {
          confirmButtonText: this.$t('common.confirm'),
          cancelButtonText: this.$t('common.cancel'),
          type: 'warning'
        }).then(() => {
          menuApi.delete({ ids: checked })
            .then((response) => {
              const res = response.data
              if (res.isSuccess) {
                this.$message({
                  message: this.$t('tips.deleteSuccess'),
                  type: 'success'
                })
              }
              this.reset()
              this.resourceQueryParams.model.menuId = null
              this.resourceReset()
            })
        }).catch(() => {
          this.$refs.menuTree.$refs.treeRef.setCheckedKeys([])
        })
      }
    },
    resetForm() {
      this.$refs.form.clearValidate()
      this.$refs.form.resetFields()
      this.menu = this.initMenu()
    },
    resourceAdd() {
      this.dialog.type = 'add'
      this.dialog.isVisible = true
      this.$refs.resourceEdit.setResource({
        menuId: this.menu.id
      })
    },
    resourceEdit(row) {
      this.dialog.type = 'edit'
      this.dialog.isVisible = true
      row.menuId = this.menu.id
      this.$refs.resourceEdit.setResource(row)
    },
    resourceSingleDelete(row) {
      this.$refs.resourceTable.clearSelection()
      this.$refs.resourceTable.toggleRowSelection(row, true)
      this.resourceBatchDelete()
    },
    resourceBatchDelete() {
      if (!this.resourceSelection.length) {
        this.$message({
          message: this.$t('tips.noDataSelected'),
          type: 'warning'
        })
        return
      }
      this.$confirm(this.$t('tips.confirmDeleteNode'), this.$t('common.tips'), {
        confirmButtonText: this.$t('common.confirm'),
        cancelButtonText: this.$t('common.cancel'),
        type: 'warning'
      }).then(() => {
        const ids = this.resourceSelection.map((item) => item.id)
        resourceApi.delete({ ids: ids }).then((response) => {
          const res = response.data
          if (res.isSuccess) {
            this.$message({
              message: this.$t('tips.deleteSuccess'),
              type: 'success'
            })
          }
          this.resourceReset()
        })
      })
    },
    resourceReset() {
      this.resourceQueryParams = initQueryParams({
        model: {
          menuId: this.resourceQueryParams.menuId
        }
      })
      this.$refs.resourceTable.clearSort()
      this.$refs.resourceTable.clearFilter()
      this.resourceSearch()
    },
    resourceSearch() {
      this.resourceFetch({
        ...this.resourceQueryParams
      })
    },
    resourceFetch(params = {}) {
      if (this.resourceQueryParams.timeRange) {
        this.resourceQueryParams.map.createTime_st = this.queryParams.timeRange[0]
        this.resourceQueryParams.map.createTime_ed = this.queryParams.timeRange[1]
      }

      this.resourceQueryParams.current = params.current ? params.current : this.resourceQueryParams.current
      this.resourceQueryParams.size = params.size ? params.size : this.resourceQueryParams.size

      if (this.resourceQueryParams.model.menuId) {
        this.resourceLoading = true
        resourceApi.page(this.resourceQueryParams)
          .then((response) => {
            const res = response.data
            if (res.isSuccess) {
              this.resourceTableData = res.data
            }
          })
          .finally(() => this.resourceLoading = false)
      } else {
        this.resourceTableData = {}
      }
    },
    resourceSortChange(val) {
      this.resourceQueryParams.sort = val.prop
      this.resourceQueryParams.order = val.order
      if (this.resourceQueryParams.sort) {
        this.resourceSearch()
      }
    },
    resourceFilterChange(filters) {
      for (const key in filters) {
        if (key.includes('.')) {
          const val = {}
          val[key.split('.')[1]] = filters[key][0]
          this.resourceQueryParams.model[key.split('.')[0]] = val
        } else {
          this.resourceQueryParams.model[key] = filters[key][0]
        }
      }
      this.resourceSearch()
    },
    onResourceSelectChange(selection) {
      this.resourceSelection = selection
    },
    resourceEditClose() {
      this.dialog.isVisible = false
    },
    resourceEditSuccess() {
      this.resourceSearch()
    }
  }
}
</script>
<style lang="scss" scoped>
  .menu {
    margin: 10px;

    .app-container {
      margin: 0 0 10px 0 !important;
    }
  }

  .el-card.is-always-shadow {
    box-shadow: none;
  }

  .el-card {
    border-radius: 0;
    border: none;

    .el-card__header {
      padding: 10px 20px !important;
      border-bottom: 1px solid #f1f1f1 !important;
    }
  }
</style>
