<script lang="ts" setup>
import ModalDigitalHumanSelect from '~/components/ModalDigitalHumanSelect.vue'

const toast = useToast()
const loginState = useLoginState()

const columns = [
  {
    key: 'id',
    label: 'ID',
    disabled: true,
  },
  {
    key: 'avatar',
    label: '头像',
    disabled: true,
  },
  {
    key: 'username',
    label: '用户名',
    disabled: true,
  },
  {
    key: 'company',
    label: '单位',
  },
  {
    key: 'mobile',
    label: '手机号',
  },
  {
    key: 'email',
    label: '电子邮箱',
  },
  {
    key: 'nickname',
    label: '昵称',
  },
  {
    key: 'sex',
    label: '性别',
  },
  {
    key: 'auth_code',
    label: '角色',
  },
  {
    key: 'actions',
    label: '操作',
  },
]

const selectedColumns = ref([...columns.filter(row => {
  return !['nickname', 'email', 'auth_code'].includes(row.key)
})])
const page = ref(1)
const pageCount = ref(15)
const state_filter = ref<'verified' | 'unverified'>('verified')
const is_verified = ref(true)
const viewingUser = ref<UserSchema | null>(null)
const isSlideOpen = computed({
  get: () => !!viewingUser.value,
  set: () => viewingUser.value = null,
})

watch([is_verified, pageCount], () => page.value = 1)
watch(state_filter, () => is_verified.value = state_filter.value === 'verified')

const {
  data: usersData,
  refresh: refreshUsersData,
  status: usersDataStatus,
} = useAsyncData(
  'systemUsers',
  () => useFetchWrapped<
    req.user.UserList & AuthedRequest,
    BaseResponse<PagedData<UserSchema>>
  >('App.User_User.ListUser', {
    token: loginState.token!,
    user_id: loginState.user.id!,
    page: page.value,
    perpage: pageCount.value,
    is_verify: is_verified.value,
  }),
  {
    watch: [page, pageCount, is_verified],
  },
)

const isDigitalSelectorOpen = ref(false)
const dhPage = ref(1)
const dhPageCount = ref(10)

watch(dhPageCount, () => dhPage.value = 1)

const {
  data: digitalHumansData,
  refresh: refreshDigitalHumansData,
  status: digitalHumansDataStatus,
} = useAsyncData(
  'currentUserDigitalHumans',
  () => useFetchWrapped<
    PagedDataRequest & AuthedRequest,
    BaseResponse<PagedData<DigitalHumanItem>>
  >('App.User_UserDigital.GetList', {
    token: loginState.token!,
    user_id: loginState.user.id!,
    to_user_id: viewingUser.value?.id || 0,
    page: dhPage.value,
    perpage: dhPageCount.value,
  }),
  {
    watch: [viewingUser, dhPage, dhPageCount],
  },
)

const items = (row: UserSchema) => [
  [
    {
      label: '数字人授权',
      icon: 'tabler:user-cog',
      click: () => openSlide(row),
      disabled: row.auth_code === 0,
    },
  ],
  [
    {
      label: row.auth_code !== 0 ? '停用账号' : '启用账号',
      icon: row.auth_code !== 0 ? 'tabler:cancel' : 'tabler:shield-check',
      click: () => setUserStatus(row.id, row.auth_code === 0),
    },
  ],
]

const openSlide = (user: UserSchema) => {
  viewingUser.value = user
}

const closeSlide = () => {
  viewingUser.value = null
}

const onDigitalHumansSelected = (digitalHumans: DigitalHumanItem[]) => {
  useFetchWrapped<
    {
      to_user_id: number
      digital_human_array: number[]
    } & AuthedRequest,
    BaseResponse<{
      total: number
      success: number
      failed: number
    }>
  >('App.User_UserDigital.CreateConnArr', {
    token: loginState.token!,
    user_id: loginState.user.id!,
    to_user_id: viewingUser.value?.id || 0,
    digital_human_array: digitalHumans.map(row => row.id || row.digital_human_id),
  }).then(res => {
    if (res.ret === 200) {
      toast.add({
        title: '授权成功',
        description: `成功授权 ${ res.data.success } 个数字人${ res.data.failed ? `，失败 ${ res.data.failed } 个` : '' }`,
        color: 'green',
        icon: 'tabler:check',
      })
      refreshDigitalHumansData()
    } else {
      toast.add({
        title: '授权失败',
        description: res.msg || '未知错误',
        color: 'red',
        icon: 'tabler:alert-triangle',
      })
    }
  })
}

const revokeDigitalHuman = (uid: number, digitalHumanId: number) => {
  useFetchWrapped<
    {
      to_user_id: number
      digital_human_id: number
    } & AuthedRequest,
    BaseResponse<{
      code: number // 1: success, 0: failed
    }>
  >('App.User_UserDigital.DeleteConn', {
    token: loginState.token!,
    user_id: loginState.user.id!,
    to_user_id: uid,
    digital_human_id: digitalHumanId,
  }).then(res => {
    if (res.ret === 200 && res.data.code === 1) {
      toast.add({
        title: '撤销成功',
        description: '已撤销数字人授权',
        color: 'green',
        icon: 'tabler:check',
      })
      refreshDigitalHumansData()
    } else {
      toast.add({
        title: '撤销失败',
        description: res.msg || '未知错误',
        color: 'red',
        icon: 'tabler:alert-triangle',
      })
    }
  })
}

const setUserStatus = (uid: number, is_verified: boolean) => {
  useFetchWrapped<
    {
      to_user_id: number
      is_verify: boolean
    } & AuthedRequest,
    BaseResponse<{
      status: number // 1: success, 0: failed
    }>
  >('App.User_User.SetUserVerify', {
    token: loginState.token!,
    user_id: loginState.user.id!,
    to_user_id: uid,
    is_verify: is_verified,
  }).then(res => {
    if (res.ret === 200 && res.data.status === 1) {
      toast.add({
        title: '操作成功',
        description: `已${ is_verified ? '启用' : '停用' }账号`,
        color: 'green',
        icon: is_verified ? 'tabler:shield-check' : 'tabler:cancel',
      })
      refreshUsersData()
    } else {
      toast.add({
        title: '操作失败',
        description: res.msg || '未知错误',
        color: 'red',
        icon: 'tabler:alert-triangle',
      })
    }
  })
}
</script>

<template>
  <LoginNeededContent need-admin>
    <div class="p-4">
      <BubbleTitle bubble-color="amber-500" subtitle="User Management" title="用户管理">
        <template #action>
          <UButton
            color="amber"
            icon="tabler:users"
            variant="soft"
            @click="openSlide(loginState.user)"
          >
            本账号数字人
          </UButton>
          <UButton
            color="amber"
            icon="tabler:reload"
            variant="soft"
            @click="refreshUsersData"
          >
            刷新
          </UButton>
        </template>
      </BubbleTitle>
      <GradientDivider line-gradient-from="amber" line-gradient-to="amber"/>
      <div>
        <div class="flex justify-between items-center w-full py-3">
          <div class="flex items-center gap-1.5">
            <span class="text-sm leading-0">每页显示:</span>
            <USelect
              v-model="pageCount"
              :options="[5, 10, 15, 20]"
              class="me-2 w-20"
              size="xs"
            />
          </div>

          <div class="flex gap-1.5 items-center">
            <USelectMenu
              v-model="state_filter"
              :options="[
                {label: '正常账号', value: 'verified', icon: 'tabler:user-check'},
                {label: '停用账号', value: 'unverified', icon: 'tabler:user-cancel'},
              ]"
              :ui-menu="{width: 'w-fit', option: {size: 'text-xs', icon: {base: 'w-4 h-4'}}}"
              size="xs"
              value-attribute="value"
            />
            <USelectMenu
              v-model="selectedColumns"
              :options="columns.filter(row => !['actions'].includes(row.key))"
              :ui-menu="{width: 'w-fit', option: {size: 'text-xs', icon: {base: 'w-4 h-4'}}}"
              multiple
            >
              <UButton
                color="gray"
                icon="tabler:layout-columns"
                size="xs"
              >
                显示列
              </UButton>
            </USelectMenu>
          </div>
        </div>
        <UTable
          :columns="selectedColumns"
          :loading="usersDataStatus === 'pending'"
          :progress="{color: 'amber', animation: 'carousel'}"
          :rows="usersData?.data.items"
          class="border dark:border-neutral-800 rounded-md"
        >
          <template #avatar-data="{ row }">
            <UAvatar :alt="row.username.toUpperCase()" :src="row.avatar" size="sm"/>
          </template>
          <template #sex-data="{ row }">
            {{ row.sex === 0 ? '' : row.sex === 1 ? '男' : '女' }}
          </template>
          <template #actions-data="{ row }">
            <UDropdown :items="items(row)">
              <UButton color="gray" icon="tabler:dots" variant="ghost"/>
            </UDropdown>
          </template>
        </UTable>
        <div class="flex justify-end py-3.5">
          <UPagination
            v-if="(usersData?.data.total || -1) > 0"
            v-model="page"
            :page-count="pageCount"
            :total="usersData?.data.total || 0"
          />
        </div>
      </div>
    </div>
    <USlideover v-model="isSlideOpen">
      <UCard
        :ui="{ body: { base: 'flex-1' }, ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }"
        class="flex flex-col flex-1"
      >
        <template #header>
          <UButton
            class="flex absolute end-5 top-5 z-10"
            color="gray"
            icon="tabler:x"
            padded
            size="sm"
            square
            variant="ghost"
            @click="closeSlide"
          />
          数字人授权管理
          <p class="text-sm font-medium text-primary">{{ viewingUser?.username }} (UID:{{ viewingUser?.id }})</p>
        </template>

        <div class="flex w-full justify-end pb-4">
          <UButton
            icon="tabler:plus"
            size="xs"
            @click="isDigitalSelectorOpen = true"
          >
            新增授权
          </UButton>
        </div>
        <div class="border dark:border-neutral-700 rounded-md">
          <UTable
            :columns="[
              {key: 'name', label: '名称'},
              {key: 'digital_human_id', label: '平台ID'},
              {key: 'model_id', label: '上游ID'},
              {key: 'actions'},
            ]"
            :loading="digitalHumansDataStatus === 'pending'"
            :rows="digitalHumansData?.data.items"
          >
            <template #actions-data="{ row }">
              <UButton
                color="gray"
                icon="tabler:cancel"
                size="xs"
                variant="ghost"
                @click="revokeDigitalHuman(viewingUser?.id || 0, row.digital_human_id)"
              >
                撤销授权
              </UButton>
            </template>
          </UTable>
        </div>
        <div class="flex justify-end py-3.5">
          <UPagination
            v-if="(digitalHumansData?.data.total || -1) > 0"
            v-model="dhPage"
            :page-count="dhPageCount"
            :total="digitalHumansData?.data.total || 0"
          />
        </div>
      </UCard>
      <ModalDigitalHumanSelect
        :disabled-digital-human-ids="digitalHumansData?.data.items.map(d => d.model_id)"
        :is-open="isDigitalSelectorOpen"
        default-tab="system"
        multiple
        @close="isDigitalSelectorOpen = false"
        @select="digitalHumans => onDigitalHumansSelected(digitalHumans as DigitalHumanItem[])"
      />
    </USlideover>
  </LoginNeededContent>
</template>

<style scoped>

</style>