<template>
<div class="page-wrapper">
  <el-form inline :model="search" @submit.prevent>
    <el-form-item label="用户名/昵称">
      <el-input v-model="search.username" />
    </el-form-item>
  </el-form>
  <div class="btn-container">
    <el-button type="primary" @click="add">添加</el-button>
    <div class="search-btn">
      <el-button type="primary" @click="loadDataBase(true)" icon="Search">搜索</el-button>
      <el-button @click="reset" icon="RefreshLeft">重置</el-button>
    </div>
  </div>
  <div class="table-container">
    <el-table :data="systemUserData" v-loading="loading" stripe>
      <el-table-column prop="username" label="用户名" />
      <el-table-column prop="realname" label="昵称" />
      <el-table-column prop="created_at" label="创建时间" >
        <template #default="scope">
          {{ datetimeFormat(scope.row.created_at) }}
        </template>
      </el-table-column>
      <el-table-column prop="updated_at" label="更新时间" >
        <template #default="scope">
          {{ datetimeFormat(scope.row.updated_at) }}
        </template>
      </el-table-column>
      <el-table-column label="操作" >
        <template #default="scope">
          <el-button link icon="Edit" @click="update(scope.row)" title="修改"></el-button>
          <el-button link type="danger" icon="Delete" @click="remove(scope.row)" title="删除"></el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
  <div class="page-container">
    <el-pagination background
      :page-sizes="store.state.pageSizeOpts"
      :layout="store.state.pageLayout"
      :current-page="search.pageNum"
      :total="total"
      @size-change="pageSizeChange"
      @current-change="pageChange">
    </el-pagination>
  </div>
  <el-dialog v-model="addModal" :title="modalTitle" >
    <el-form ref="userForm" :model="formData" :rules="ruleValidate" :label-width="120">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="formData.username" />
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input v-model="formData.password" type="password" />
      </el-form-item>
      <el-form-item label="昵称" prop="realname">
        <el-input v-model="formData.realname" />
      </el-form-item>
      <el-form-item label="角色" prop="realname">
        <el-select v-model="formData.role_ids" multiple >
          <el-option v-for="role in roles" :key="role._id" :value="role._id" :label="role.name"></el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="addModal = false">取消</el-button>
        <el-button type="primary" @click="save" :loading="modalLoading">确定</el-button>
      </span>
    </template>
  </el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, computed, nextTick } from 'vue'
import { useStore } from 'vuex'
import { useBaseList } from '@/model/baselist'
import { Page } from '@/model/common.dto'
import http from '@/utils/http'
import { SystemUserModel } from '@/model/system/system-user'
import { SystemRoleModel } from '@/model/system/system-role'
import { ElMessage, ElMessageBox } from 'element-plus'
import { VForm } from '@/types'

const store = useStore()

class SystemUserPage extends Page {
  username?: string
  reset() {
    super.reset()
    this.username = undefined
  }
}

const { loading, modalLoading, total, search, setLoadData, loadDataBase, reset, pageChange, pageSizeChange, datetimeFormat } = useBaseList(new SystemUserPage())

const systemUserData = ref<SystemUserModel[]>([])
const roles = ref<SystemRoleModel[]>([])
const addModal = ref(false)
const modalTitle = ref<string | null>(null)
const formData = reactive<SystemUserModel>({
  _id: null,
  username: null,
  password: null,
  realname: null,
  role_ids: []
})
const userForm = ref<VForm>()

const ruleValidate = computed(() => ({
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { validator: async (rule: object, value: string, callback: Function) => {
        const data = await http.get<any, any>('/api/v1/system/user/exists', {params: {username: value, id: formData._id}})
        if(data.data.exists) {
          callback(new Error('用户名已存在'))
        } else {
          callback()
        }
      }, trigger: 'blur'
    }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 8, max: 16, message: '密码长度8~16位', trigger: 'blur' },
    { pattern: /^(?![\d]+$)(?![a-zA-Z]+$)(?![-=+_.,]+$)[\da-zA-Z-=+_.,]{8,16}$/, message: '密码由字母、数字、特殊字符中的任意两种组成', trigger: 'blur' }
  ],
}))

async function loadData() {
  loading.value = true
  const data = await http.get<{params: SystemUserPage}, any>('/api/v1/system/user/list', {params: search})
  loading.value = false
  total.value = data.total
  systemUserData.value = data.data
}
setLoadData(loadData)

function add() {
  Object.assign(formData, {
    _id: null,
    username: null,
    password: null,
    realname: null,
    role_ids: []
  })
  modalTitle.value = '新增用户'
  addModal.value = true
  clearValidate()
}

function update(row: SystemUserModel) {
  Object.assign(formData, {
    _id: row._id,
    username: row.username,
    realname: row.realname,
    role_ids: row.role_ids
  })
  modalTitle.value = '修改用户'
  addModal.value = true
  clearValidate()
}

async function save() {
  userForm.value?.validate(async (valid: boolean) => {
    if (!valid) return
    modalLoading.value = true
    const data = await http.post<SystemUserModel, any>('/api/v1/system/user/save', formData)
    modalLoading.value = false
    addModal.value = false
    ElMessage.success(data.message)
    loadData()
  })
}

function remove(row: SystemUserModel) {
  ElMessageBox.confirm(`是否确认删除 ${row.username} 用户？`, '确认删除', {type: 'warning'}).then(async () => {
    const data = await http.delete<{params: {id: string}}, any>('/api/v1/system/user/delete', {params: {id: row._id}})
    if(data.status) {
      ElMessage.success(data.message)
      loadData()
    } else {
      ElMessage.warning(data.message)
    }
  }).catch(() => {})
}

function clearValidate() {
  nextTick(() => {
    userForm.value?.clearValidate()
  })
}

loadData()
http.get<never, any>('/api/v1/system/role/listAll').then(data => {
  roles.value = data
})
</script>