<script lang="ts" setup>
import { number, object, string, type InferType } from 'yup'
import type { FormSubmitEvent } from '#ui/types'

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

const data_layout = ref<'grid' | 'list'>('grid')
const pagination = reactive({
  page: 1,
  pageSize: 14,
})
const showSystemAvatar = ref(false)
watchEffect(() => {
  if (showSystemAvatar.value) {
    data_layout.value = 'list'
  }
})

const {
  data: userAvatarList,
  status: userAvatarStatus,
  refresh: refreshUserAvatarList,
} = useAsyncData(
  'user-digital-human',
  () =>
    useFetchWrapped<
      req.gen.DigitalHumanList & AuthedRequest,
      BaseResponse<PagedData<DigitalHumanItem>>
    >('App.User_UserDigital.GetList', {
      token: loginState.token!,
      user_id: loginState.user.id,
      to_user_id: loginState.user.id,
      page: pagination.page,
      perpage: pagination.pageSize,
    }),
  {
    watch: [pagination, showSystemAvatar],
  }
)

const {
  data: systemAvatarList,
  status: systemAvatarStatus,
  refresh: refreshSystemAvatarList,
} = useAsyncData(
  'sys-digital-human',
  () =>
    useFetchWrapped<
      req.gen.DigitalHumanList & AuthedRequest,
      BaseResponse<PagedData<DigitalHumanItem>>
    >('App.Digital_Human.GetList', {
      token: loginState.token!,
      user_id: loginState.user.id,
      to_user_id: loginState.user.id,
      page: pagination.page,
      perpage: pagination.pageSize,
    }),
  {
    watch: [pagination, showSystemAvatar],
  }
)

const onSystemAvatarDelete = (row: DigitalHumanItem) => {
  useFetchWrapped<
    { digital_human_id: number } & AuthedRequest,
    BaseResponse<{ code: 0 | 1 }>
  >('App.Digital_Human.Delete', {
    token: loginState.token!,
    user_id: loginState.user.id,
    digital_human_id: row.id!,
  })
    .then((res) => {
      if (res.ret === 200 && res.data.code === 1) {
        toast.add({
          title: '删除成功',
          description: '数字人已删除',
          color: 'green',
          icon: 'i-tabler-check',
        })
        refreshSystemAvatarList()
      } else {
        toast.add({
          title: '删除失败',
          description: res.msg || '未知错误',
          color: 'red',
          icon: 'i-tabler-alert-triangle',
        })
      }
    })
    .catch(() => {
      toast.add({
        title: '删除失败',
        description: '未知错误',
        color: 'red',
        icon: 'i-tabler-alert-triangle',
      })
    })
}

const columns = [
  {
    key: 'avatar',
    label: '图片',
  },
  {
    key: 'name',
    label: '名称',
  },
  {
    key: 'model_id',
    label: 'ID',
  },
  {
    key: 'type',
    label: '来源',
  },
  {
    key: 'description',
    label: '备注',
  },
  {
    key: 'actions',
  },
]

const sourceTypeList = [
  { label: 'xsh_wm', value: 1, color: 'blue' },   // 万木（腾讯）
  { label: 'xsh_zy', value: 2, color: 'green' },  // XSH 自有
  { label: 'xsh_fh', value: 3, color: 'purple' }, // 硅基（泛化数字人）
  { label: 'xsh_bb', value: 4, color: 'indigo' }, // 百度小冰
]

const isCreateSlideOpen = ref(false)

const createAvatarState = reactive({
  name: '',
  description: '',
  model_id: undefined,
  avatar: '',
  type: 2,
})

const createAvatarSchema = object({
  name: string().required('请输入名称'),
  description: string().required('请输入备注'),
  model_id: number().required('请输入ID'),
  avatar: string().required('请上传图片'),
  type: number().required('请选择类型'),
})

type CreateAvatarSchema = InferType<typeof createAvatarSchema>

const onCreateAvatarSubmit = (event: FormSubmitEvent<CreateAvatarSchema>) => {
  useFetchWrapped<
    CreateAvatarSchema & AuthedRequest,
    BaseResponse<{ digital_human_id: number }>
  >('App.Digital_Human.Create', {
    token: loginState.token!,
    user_id: loginState.user.id,
    name: event.data.name,
    description: event.data.description,
    model_id: event.data.model_id,
    avatar: createAvatarState.avatar,
    type: event.data.type,
  })
    .then((res) => {
      if (res.ret === 200 && res.data.digital_human_id) {
        toast.add({
          title: '创建成功',
          description: '数字人已创建',
          color: 'green',
          icon: 'i-tabler-check',
        })
        refreshSystemAvatarList()
        showSystemAvatar.value = true
        isCreateSlideOpen.value = false
      } else {
        toast.add({
          title: '创建失败',
          description: res.msg || '未知错误',
          color: 'red',
          icon: 'i-tabler-alert-triangle',
        })
      }
    })
    .catch(() => {
      toast.add({
        title: '创建失败',
        description: '未知错误',
        color: 'red',
        icon: 'i-tabler-alert-triangle',
      })
    })
}

const onAvatarUpload = async (files: FileList) => {
  const file = files[0]
  try {
    const url = await useFileGo(file, 'material')
    createAvatarState.avatar = url
    toast.add({
      title: '上传文件成功',
      description: '文件已上传',
      color: 'green',
      icon: 'i-tabler-check',
    })
  } catch {
    toast.add({
      title: '上传文件失败',
      description: '请重试',
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
  }
}
</script>

<template>
  <div class="h-full">
    <div class="p-4 pb-0">
      <BubbleTitle
        title="数字讲师管理"
        subtitle="Avatars"
      >
        <template #action>
          <UButton
            color="gray"
            variant="soft"
            :label="showSystemAvatar ? '显示用户数字人' : '显示系统数字人'"
            @click="showSystemAvatar = !showSystemAvatar"
          />
          <UButton
            v-if="loginState.user.auth_code === 2"
            color="amber"
            variant="soft"
            label="创建数字人"
            @click="isCreateSlideOpen = true"
          />
          <UButton
            :icon="
              data_layout === 'grid'
                ? 'tabler:layout-list'
                : 'tabler:layout-grid'
            "
            variant="soft"
            color="gray"
            @click="data_layout = data_layout === 'grid' ? 'list' : 'grid'"
            :label="data_layout === 'grid' ? '列表视图' : '宫格视图'"
          />
        </template>
      </BubbleTitle>
      <GradientDivider />
    </div>
    <div class="p-4">
      <UAlert
        v-if="showSystemAvatar && loginState.user.auth_code === 2"
        icon="tabler:user-shield"
        title="正在显示系统数字人"
        description="当前正在显示和管理系统数字人，仅管理员可见"
        class="mb-4"
      />
      <div
        v-if="data_layout === 'grid'"
        class="grid grid-cols-7 gap-4"
      >
        <div
          v-for="(avatar, k) in showSystemAvatar
            ? systemAvatarList?.data.items
            : userAvatarList?.data.items"
          :key="avatar.model_id || k"
          class="relative rounded-lg shadow overflow-hidden w-full aspect-[9/16] group"
        >
          <NuxtImg
            :src="avatar.avatar"
            class="w-full h-full object-cover"
          />
          <div
            class="absolute inset-x-0 bottom-0 p-2 bg-gradient-to-t from-black/50 to-transparent flex gap-2"
          >
            <UBadge
              color="white"
              variant="solid"
              icon="tabler:user-screen"
            >
              {{ avatar.name }}
            </UBadge>
            <template
              v-for="(t, i) in sourceTypeList"
              :key="i"
            >
              <UBadge
                v-if="t.value === avatar.type"
                variant="subtle"
                :color="t.color"
                :label="t.label"
              />
            </template>
          </div>
          <div
            class="absolute inset-0 flex flex-col justify-center items-center bg-white/50 dark:bg-neutral-800/50 backdrop-blur opacity-0 group-hover:opacity-100 transition-opacity"
          >
            <UButtonGroup>
              <UButton
                color="black"
                icon="tabler:download"
                label="下载图片"
                @click="
                  () => {
                    const { download } = useDownload(
                      avatar.avatar,
                      `数字人_${avatar.name}.png`
                    )
                    download()
                  }
                "
              />
            </UButtonGroup>
            <span
              class="text-xs font-medium text-neutral-400 dark:text-neutral-300 pt-4"
            >
              ID: {{ avatar.model_id }}
            </span>
          </div>
        </div>
      </div>
      <div v-else>
        <div class="flex flex-col gap-4">
          <UTable
            :rows="
              showSystemAvatar
                ? systemAvatarList?.data.items
                : userAvatarList?.data.items
            "
            :columns="columns"
            :loading="userAvatarStatus === 'pending'"
            :progress="{ color: 'amber', animation: 'carousel' }"
            class="border dark:border-neutral-800 rounded-md"
          >
            <template #avatar-data="{ row }">
              <NuxtImg
                :src="row.avatar"
                class="h-16 aspect-[9/16] rounded-lg"
              />
            </template>
            <template #type-data="{ row }">
              <template
                v-for="(t, i) in sourceTypeList"
                :key="i"
              >
                <UBadge
                  v-if="t.value === row.type"
                  variant="subtle"
                  :color="t.color"
                  :label="t.label"
                />
              </template>
            </template>
            <template #actions-data="{ row }">
              <div class="flex gap-2">
                <UButton
                  color="gray"
                  icon="tabler:download"
                  label="下载图片"
                  variant="soft"
                  size="xs"
                  @click="
                    () => {
                      const { download } = useDownload(
                        row.avatar,
                        `数字人_${row.name}.png`
                      )
                      download()
                    }
                  "
                />
                <UButton
                  color="red"
                  icon="tabler:trash"
                  label="删除"
                  variant="soft"
                  size="xs"
                  @click="onSystemAvatarDelete(row)"
                />
              </div>
            </template>
          </UTable>
        </div>
      </div>
      <div class="flex justify-end mt-4">
        <UPagination
          v-model="pagination.page"
          :max="9"
          :page-count="pagination.pageSize"
          :total="userAvatarList?.data.total || 0"
        />
      </div>
    </div>

    <USlideover v-model="isCreateSlideOpen">
      <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="isCreateSlideOpen = false"
          />
          创建系统数字人
        </template>

        <UForm
          class="space-y-3"
          :schema="createAvatarSchema"
          :state="createAvatarState"
          @submit="onCreateAvatarSubmit"
        >
          <UFormGroup
            label="名称"
            name="name"
          >
            <UInput v-model="createAvatarState.name" />
          </UFormGroup>
          <UFormGroup
            label="备注"
            name="description"
          >
            <UInput v-model="createAvatarState.description" />
          </UFormGroup>
          <UFormGroup
            label="ID"
            name="model_id"
          >
            <UInput v-model="createAvatarState.model_id" />
          </UFormGroup>
          <UFormGroup
            label="图片"
            name="avatar"
          >
            <UniFileDnD
              accept="image/png,image/jpeg"
              @change="onAvatarUpload"
            />
          </UFormGroup>
          <UFormGroup
            label="类型"
            name="type"
          >
            <USelectMenu
              v-model="createAvatarState.type"
              value-attribute="value"
              :options="sourceTypeList"
            />
          </UFormGroup>
          <UFormGroup class="flex justify-end pt-4">
            <UButton
              type="submit"
              color="primary"
              label="创建"
            />
          </UFormGroup>
        </UForm>
      </UCard>
    </USlideover>
  </div>
</template>

<style scoped></style>
