import { getMenus } from '@/api/system/menu'
import { SearchOutline } from '@vicons/ionicons5'
import {
  NForm,
  NFormItem,
  NInput,
  NSpace,
  NButton,
  useMessage,
  NRadioGroup,
  NRadio,
  NCascader,
  NTree,
  NGrid,
  NFormItemGi,
  NIcon,
  NCheckbox
} from 'naive-ui'
import { defineComponent, onMounted, PropType, reactive, ref, shallowRef } from 'vue'
import { sysRoleSave, sysRoleUpdate, sysRoleDetail } from '../api'
export default defineComponent({
  name: 'role-operation',
  props: {
    type: {
      type: String,
      default: 'add'
    },
    applyList: {
      type: Array as PropType<any>,
      default: () => []
    },
    data: {
      type: Object as PropType<any>,
      default: () => {}
    }
  },
  emits: ['close', 'getList'],
  setup(props, { slots, attrs, emit }) {
    const forms = reactive({
      appId: null,
      roleName: null,
      menuId: [] as any,
      enable: false,
      roleDesc: null
    })
    const menuList = shallowRef<any[]>([])
    const pattern = ref('')
    const btnLoading = ref(false)
    const isChecked = ref(false)
    const idsList = ref<any[]>([]) // 所有结点
    const indeterminate = ref(false)
    const indeterminateKeys = ref<any[]>([])
    const roleDetail = ref<any>({})

    const formsRef = ref()
    const treeRef = ref()
    const message = useMessage()

    const onSubmit = async () => {
      const res = treeRef.value.getCheckedData()
      const inRes = treeRef.value.getIndeterminateData()
      const menuId = [...res.keys, ...inRes.keys]
      // return
      formsRef.value.validate(async (error: any) => {
        if (error) return false
        try {
          const { ...res } = forms
          const roleIds = [...new Set(menuId)]
          btnLoading.value = true

          if (props.type === 'add') {
            await sysRoleSave({ ...res, menuId: roleIds })
            message.success('添加成功')
          } else if (props.type === 'edit') {
            await sysRoleUpdate({ ...res, menuId: roleIds, id: props.data.id })
            message.success('修改成功')
          }

          emit('getList')
          emit('close')
        } catch {}
        btnLoading.value = false
      })
    }

    // 选中结点
    const updateCheckedKeys = (options: any) => {
      // 判断选中条件
      if (options.length >= idsList.value.length) {
        isChecked.value = true
        indeterminate.value = false
      } else if (options.length > 0) {
        indeterminate.value = true
        isChecked.value = false
      } else {
        indeterminate.value = false
        isChecked.value = false
      }
      forms.menuId = options
    }

    // 由于手动添加选中的值，不会触发update事件，所以需要手动去设置按钮状态
    const onCheckAll = (obj: boolean) => {
      isChecked.value = obj
      if (obj) {
        forms.menuId = [...idsList.value]
        isChecked.value = true
      } else {
        forms.menuId = []
        isChecked.value = false
      }
      indeterminate.value = false
      indeterminateKeys.value = []
    }

    const getMenuList = async () => {
      try {
        const menus = await getMenus({ delFlag: false })
        menuList.value = menus.data
        getMenuLength(menus.data)
      } catch {}
    }

    // 获取菜单id数量
    const getMenuLength = async (menu: any) => {
      menu.map((m: any) => {
        idsList.value.push(m.id)
        if (m.children && m.children.length > 0) {
          getMenuLength(m.children)
        }
      })
    }

    // 获取角色详情
    const getRoleDetail = async () => {
      try {
        const data = props.data
        const res = await sysRoleDetail({ id: data.id })
        roleDetail.value = res.data || {}
      } catch {
        //
      }
    }

    onMounted(async () => {
      await getMenuList()
      if (props.type === 'edit') {
        await getRoleDetail()
        const data = props.data
        forms.appId = data.appId
        forms.roleName = data.roleName
        forms.enable = data.enable
        forms.roleDesc = data.roleDesc
        forms.menuId = roleDetail.value.menuLeafId
        if (roleDetail.value.menuId.length >= idsList.value.length) {
          isChecked.value = true
          indeterminate.value = false
        } else if (forms.menuId.length > 0) {
          indeterminate.value = true
          isChecked.value = false
        }
      }
    })

    return () => (
      <div style="background: #fff; padding-top: 12px">
        <NForm model={forms} ref={formsRef} label-placement="left" label-width="100">
          <NFormItem
            label="应用分类"
            path="appId"
            rule={[
              {
                required: true,
                message: '请选择应用分类'
              }
            ]}
          >
            <NCascader
              v-model:value={forms.appId}
              options={props.applyList}
              showPath={true}
              allowCheckingNotLoaded={false}
              checkStrategy="child"
              valueField="id"
              labelField="appName"
              childrenField="bizApps"
              expandTrigger="hover"
              placeholder="请选择应用分类"
              clearable
            ></NCascader>
          </NFormItem>
          <NGrid cols={2}>
            <NFormItemGi
              label="角色名称"
              path="roleName"
              rule={[
                {
                  required: true,
                  message: '请输入角色名称'
                }
              ]}
            >
              <NInput
                v-model:value={forms.roleName}
                placeholder="请输入角色名称"
                clearable
                maxlength={100}
              ></NInput>
            </NFormItemGi>
            <NFormItemGi
              label="角色状态"
              path="enable"
              rule={[
                {
                  required: true,
                  message: '请选择角色状态'
                }
              ]}
            >
              <NRadioGroup v-model:value={forms.enable}>
                <NSpace>
                  <NRadio value={true}>启用</NRadio>
                  <NRadio value={false}>停用</NRadio>
                </NSpace>
              </NRadioGroup>
            </NFormItemGi>
          </NGrid>
          <NFormItem label="备注" path="roleDesc">
            <NInput
              v-model:value={forms.roleDesc}
              maxlength={180}
              type="textarea"
              rows={2}
              placeholder="请输入备注"
              clearable
            />
          </NFormItem>

          <NFormItem label="权限" path="status">
            <NSpace vertical style={{ width: '100%' }}>
              <NInput
                placeholder="输入菜单名搜索"
                v-model:value={pattern.value}
                clearable
                v-slots={{
                  suffix: () => (
                    <NIcon>
                      <SearchOutline />
                    </NIcon>
                  )
                }}
              />

              <NCheckbox
                indeterminate={indeterminate.value}
                checked={isChecked.value}
                onUpdateChecked={onCheckAll}
              >
                全选
              </NCheckbox>

              <NTree
                style={{
                  width: '100%',
                  border: '1px solid #e0e0e6',
                  height: '250px',
                  borderRadius: '3px'
                }}
                ref={treeRef}
                virtual-scroll
                cascade
                checkable
                showIrrelevantNodes={false}
                pattern={pattern.value}
                data={menuList.value}
                checkedKeys={forms.menuId}
                // indeterminateKeys={indeterminateKeys.value}
                onUpdate:checkedKeys={updateCheckedKeys}
                // onUpdateIndeterminateKeys={updateIndeterminateKeys}
                keyField="id"
                labelField="name"
                childrenField="children"
              />
            </NSpace>
          </NFormItem>
        </NForm>

        <NSpace justify="end">
          <NButton type="default" onClick={() => emit('close')}>
            取消
          </NButton>
          <NButton type="primary" onClick={() => onSubmit()} loading={btnLoading.value}>
            保存
          </NButton>
        </NSpace>
      </div>
    )
  }
})
