<template>
  <el-dialog
      v-model="showDialog"
      :title="popTitle"
      width="500px"
      :destroy-on-close="true"
  >
    <el-form
        :model="formData"
        label-width="90px"
        ref="formRef"
        :rules="formRules"
        class="page-form"
        v-loading="loading"
    >
      <el-form-item :label="t('roleName')" prop="role_name">
        <el-input
            v-model.trim="formData.role_name"
            :placeholder="t('roleNamePlaceholder')"
            clearable
            :disabled="formData.uid"
            class="input-width"
            maxlength="10"
            :show-word-limit="true"
        />
      </el-form-item>


      <el-form-item label="类型">
        <el-radio-group v-model="formData.role_key">
        <span v-for="(item,index) in roleKeyList" class="mr-2">
          <el-radio :label="item.value">{{ item.name }}</el-radio>
        </span>
        </el-radio-group>
      </el-form-item>


      <el-form-item :label="t('status')">
        <el-radio-group v-model="formData.status">
          <el-radio :label="1">{{ t('startUsing') }}</el-radio>
          <el-radio :label="0">{{ t('statusDeactivate') }}</el-radio>
        </el-radio-group>
      </el-form-item>
	  
	  
	  
	  <el-form-item label="部门" >
	    <el-select
	      class="input-width"
	      v-model="formData.dept_id"
	      clearable
	      placeholder="请选择部门"
	    >
	      <el-option label="请选择" value=""></el-option>
	      <el-option
	        v-for="(item, index) in parentDepartmentIdList"
	        :key="index"
	        :label="item['department_name']"
	        :value="item['id']"
	      />
	    </el-select>
	  </el-form-item>

      <el-form-item :label="t('permission')" prop="rules">
        <div class="flex items-center justify-between w-11/12">
          <div>
            <el-checkbox v-model="selectAll" :label="t('selectAll')"/>
            <el-checkbox v-model="checkStrictly" :label="t('checkStrictly')"/>
          </div>
          <el-button link type="primary" @click="menuAction()">{{
              t('foldText')
            }}
          </el-button>
        </div>
        <el-scrollbar height="35vh" class="w-full">
          <el-tree
              :data="menus"
              :props="{ label: 'menu_name' }"
              :default-checked-keys="formData.rules"
              :check-strictly="checkStrictly"
              show-checkbox
              default-expand-all
              @check-change="handleCheckChange"
              node-key="menu_key"
              ref="treeRef"
          />
        </el-scrollbar>
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
        <el-button
            type="primary"
            :loading="loading"
            @click="confirm(formRef)"
        >{{ t('confirm') }}</el-button
        >
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup async>
import {ref, reactive, computed, watch, toRaw} from 'vue'
import {t} from '@/lang'
import {
  getWithDepartmentsList} from '@/app/api/departments'
import type {FormInstance} from 'element-plus'
import {addRole, editRole, getRoleInfo} from '@/app/api/sys'
import {getAuthMenus} from '@/app/api/auth'
import {useDictionary} from '@/app/api/dict'
import {debounce} from '@/utils/common'

const showDialog = ref(false)
const loading = ref(false)
const isOpen = ref(true)

let popTitle: string = ''

// 获取权限数据
const menus = ref<Record<string, any>[]>([])
getAuthMenus({is_button: 0}).then((res) => {
  menus.value = res.data
})

// 全选
const selectAll = ref(false)
const checkStrictly = ref(false)
const treeRef: Record<string, any> | null = ref(null)
watch(selectAll, () => {
  if (selectAll.value) {
    treeRef.value.setCheckedNodes(toRaw(menus.value))
  } else {
    treeRef.value.setCheckedNodes([])
  }
})

const parentDepartmentIdList = ref([] as any[])
const setParentDepartmentIdList = async () => {
  parentDepartmentIdList.value = await (await getWithDepartmentsList({})).data
}
setParentDepartmentIdList()

const roleKeyList = ref([])
const getRolekeyDictList = async () => {
  roleKeyList.value = await (
      await useDictionary('role_key')
  ).data.dictionary
}
getRolekeyDictList()

const handleCheckChange = debounce((e) => {
  formData.rules = treeRef.value.getCheckedKeys()
})

const menuAction = () => {
  if (isOpen.value) {
    collapseAll(menus.value)
    isOpen.value = false
  } else {
    unFoldAll(menus.value)
    isOpen.value = true
  }
}

// 全部展开
const unFoldAll = (data: any) => {
  Object.keys(data).forEach((key: string | any) => {
    treeRef.value.store.nodesMap[data[key].menu_key].expanded = true
    if (data[key].children && data[key].children.length > 0)
      collapseAll(data[key].children)
  })
}
// 全部折叠
const collapseAll = (data: any) => {
  Object.keys(data).forEach((key: string | any) => {
    treeRef.value.store.nodesMap[data[key].menu_key].expanded = false
    if (data[key].children && data[key].children.length > 0)
      collapseAll(data[key].children)
  })
}
/**
 * 表单数据
 */
const initialFormData = {
  role_id: 0,
  role_name: '',
  status: 1,
  role_key: '',
  dept_id:'',
  rules: [],
}
const formData: Record<string, any> = reactive({...initialFormData})

const formRef = ref<FormInstance>()

// 表单验证规则
const formRules = computed(() => {
  return {
    role_name: [
      {required: true, message: t('roleNamePlaceholder'), trigger: 'blur'},
    ],
    rules: [
      {
        validator: (rule: any, value: string, callback: any) => {
          if (!value.length) callback(new Error(t('rulesPlaceholder')))
          else callback()
        },
        trigger: 'blur',
      },
    ],
  }
})

const emit = defineEmits(['complete'])

/**
 * 确认
 * @param formEl
 */
const confirm = async (formEl: FormInstance | undefined) => {
  if (loading.value || !formEl) return
  const save = formData.role_id ? editRole : addRole

  await formEl.validate(async (valid) => {
    if (valid) {
      loading.value = true

      const data = Object.assign({}, formData)
      data.rules = data.rules.concat(treeRef.value.getHalfCheckedKeys())

      save(data)
          .then((res) => {
            loading.value = false
            showDialog.value = false

            emit('complete')
          })
          .catch(() => {
            loading.value = false
            // showDialog.value = false
          })
    }
  })
}

const setFormData = async (row: any = null) => {
  loading.value = true
  selectAll.value = false
  Object.assign(formData, initialFormData)
  popTitle = t('addRole')
  if (row) {
    popTitle = t('updateRole')
    const data = await (await getRoleInfo(row.role_id)).data
    Object.keys(formData).forEach((key: string) => {
      if (data[key] != undefined) {
        if (key == 'rules') {
          const arr = data.rules
          const newArr: any = []

          Object.keys(data.rules).forEach((i) => {
            checked(data.rules[i], menus.value, newArr)
          })
          formData[key] = newArr
        } else {
          formData[key] = data[key]
        }
      }
    })
  }
  loading.value = false
}

function checked(menuKey: string, data: any, newArr: any) {
  Object.keys(data).forEach((key: string) => {
    const item = data[key]
    if (item.menu_key == menuKey) {
      if (!item.children || item.children.length == 0) {
        newArr.push(item.menu_key)
      }
    } else {
      if (item.children && item.children.length > 0) {
        checked(menuKey, item.children, newArr)
      }
    }
  })
}

defineExpose({
  showDialog,
  setFormData,
})
</script>

<style lang="scss" scoped></style>
