<template>
  <div>
    <warning-bar title="注：右上角头像下拉可切换角色" />
    <div class="gva-table-box">
      <div class="gva-btn-list">
        <el-button
          v-preReClick
          icon="plus"
          type="primary"
          @click="addUser"
        >新增用户
        </el-button>
      </div>
      <el-table
        :data="tableData"
        row-key="ID"
      >
        <el-table-column
          align="left"
          label="头像"
          min-width="75"
        >
          <template #default="scope">
            <CustomPic
              :pic-src="scope.row.headerImg"
              style="margin-top: 8px"
            />
          </template>
        </el-table-column>
        <el-table-column
          align="left"
          label="ID"
          min-width="50"
          prop="ID"
        />
        <el-table-column
          align="left"
          label="用户名"
          min-width="150"
          prop="userName"
        />
        <el-table-column
          align="left"
          label="昵称"
          min-width="150"
          prop="nickName"
        />
        <el-table-column
          align="left"
          label="手机号"
          min-width="180"
          prop="phone"
        />
        <el-table-column
          align="left"
          label="邮箱"
          min-width="180"
          prop="email"
        />
        <el-table-column
          align="left"
          label="用户角色"
          min-width="200"
        >
          <template #default="scope">
            <el-cascader
              v-model="scope.row.authorityIds"
              :clearable="false"
              :options="authOptions"
              :props="{
                multiple: true,
                checkStrictly: true,
                label: 'authorityName',
                value: 'authorityId',
                disabled: 'disabled',
                emitPath: false
              }"
              :show-all-levels="false"
              collapse-tags
              @visible-change="
                flag => {
                  changeAuthority(scope.row, flag, 0)
                }
              "
              @remove-tag="
                removeAuth => {
                  changeAuthority(scope.row, false, removeAuth)
                }
              "
            />
          </template>
        </el-table-column>
        <el-table-column
          align="left"
          label="启用"
          min-width="150"
        >
          <template #default="scope">
            <el-switch
              v-model="scope.row.enable"
              :active-value="1"
              :inactive-value="2"
              inline-prompt
              @change="
                () => {
                  switchEnable(scope.row)
                }
              "
            />
          </template>
        </el-table-column>

        <el-table-column
          fixed="right"
          label="操作"
          min-width="350"
        >
          <template #default="scope">
            <el-popover
              v-model:visible="scope.row.visible"
              placement="top"
              width="160"
            >
              <p>确定要删除此用户吗</p>
              <div style="text-align: right; margin-top: 8px">
                <el-button
                  v-preReClick
                  link
                  type="primary"
                  @click="scope.row.visible = false"
                >取消
                </el-button>
                <el-button
                  v-preReClick
                  type="primary"
                  @click="deleteUserFunc(scope.row)"
                >确定
                </el-button>
              </div>
              <template #reference>
                <el-button
                  v-preReClick
                  icon="delete"
                  link
                  type="primary"
                >删除</el-button>
              </template>
            </el-popover>
            <el-button
              v-preReClick
              icon="edit"
              link
              type="primary"
              @click="openEdit(scope.row)"
            >编辑
            </el-button>
            <el-button
              v-preReClick
              icon="magic-stick"
              link
              type="primary"
              @click="resetPasswordFunc(scope.row)"
            >重置密码
            </el-button>
            <el-button
              v-preReClick
              icon="setting"
              link
              type="primary"
              @click="keySetting(scope.row)"
            >ukey设置
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="gva-pagination">
        <el-pagination
          :current-page="page"
          :page-size="pageSize"
          :page-sizes="[10, 30, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @current-change="handleCurrentChange"
          @size-change="handleSizeChange"
        />
      </div>
    </div>
    <el-dialog
      v-model="addUserDialog"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      title="用户"
    >
      <div style="height: 60vh; overflow: auto; padding: 0 12px">
        <el-form
          ref="userForm"
          :model="userInfo"
          :rules="rules"
          label-width="80px"
        >
          <el-form-item
            v-if="dialogFlag === 'add'"
            label="用户名"
            prop="userName"
          >
            <el-input v-model="userInfo.userName" />
          </el-form-item>
          <el-form-item
            v-if="dialogFlag === 'add'"
            label="密码"
            prop="password"
          >
            <el-input v-model="userInfo.password" />
          </el-form-item>
          <el-form-item
            label="昵称"
            prop="nickName"
          >
            <el-input v-model="userInfo.nickName" />
          </el-form-item>
          <el-form-item
            label="手机号"
            prop="phone"
          >
            <el-input v-model="userInfo.phone" />
          </el-form-item>
          <el-form-item
            label="邮箱"
            prop="email"
          >
            <el-input v-model="userInfo.email" />
          </el-form-item>
          <el-form-item
            label="用户角色"
            prop="authorityId"
          >
            <el-cascader
              v-model="userInfo.authorityIds"
              :clearable="false"
              :options="authOptions"
              :props="{
                multiple: true,
                checkStrictly: true,
                label: 'authorityName',
                value: 'authorityId',
                disabled: 'disabled',
                emitPath: false
              }"
              :show-all-levels="false"
              style="width: 100%"
            />
          </el-form-item>
          <el-form-item
            label="启用"
            prop="disabled"
          >
            <el-switch
              v-model="userInfo.enable"
              :active-value="1"
              :inactive-value="2"
              inline-prompt
            />
          </el-form-item>
          <el-form-item
            label="头像"
            label-width="80px"
          >
            <div
              style="display: inline-block"
              @click="openHeaderChange"
            >
              <img
                v-if="userInfo.headerImg"
                :src="
                  userInfo.headerImg &&
                    userInfo.headerImg.slice(0, 4) !== 'http'
                    ? path + userInfo.headerImg
                    : userInfo.headerImg
                "
                alt="头像"
                class="header-img-box"
              >
              <div
                v-else
                class="header-img-box"
              >从媒体库选择</div>
              <ChooseImg
                ref="chooseImg"
                :target="userInfo"
                :target-key="`headerImg`"
              />
            </div>
          </el-form-item>
        </el-form>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button
            v-preReClick
            @click="closeAddUserDialog"
          >取 消</el-button>
          <el-button
            v-preReClick
            type="primary"
            @click="enterAddUserDialog"
          >确 定
          </el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog
      v-model="bindKeyDialog"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
      title="ukey设置"
    >
      <div style="height: 60vh; overflow: auto; padding: 0 12px">
        <el-form
          ref="userForm"
          :model="userInfo"
          label-width="80px"
        >
          <el-divider content-position="left">用户信息</el-divider>
          <el-form-item
            v-if="dialogFlag === 'add'"
            label="用户名"
            prop="userName"
          >
            <el-input
              v-model="userInfo.userName"
              readonly
            />
          </el-form-item>
          <el-form-item
            label="昵称"
            prop="nickName"
          >
            <el-input
              v-model="userInfo.nickName"
              readonly
            />
          </el-form-item>
          <el-form-item
            label="手机号"
            prop="phone"
          >
            <el-input
              v-model="userInfo.phone"
              readonly
            />
          </el-form-item>

          <el-divider content-position="left">ukey信息</el-divider>
          <div v-if="!showCertList">
            <el-form-item
              label="sn"
              prop="sn"
            >
              <el-input
                v-model="userSn.sn"
                readonly
              />
            </el-form-item>
            <el-form-item
              label="证书"
              prop="sn"
            >
              <el-input
                v-model="userSn.certInfo"
                readonly
              />
            </el-form-item>
            <el-form-item>
              <el-button
                v-preReClick
                type="primary"
                @click="unbindKey"
              >解绑</el-button>
            </el-form-item>
          </div>

          <el-form-item
            v-if="showCertList"
            label="key"
            prop="sn"
          >
            <div style="display: flex">
              <el-select
                v-model="userSnForm.info"
                placeholder="证书名"
                style="width: 200px; margin-right: 10px"
              >
                <el-option
                  v-for="item in certs"
                  :key="item.label"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
              <el-button
                v-preReClick
                type="primary"
                @click="getCertList"
              >刷新</el-button>
            </div>
          </el-form-item>
        </el-form>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button
            v-preReClick
            @click="closeBindKeyDialog"
          >取 消</el-button>
          <el-button
            v-preReClick
            type="primary"
            @click="enterBindKeyDialog"
          >确 定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import {
  getUserList,
  setUserAuthorities,
  register,
  deleteUser
} from '@/api/user'

import { getAuthorityList } from '@/api/authority'
import CustomPic from '@/components/customPic/index.vue'
import ChooseImg from '@/components/chooseImg/index.vue'
import WarningBar from '@/components/warningBar/warningBar.vue'
import { setUserInfo, resetPassword } from '@/api/user.js'
import { info, bind, unbind } from '@/api/sn.js'

import { nextTick, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import hunca_mToken_core from '@/utils/mtoken/hunca_mToken_core.js'

defineOptions({
  name: 'User'
})

const path = ref(import.meta.env.VITE_BASE_API + '/')
// 初始化相关
const setAuthorityOptions = (AuthorityData, optionsData) => {
  AuthorityData &&
    AuthorityData.forEach(item => {
      if (item.children && item.children.length) {
        const option = {
          authorityId: item.authorityId,
          authorityName: item.authorityName,
          children: []
        }
        setAuthorityOptions(item.children, option.children)
        optionsData.push(option)
      } else {
        const option = {
          authorityId: item.authorityId,
          authorityName: item.authorityName
        }
        optionsData.push(option)
      }
    })
}

const page = ref(1)
const total = ref(0)
const pageSize = ref(10)
const tableData = ref([])
// 分页
const handleSizeChange = val => {
  pageSize.value = val
  getTableData()
}

const handleCurrentChange = val => {
  page.value = val
  getTableData()
}

// 查询
const getTableData = async() => {
  const table = await getUserList({
    page: page.value,
    pageSize: pageSize.value
  })
  if (table.code === 100000) {
    tableData.value = table.data.list
    total.value = table.data.total
    page.value = table.data.page
    pageSize.value = table.data.pageSize
  }
}

watch(
  () => tableData.value,
  () => {
    setAuthorityIds()
  }
)

const initPage = async() => {
  getTableData()
  const res = await getAuthorityList({ page: 1, pageSize: 999 })
  setOptions(res.data.list)
}

initPage()

const resetPasswordFunc = row => {
  ElMessageBox.confirm('是否将此用户密码重置为123456?', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async() => {
    const res = await resetPassword({
      ID: row.ID
    })
    if (res.code === 100000) {
      ElMessage({
        type: 'success',
        message: res.message
      })
    } else {
      ElMessage({
        type: 'error',
        message: res.message
      })
    }
  })
}
const setAuthorityIds = () => {
  tableData.value &&
    tableData.value.forEach(user => {
      user.authorityIds =
        user.authorities &&
        user.authorities.map(i => {
          return i.authorityId
        })
    })
}

// u-key 操作api
const mToken = new hunca_mToken_core()
const certs = ref([])
const userSn = ref({
  userId: '',
  certInfo: '',
  sn: ''
})

const userSnForm = ref({
  info: ''
})

const bindKeyDialog = ref(false)
const showCertList = ref(false)
const keySetting = async row => {
  bindKeyDialog.value = true
  userInfo.value = JSON.parse(JSON.stringify(row))
  userSn.value.userId = JSON.parse(JSON.stringify(row)).uuid
  const res = await info({ userId: row.uuid })
  if (res.code === 100000 && res.data) {
    userSn.value.sn = res.data.sn
    userSn.value.certInfo = res.data.userName
  } else {
    showCertList.value = true
  }
}
const getCertList = () => {
  const userList = mToken.Hunca_GetUserList()
  if (userList.length == 0) {
    ElMessage({ type: 'error', message: '未识别到key' })
    return
  }
  certs.value = []
  for (const user of userList) {
    mToken.Hunca_DealCertInfo(user)
    const certSn = mToken.Hunca_GetSignCertSn()
    const certInfo = mToken.Hunca_GetSignCertSubject()
    certs.value.push({ label: user, value: { sn: certSn, userName: certInfo }})
  }
  ElMessage({ type: 'success', message: '刷新成功' })
}
const closeBindKeyDialog = () => {
  showCertList.value = false
  bindKeyDialog.value = false
}
const enterBindKeyDialog = () => {
  bindKey()
  closeBindKeyDialog()
}
const unbindKey = async() => {
  const res = await unbind({ userId: userSn.value.userId })
  if (res.code === 100000) {
    ElMessage({ type: 'success', message: res.message })
  }
  showCertList.value = true
}
const bindKey = async() => {
  const res = await bind({
    sn: userSnForm.value.info.sn,
    userId: userSn.value.userId,
    userName: userSnForm.value.info.userName
  })
  if (res.code === 100000) {
    ElMessage({ type: 'success', message: res.message })
  }
  userSnForm.value = {}
}

const chooseImg = ref(null)
const openHeaderChange = () => {
  chooseImg.value.open()
}

const authOptions = ref([])
const setOptions = authData => {
  authOptions.value = []
  setAuthorityOptions(authData, authOptions.value)
}

const deleteUserFunc = async row => {
  const res = await deleteUser({ id: row.ID })
  if (res.code === 100000) {
    ElMessage.success('删除成功')
    row.visible = false
    await getTableData()
  }
}

// 弹窗相关
const userInfo = ref({
  username: '',
  password: '',
  nickName: '',
  headerImg: '',
  authorityId: '',
  authorityIds: [],
  enable: 1
})

const rules = ref({
  userName: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 5, message: '最低5位字符', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入用户密码', trigger: 'blur' },
    { min: 6, message: '最低6位字符', trigger: 'blur' }
  ],
  nickName: [{ required: true, message: '请输入用户昵称', trigger: 'blur' }],
  phone: [
    {
      pattern: /^1([38][0-9]|4[014-9]|[59][0-35-9]|6[2567]|7[0-8])\d{8}$/,
      message: '请输入合法手机号',
      trigger: 'blur'
    }
  ],
  email: [
    {
      pattern: /^([0-9A-Za-z\-_.]+)@([0-9a-z]+\.[a-z]{2,3}(\.[a-z]{2})?)$/g,
      message: '请输入正确的邮箱',
      trigger: 'blur'
    }
  ],
  authorityId: [{ required: true, message: '请选择用户角色', trigger: 'blur' }]
})
const userForm = ref(null)
const enterAddUserDialog = async() => {
  userInfo.value.authorityId = userInfo.value.authorityIds[0]
  userForm.value.validate(async valid => {
    if (valid) {
      const req = {
        ...userInfo.value
      }
      if (dialogFlag.value === 'add') {
        const res = await register(req)
        if (res.code === 100000) {
          ElMessage({ type: 'success', message: '创建成功' })
          await getTableData()
          closeAddUserDialog()
        }
      }
      if (dialogFlag.value === 'edit') {
        const res = await setUserInfo(req)
        if (res.code === 100000) {
          ElMessage({ type: 'success', message: '编辑成功' })
          await getTableData()
          closeAddUserDialog()
        }
      }
    }
  })
}

const addUserDialog = ref(false)
const closeAddUserDialog = () => {
  userForm.value.resetFields()
  userInfo.value.headerImg = ''
  userInfo.value.authorityIds = []
  addUserDialog.value = false
}

const dialogFlag = ref('add')

const addUser = () => {
  dialogFlag.value = 'add'
  addUserDialog.value = true
}

const tempAuth = {}
const changeAuthority = async(row, flag, removeAuth) => {
  if (flag) {
    if (!removeAuth) {
      tempAuth[row.ID] = [...row.authorityIds]
    }
    return
  }
  await nextTick()
  const res = await setUserAuthorities({
    ID: row.ID,
    authorityIds: row.authorityIds
  })
  if (res.code === 100000) {
    ElMessage({ type: 'success', message: '角色设置成功' })
  } else {
    if (!removeAuth) {
      row.authorityIds = [...tempAuth[row.ID]]
      delete tempAuth[row.ID]
    } else {
      row.authorityIds = [removeAuth, ...row.authorityIds]
    }
  }
}

const openEdit = row => {
  dialogFlag.value = 'edit'
  userInfo.value = JSON.parse(JSON.stringify(row))
  addUserDialog.value = true
}

const switchEnable = async row => {
  userInfo.value = JSON.parse(JSON.stringify(row))
  await nextTick()
  const req = {
    ...userInfo.value
  }
  const res = await setUserInfo(req)
  if (res.code === 100000) {
    ElMessage({
      type: 'success',
      message: `${req.enable === 2 ? '禁用' : '启用'}成功`
    })
    await getTableData()
    userInfo.value.headerImg = ''
    userInfo.value.authorityIds = []
  }
}
</script>

<style lang="scss">
.header-img-box {
  @apply w-52 h-52 border border-solid border-gray-300 rounded-xl flex justify-center items-center cursor-pointer;
}
</style>
