<script lang="ts" setup name="SystemEditDept">
import type { Ref } from 'vue'
import { nextTick, reactive } from 'vue'
import { ElButton, ElCol, ElDialog, ElForm, ElFormItem, ElInput, ElInputNumber, ElMessage, ElMessageBox, ElOption, ElRow, ElSelect } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import type { DeptInfo, DeptTypeInfo } from './dept-interface'
import { addDept, getDeptTypeList, updateDept } from '@/api/system/dept'
import useDictStore from '@/store/modules/dict'
import DeptSelect from '@/components/DeptSelect/index.vue'
// ----------------------- 以下是字段定义 emits props ---------------------
const emits = defineEmits(['closeRefresh'])

// 对话框类型：create,update
const dialogStatus = ref('create')
const dialogVisible = ref(false)
// 显示标题
const textMap: { [key: string]: string } = {
  update: '编辑',
  create: '新增',
}
const defaultFormData: DeptInfo = {
  id: '',
  simpleName: '',
  fullName: '',
  deptType: '',
  pid: '',
  num: 0,
  version: '',
  tips: '',
}
// 表单数据对象
const formData: DeptInfo = reactive({ ...defaultFormData })

// 保存按钮加载状态
const btnLoading = ref(false)

// ---------------表单提交--------------------------------
// 表单对象
const dataFormRef = ref<FormInstance>()
// 校验规则
const rules: FormRules = reactive({
  simpleName: [{ required: true, message: '组织名称不可为空', trigger: ['blur', 'change'] }],
  fullName: [{ required: true, message: '组织全称不可为空', trigger: ['blur', 'change'] }],
  pid: [{ required: true, message: '父组织必选', trigger: ['blur', 'change'] }],
  deptType: [{ required: true, message: '组织类型必选', trigger: ['blur', 'change'] }],
  num: [{ required: true, message: '排序不可为空', trigger: 'blur' }, { pattern: /^\d+(\.\d+)?$/, trigger: ['blur', 'change'], message: '' }],
})

const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) { return }
  await formEl.validate((valid, fields) => {
    if (valid) {
      if (valid) {
        if (dialogStatus.value === 'create') {
          createData()
        }
        else if (dialogStatus.value === 'update') {
          updateData()
        }
      }
    }
  })
}
// 新增数据
function createData() {
  btnLoading.value = true
  addDept(formData).then((res) => {
    ElMessageBox.confirm(
      '新增成功，是否继续新增?',
      '提示',
      {
        confirmButtonText: '是',
        cancelButtonText: '否',
        type: 'info',
      },
    ).then(() => {
      resetForm()
    }).catch(() => {
      closeRefresh()
    }).finally(() => {
      clearBuffer()
    })
    btnLoading.value = false
  }).catch((_) => {
    btnLoading.value = false
  })
}

// 更新数据
function updateData() {
  updateDept(formData).then((res) => {
    ElMessage.success('修改成功')
    btnLoading.value = false
    clearBuffer()
    closeRefresh()
  }).catch((_) => { // 异常情况，loading置为false
    btnLoading.value = false
  })
}
const dictStore = useDictStore()

// 部门选择组件
const deptSelect = ref()
// 在组织变更后清空pinia中缓存
function clearBuffer() {
  dictStore.setAllCompanyList([])
  dictStore.setAllDeptList([])
  deptSelect.value.refreshTree() // 刷新组件
}
// 重置表单
function resetForm() {
  const form = formData
  const keys = Object.keys(formData)
  keys.forEach((key) => {
    form[key] = defaultFormData[key]
  })
  Object.assign(formData, form)
  nextTick(() => {
    dataFormRef.value?.clearValidate()
  })
}

const deptTypeList: Ref<DeptTypeInfo[]> = ref([])
// 获取所有组织类型
function getDeptType() {
  getDeptTypeList().then((res) => {
    deptTypeList.value = res.data
  })
}
getDeptType()

// ----------初始化、关闭对话框相关-----------------
function initDialog(dialogstatus: string, row: DeptInfo) {
  dialogStatus.value = dialogstatus
  dialogVisible.value = true
  btnLoading.value = false
  if (dialogstatus === 'create') {
    resetForm()
    nextTick(() => {
      dataFormRef.value?.clearValidate()
    })
  }
  else if (dialogstatus === 'update') {
    formData.id = row.id
    formData.simpleName = row.simpleName
    formData.fullName = row.fullName
    formData.deptType = row.deptType
    formData.pid = row.pid
    formData.num = row.num
    formData.version = row.version
    formData.tips = row.tips
  }
}

// 关闭并刷新
function closeRefresh() {
  dialogVisible.value = false
  resetForm()
  emits('closeRefresh')
}
// 关闭弹窗
function dialogClose() {
  resetForm()
  dialogVisible.value = false
}
// ----------------------- 以下是暴露的方法内容 ----------------------------
defineExpose({ initDialog })
</script>

<template>
  <el-dialog
    v-model="dialogVisible"
    :title="textMap[dialogStatus]"
    width="50%"
    :before-close="dialogClose"
    append-to-body
    :open-delay="0"
    :close-on-click-modal="false"
  >
    <el-form
      ref="dataFormRef" :model="formData" :rules="rules" label-position="left" label-width="110px" class="form-container"
      size="default" @submit.prevent
    >
      <el-row :gutter="10">
        <el-col :span="12" class="grid-cell">
          <el-form-item label="组织名称" prop="simpleName" class="required">
            <el-input v-model.trim="formData.simpleName" type="text" placeholder="必填" clearable />
          </el-form-item>
        </el-col>
        <el-col :span="12" class="grid-cell">
          <el-form-item label="组织全称" prop="fullName" class="required">
            <el-input v-model.trim="formData.fullName" type="text" placeholder="必填" clearable />
          </el-form-item>
        </el-col>
        <el-col :span="12" class="grid-cell">
          <el-form-item label="父组织" prop="pid" class="required">
            <dept-select ref="deptSelect" v-model="formData.pid" :dept-show="true" />
          </el-form-item>
        </el-col>
        <el-col :span="12" class="grid-cell">
          <el-form-item label="组织类型" prop="deptType" class="required">
            <el-select v-model="formData.deptType" class="full-width-input" clearable placeholder="请选择">
              <el-option v-for="(item, index) in deptTypeList" :key="index" :label="item.name" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12" class="grid-cell">
          <el-form-item label="排序" prop="num" class="required">
            <el-input-number
              v-model="formData.num" class="full-width-input" controls-position="right"
              :min="0" :max="999" :precision="0" :step="1"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12" class="grid-cell">
          <el-form-item label="备注" prop="tips">
            <el-input v-model.trim="formData.tips" type="text" placeholder="非必填" clearable />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button :loading="btnLoading" type="primary" @click="submitForm(dataFormRef)">
          保存
        </el-button>
        <el-button @click="dialogClose">
          取消
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.form-container {
  width: 100%;

  .full-width-input {
    width: 100%;
  }
}
</style>
