<template>
  <div class="role page_container">
    <el-button class="btn-create" type="primary" @click="handleCreate" size="small">新建角色</el-button>
    <el-tabs v-model="activeName" type="card">
      <el-tab-pane label="角色权限" name="0" lazy>
        <table-list v-bind="tableOptions" ref="tabList">
          <template v-slot:table-role-name="{ row }"><span class="color-blue">{{row.name}}</span></template>
          <!-- 操作 -->
          <template v-slot:table-operate="{ row }">
            <el-button type="text" @click="handleEdit(row)" size="mini">编辑名称</el-button>
            <el-button type="text" @click="handleSetPermission(row)" size="mini">权限配置</el-button>
            <el-button type="text" @click="handleDelete(row)" size="mini">删除</el-button>
          </template>
        </table-list>
      </el-tab-pane>
    </el-tabs>
    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" :width="dialogStyle.width" :top="dialogStyle.top" @close="handleDialogClose" :destroy-on-close="true">
      <el-form :model="form" label-width="100px" ref="dialogForm" class="dialog-form">
        <template v-if="dialogType === 'create' || dialogType === 'edit'">
          <el-form-item label="角色名称" prop="role_name" :rules="{ required: true, message: '请输入角色名称', trigger: 'blur' }">
            <el-input v-model="form.role_name" size="small"></el-input>
          </el-form-item>
        </template>
        <template v-if="dialogType === 'permission'">
          <el-form-item label="全选：">
            <el-checkbox :indeterminate="indeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
          </el-form-item>
          <el-form-item :label="`${perm.name}：`" v-for="perm in permissionList" :key="perm.id">
            <div v-for="item in perm.children" :key="item.id">
              <span class="sub-title">{{item.name}}</span>
              <el-checkbox-group v-model="form[item.v_model_key]" @change="handleCheckedChange">
                <el-checkbox v-for="subItem in item.children" :label="subItem.tag" :key="subItem.id">{{subItem.name}}</el-checkbox>
              </el-checkbox-group>
            </div>
          </el-form-item>
        </template>
      </el-form>
      <span v-if="dialogType === 'delete'">此操作将删除这条数据，确认继续执行？</span>
      <span slot="footer">
        <el-button @click="handleDialogClose" size="mini">取 消</el-button>
        <el-button type="primary" @click="handleDialogSubmit" size="mini">提 交</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import TableList from '@/components/TableList'
import { getRoleList, getPermissionList, createRole, deleteRole, updateRole } from '@/api/settings.js'
function recursionData(arr) {
  const leafArr = []
  function recursion(target) {
    let list = []
    const isArr = Array.isArray(target)
    if (isArr) {
      list = target
    } else if (Array.isArray(target.children)) {
      list = target.children
    }
    list.reverse()
    list.filter(item => {
      if (Array.isArray(item.children) && item.children.length > 0) {
        const _prop = item.tag.replace(/-/g, '_')
        item.v_model_key = _prop
        recursion(item)
      } else {
        // 累计leaf节点
        const key = isArr ? '' : target.v_model_key
        item.parent_v_model_key = key || ''
        leafArr.push(item)
      }
    })
  }
  recursion(arr)
  return leafArr
}
const defaultForm = {
  role_name: ''
}
const permissionForm = {}
export default {
  components: { TableList },
  data() {
    return {
      activeName: '0',
      // 项目类型
      tableOptions: {
        remote: {
          httpRequest: getRoleList
        },
        columns: [
          { prop: 'name', label: '角色名称', slots: 'table-role-name' },
          { prop: 'user_count', label: '角色拥有人' },
          { prop: 'operate', label: '操作', slots: 'table-operate' }
        ]
      },
      dialogVisible: false,
      dialogType: '',
      form: Object.assign({}, defaultForm),
      selectedTableItem: '',
      indeterminate: false,
      checkAll: false,
      permissionList: [],
      permissionLeafList: 0
    }
  },
  computed: {
    userRoleId() {
      let roleId = ''
      if (this.$store.state.user.roles.length) roleId = this.$store.state.user.roles[0].id
      return roleId
    },
    dialogTitle() {
      let text = '新建角色'
      switch (this.dialogType) {
        case 'edit':
          text = '编辑名称'
          break
        case 'permission':
          text = '编辑权限配置'
          break
        case 'delete':
          text = '删除角色'
          break
      }
      return text
    },
    dialogWidth() {
      let width = 440
      if (this.dialogType === 'permission') width = 640
      return width + 'px'
    },
    dialogStyle() {
      const style = {
        width: '440px',
        top: '15vh'
      }
      if (this.dialogType === 'permission') {
        style.width = '640px'
        style.top = '10px'
      }
      return style
    },
    checkedCount() {
      let checkedCount = 0
      const form = this.form
      for (const key in form) {
        if (Array.isArray(form[key])) {
          checkedCount += form[key].length
        }
      }
      return checkedCount
    },
    isCheckAll() {
      const count = this.permissionLeafList.length
      return this.checkedCount === count
    },
    isIndeterminate() {
      const checkedCount = this.checkedCount
      return checkedCount > 0 && !this.isCheckAll
    }
  },
  created() {
    console.log(this.$store.state.user.roles)
    this.fetchPermissionList()
  },
  methods: {
    assignForm() {
      Object.keys(permissionForm).forEach(key => {
        permissionForm[key] = []
      })
      this.form = Object.assign({}, defaultForm, permissionForm)
    },
    handleCreate() {
      this.dialogVisible = true
      this.dialogType = 'create'
    },
    handleEdit(val) {
      this.selectedTableItem = val
      this.dialogVisible = true
      this.dialogType = 'edit'
      this.form = {
        role_name: val.name
      }
    },
    handleDelete(val) {
      this.selectedTableItem = val
      this.dialogVisible = true
      this.dialogType = 'delete'
    },
    handleSetPermission(val) {
      this.selectedTableItem = val
      this.dialogVisible = true
      this.dialogType = 'permission'
      this.reviewPermission(val.permission_tags)
    },
    reviewPermission(permissions) {
      // const permissionData = []
      this.permissionLeafList.forEach(item => {
        const targetArr = this.form[item.parent_v_model_key]
        if (permissions.includes(item.tag) && !targetArr.includes(item.tag)) {
          targetArr.push(item.tag)
        }
      })
      this.checkAll = this.isCheckAll
    },
    handleCheckAllChange(val) {
      if (val) {
        this.setCheckAll()
      } else {
        this.assignForm()
      }
      this.indeterminate = false
    },
    setCheckAll() {
      this.permissionLeafList.forEach(item => {
        const targetArr = this.form[item.parent_v_model_key]
        if (!targetArr.includes(item.tag)) {
          targetArr.push(item.tag)
        }
      });
    },
    handleCheckedChange() {
      // const checkedCount = value.length;
      this.checkAll = this.isCheckAll
      this.indeterminate = this.isIndeterminate
    },
    handleDialogClose() {
      this.dialogVisible = false
      this.assignForm()
    },
    handleDialogSubmit() {
      this.$refs.dialogForm.validate(valid => {
        if (valid) {
          switch (this.dialogType) {
            case 'create':
              this.fetchCreateRole()
              break
            case 'delete':
              this.fetchDeleteRole()
              break
            case 'edit':
              this.fetchUpdateRole()
              break
            case 'permission':
              this.fetchUpdateRolePermissions()
              break
          }
          this.dialogVisible = false
        } else {
          return false
        }
      })
    },
    fetchRoleList() {
      this.$refs.tabList.refetch()
    },
    fetchCreateRole() {
      const data = {
        name: this.form.role_name
      }
      createRole(data).then((res) => {
        if (res.code === 0 && res.message === 'SUCCESS') {
          this.fetchRoleList()
          this.$message.success('新建角色成功')
        } else {
          this.$message.error('新建角色失败')
        }
      })
    },
    fetchUpdateRole() {
      const data = {
        role_id: this.selectedTableItem.id,
        name: this.form.role_name
      }
      updateRole(data).then((res) => {
        if (res.code === 0 && res.data && res.data.status) {
          this.fetchRoleList()
          this.$message.success('编辑角色名称成功')
        } else {
          this.$message.error('编辑角色名称失败')
        }
      })
    },
    fetchDeleteRole() {
      const data = {
        role_id: this.selectedTableItem.id
      }
      if (this.userRoleId === data.role_id) {
        this.$message.error('不能删除你自己账户所分配的角色')
        return
      }
      deleteRole(data).then((res) => {
        if (res.code === 0 && res.data && res.data.status) {
          this.fetchRoleList()
          this.$message.success('删除角色成功')
        } else {
          this.$message.error('删除角色失败')
        }
      })
    },
    fetchUpdateRolePermissions() {
      const permissionArr = []
      Object.keys(this.form).forEach(key => {
        const item = this.form[key]
        if (Array.isArray(item)) {
          item.forEach((it) => {
            permissionArr.push(it)
          })
        }
      })
      const data = {
        role_id: this.selectedTableItem.id,
        permission_tags: permissionArr
      }
      updateRole(data).then(async (res) => {
        if (res.code === 0 && res.data && res.data.status) {
          this.fetchRoleList()
          this.$message.success('权限配置成功')
          // 刷新用户user_detail
          if (this.userRoleId === data.role_id) {
            await this.$store.dispatch('checkRolesPermissions')
            // updateRoutes
            await this.$store.dispatch('updateRoutes')
          }
        } else {
          this.$message.error('权限配置失败')
        }
      })
    },
    async fetchPermissionList() {
      const result = await new Promise((resolve, reject) => {
        getPermissionList().then((res) => {
          if (res.code === 0 && Array.isArray(res.data)) {
            resolve(res.data)
          } else reject()
        }).catch(() => {
          reject()
        })
      })
      if (result) {
        const leafNodeList = recursionData(result)
        this.permissionLeafCount = leafNodeList.length
        this.permissionLeafList = leafNodeList
        // console.log(leafNodeList)
        result.forEach(item => {
          item.children.forEach(subItem => {
            const key = subItem.v_model_key
            permissionForm[key] = []
          })
        })
        this.permissionList = result
        this.assignForm()
      }
    }
  }
}
</script>
<style scoped>
.role{
  box-sizing:border-box;
  padding:15px;
  position:relative;
}
.btn-create{
  position:absolute;
  right:20px;
  top:16px;
  z-index:1;
}
.color-blue{
  color:#409EFF;
}
.el-form ::v-deep.el-form-item{
  margin-bottom:6px;
}
.el-form ::v-deep.el-form-item__label{
  font-weight: bold;
  font-size:16px;
}
.sub-title{
  font-size:16px;
}
.el-tabs{
  height:100%;
}
.el-tabs ::v-deep.el-tabs__content{
  height:calc(100% - 56px);
}
.el-tab-pane{
  height:100%;
}
.table-list .table-list-bd{
  height:100%;
}
</style>
