<template>
  <el-drawer
    :visible.sync="visibleProxy"
    :title="$t(title)"
    :size="width"
    :close-on-click-modal="false"
    direction="rtl"
    @close="onClose"
  >
    <div class="perm-drawer__body" v-loading="treeLoading">
      <el-tree
        v-if="treeReady"
        ref="permTree"
        node-key="menu_id"
        :data="treeData"
        :props="{ label: 'name', children: 'children' }"
        :default-expand-all="false"
        :expand-on-click-node="false"
        :check-strictly="true"
        show-checkbox
        @check="onTreeCheck"
      >
        <span slot-scope="{ node, data }" class="perm-drawer__tree-node">
          <span :class="{ 'perm-drawer__tree-node--disabled': !data.status }">
            <i v-if="data.icon" :class="`fa fa-${data.icon}`" />
            <i v-else-if="data.children" :class="`el-icon-${node.expanded ? 'folder-opened' : 'folder'}`" />
            <i v-else class="el-icon-document" />
            {{ $t(data.name) }}
          </span>
        </span>
      </el-tree>
    </div>

    <div class="perm-drawer__footer">
      <el-button size="mini" @click="onCancel">
        {{ $t(cancelText) }}
      </el-button>
      <el-button type="primary" size="mini" :loading="submitting" @click="onSubmit">
        {{ $t(confirmText) }}
      </el-button>
    </div>
  </el-drawer>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'
import util from '@/libs/util'
import { getMenuAll } from '@/api/menu'
import { giveRoleMenu, getRoleMenu } from '@/api/system-administration/role'

export default {
  name: 'RolePermDrawer',
  mixins: [i18nMixin('page.system_administration.user_management.role')],
  props: {
    visible: { type: Boolean, default: false },
    roleId: { type: Number, default: 0 },
    title: { type: String, default: '' },
    confirmText: { type: String, default: '' },
    cancelText: { type: String, default: '' },
    width: { type: String, default: '360px' }
  },
  data () {
    return {
      treeLoading: false,
      submitting: false,
      treeReady: false,
      treeData: [],
      checkedMenuIds: []
    }
  },
  computed: {
    visibleProxy: {
      get () { return this.visible },
      set (val) { this.$emit('update:visible', val) }
    }
  },
  watch: {
    visible (val) {
      if (val) { this.loadData() }
    }
  },
  methods: {
    async loadData () {
      this.treeReady = false
      this.treeLoading = true
      try {
        const [menuRes, roleMenuRes] = await Promise.all([
          getMenuAll()
        ])
        const menuData = Array.isArray(menuRes) ? menuRes : (menuRes.data || [])
        const roleData = Array.isArray(roleMenuRes) ? roleMenuRes : (roleMenuRes.data || [])
        this.checkedMenuIds = roleData.map(item => item.menu_id)
        this.treeData = util.formatDataToTree(menuData)
        this.treeReady = true
        await this.$nextTick()
        await new Promise(resolve => setTimeout(resolve, 50))
        this.$refs.permTree.setCheckedKeys(this.checkedMenuIds)
      } finally {
        this.treeLoading = false
      }
    },
    onTreeCheck () {},
    onClose () {
      this.treeReady = false
      this.treeData = []
      this.checkedMenuIds = []
    },
    onCancel () {
      this.visibleProxy = false
    },
    async onSubmit () {
      this.submitting = true
      try {
        const menuIds = this.$refs.permTree.getCheckedKeys()
        await giveRoleMenu({ role_id: this.roleId, role_menu: menuIds })
        this.$message.success(this.$t(this.key('operation_success')))
        this.visibleProxy = false
        this.$emit('saved')
      } finally {
        this.submitting = false
      }
    }
  }
}
</script>

<style scoped>
.perm-drawer__body {
  height: calc(100vh - 140px);
  overflow-y: auto;
  padding: 10px 20px;
}
.perm-drawer__footer {
  position: absolute;
  bottom: 0;
  right: 0;
  left: 0;
  padding: 10px 20px;
  border-top: 1px solid #e8e8e8;
  background: #fff;
  text-align: right;
}
.perm-drawer__tree-node {
  display: flex;
  align-items: center;
  gap: 5px;
}
.perm-drawer__tree-node--disabled {
  color: #c0c4cc;
}
</style>
