<script setup lang="ts">
import AForm from '@/components/AForm/index.vue'
import { FormConfigType } from '@/components/AForm/type'
import { ToolbarConfigType } from '@/components/AToolbar/type'
import { ColumnConfigType } from '@/components/ATable/type'
import { StrAnyObj, StrAnyObjArr } from '@/typings'
import { useHandleData } from '@/utils/useHandleData'
import {
  getPageApi,
  getDetailApi,
  addApi,
  editApi,
  deleteApi,
  resetPwdApi
} from '@/api/system/user'
import { getPageApi as getRolePageApi } from '@/api/system/role'
import DeptTreeSelect from '@/views/components/DeptTreeSelect/index.vue'
import { useUserStore } from '@/stores/modules/user'

const userStore = useUserStore()

const queryRef = ref<InstanceType<typeof AForm>>()
const formRef = ref<InstanceType<typeof AForm>>()
const queryDeptRef = ref<InstanceType<typeof DeptTreeSelect>>()
const deptIdRef = ref<InstanceType<typeof DeptTreeSelect>>()

const showQuery = ref<boolean>(true)
const selectKeys = ref<string[]>([])
const pageTotal = ref<number>(0)

const queryData = ref<StrAnyObj>({ pageNum: 1, pageSize: 10 })
const tableData = ref<StrAnyObjArr>([])
const formData = ref<StrAnyObj>({ sex: 0, status: 1, builtin: 0 })

const dialogTitle = ref<string>('')
const dialogVisible = ref<boolean>(false)

const queryConfig: FormConfigType[] = [
  {
    type: 'input',
    prop: 'username',
    label: '账号'
  },
  {
    type: 'input',
    prop: 'nickname',
    label: '昵称'
  },
  {
    type: 'select',
    prop: 'builtin',
    label: '系统内置',
    dict: 'yes_no',
    if: () => userStore.superAdmin
  },
  {
    type: 'select',
    prop: 'status',
    label: '状态',
    dict: 'enable_disable'
  },
  {
    type: 'slot',
    prop: 'queryDept',
    label: '部门'
  }
]

const toolbarConfig: ToolbarConfigType[] = [
  {
    common: 'search',
    click() {
      queryData.value.pageNum = 1
      getPage()
    }
  },
  {
    common: 'reset',
    click() {
      queryRef.value?.resetFields()
      getPage()
    }
  },
  {
    common: 'add',
    permissions: 'sysUser:add',
    click() {
      dialogVisible.value = true
      dialogTitle.value = '新增'
      nextTick(() => deptIdRef.value?.load())
    }
  },
  {
    common: 'delete',
    permissions: 'sysUser:delete',
    disabled() {
      return selectKeys.value.length == 0
    },
    click() {
      handleRemove(selectKeys.value)
    }
  }
]

const columnConfig: ColumnConfigType[] = [
  {
    prop: 'username',
    label: '账号'
  },
  {
    prop: 'nickname',
    label: '昵称'
  },
  {
    prop: 'deptName',
    label: '部门'
  },
  {
    prop: 'phoneNumber',
    label: '手机号'
  },
  {
    prop: 'email',
    label: '邮箱'
  },
  {
    prop: 'builtin',
    label: '系统内置',
    dict: 'yes_no',
    if: () => userStore.superAdmin
  },
  {
    prop: 'status',
    label: '状态',
    dict: 'enable_disable'
  },
  {
    width: 300,
    handleConfig: [
      {
        icon: 'key',
        text: '重置密码',
        permissions: 'sysUser:resetPwd',
        if: (row) => userStore.superAdmin || row.builtin === 0,
        click(row) {
          handleResetPwd(row)
        }
      },
      {
        common: 'update',
        permissions: 'sysUser:edit',
        if: (row) => userStore.superAdmin || row.builtin === 0,
        click(row) {
          dialogVisible.value = true
          dialogTitle.value = '编辑'
          getDetailApi({ id: row.id }).then((resp: StrAnyObj) => {
            formData.value = resp
          })
          nextTick(() => deptIdRef.value?.load())
        }
      },
      {
        common: 'delete',
        permissions: 'sysUser:delete',
        if: (row) => userStore.superAdmin || row.builtin === 0,
        click(row) {
          handleRemove([row.id])
        }
      }
    ]
  }
]

const formConfig: FormConfigType[] = [
  {
    type: 'input',
    prop: 'username',
    label: '账号',
    rule: [{ required: true, message: '账号不能为空', trigger: 'blur' }],
    if: () => !formData.value.id
  },
  {
    type: 'input',
    itemType: 'password',
    prop: 'password',
    label: '密码',
    rule: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
    if: () => !formData.value.id
  },
  {
    type: 'input',
    prop: 'nickname',
    label: '昵称',
    rule: [{ required: true, message: '昵称不能为空', trigger: 'blur' }]
  },
  {
    type: 'slot',
    prop: 'deptId',
    label: '部门',
    rule: [{ required: true, message: '部门不能为空', trigger: 'blur' }]
  },
  {
    type: 'input',
    prop: 'phoneNumber',
    label: '手机号',
    rule: [
      {
        pattern: /^($|1[3-9][0-9]{9})$/,
        message: '手机号格式不正确',
        trigger: 'blur'
      }
    ]
  },
  {
    type: 'input',
    prop: 'email',
    label: '邮箱',
    rule: [{ type: 'email', message: '邮箱格式不正确', trigger: 'blur' }]
  },
  {
    type: 'radio',
    prop: 'sex',
    label: '性别',
    dict: 'user_sex',
    rule: [{ required: true, message: '性别不能为空', trigger: 'blur' }]
  },
  {
    type: 'radio',
    prop: 'status',
    label: '状态',
    dict: 'enable_disable',
    rule: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
  },
  {
    type: 'radio',
    prop: 'builtin',
    label: '系统内置',
    dict: 'yes_no',
    if: () => userStore.superAdmin,
    rule: [{ required: true, message: '系统内置不能为空', trigger: 'blur' }]
  },
  {
    type: 'select',
    prop: 'roleIdList',
    label: '角色',
    multiple: true,
    keyName: 'id',
    labelName: 'name',
    async option() {
      const rolePage = await getRolePageApi({ searchAll: true })
      return rolePage.records
    },
    span: 24,
    rule: [{ required: true, message: '角色不能为空', trigger: 'blur' }]
  },
  {
    type: 'input',
    itemType: 'textarea',
    prop: 'remark',
    label: '备注',
    rows: 3,
    span: 24
  }
]

onMounted(() => {
  getPage()
  queryDeptRef.value?.load()
})

function getPage() {
  getPageApi(queryData.value).then((resp) => {
    tableData.value = resp.records
    pageTotal.value = resp.total
  })
}

function tableSelectionChange(item: StrAnyObjArr) {
  selectKeys.value = item.map((item) => item.id)
}

function formSubmit() {
  formRef.value?.validate(() => {
    if (formData.value.id) {
      editApi(formData.value).then(() => {
        dialogVisible.value = false
        ElMessage.success('修改成功')
        getPage()
      })
    } else {
      addApi(formData.value).then(() => {
        dialogVisible.value = false
        ElMessage.success('新增成功')
        getPage()
      })
    }
  })
}

function formClosed() {
  formRef.value?.resetFields()
}

function handleRemove(idList: string[]) {
  useHandleData('是否确认删除？', () => {
    deleteApi({ idList }).then(() => {
      ElMessage.success('删除成功')
      getPage()
    })
  })
}

function handleResetPwd(row: StrAnyObj) {
  ElMessageBox.prompt(`请输入【${row['nickname']}】的新密码`, '重置密码', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    closeOnClickModal: true,
    inputPattern: /^.{6,30}$/,
    inputErrorMessage: '用户密码长度必须介于 6 和 30 之间'
  }).then(({ value }) => {
    resetPwdApi({ userId: row.id, password: value }).then(() => {
      ElMessage.success(`重置密码成功`)
    })
  })
}
</script>

<template>
  <div>
    <el-card v-if="showQuery">
      <a-form ref="queryRef" v-model="queryData" :config="queryConfig" :span="6">
        <template #queryDept>
          <dept-tree-select ref="queryDeptRef" v-model="queryData.deptId" />
        </template>
      </a-form>
    </el-card>

    <a-table
      selection
      :data="tableData"
      :page-total="pageTotal"
      :toolbar-config="toolbarConfig"
      :column-config="columnConfig"
      v-model:showQuery="showQuery"
      v-model:page-num="queryData.pageNum"
      v-model:page-size="queryData.pageSize"
      @page-num-change="getPage"
      @page-size-change="getPage"
      @selection-change="tableSelectionChange"
    >
    </a-table>

    <a-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="800px"
      @submit="formSubmit"
      @closed="formClosed"
    >
      <a-form ref="formRef" v-model="formData" :config="formConfig" :span="12">
        <template #deptId>
          <dept-tree-select ref="deptIdRef" v-model="formData.deptId" />
        </template>
      </a-form>
    </a-dialog>
  </div>
</template>
