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

useHead({
  title: '数字人定制管理 | 管理员',
})

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

// 定制记录列表
const pagination = reactive({
  page: 1,
  pageSize: 20,
})

const {
  data: trainListResp,
  status: trainListStatus,
  refresh: refreshTrainList,
} = useAsyncData(
  'digital-train-list',
  () =>
    useFetchWrapped<
      PagedDataRequest & AuthedRequest,
      BaseResponse<PagedData<DigitalHumanTrainItem>>
    >('App.Digital_Train.GetList', {
      token: loginState.token!,
      user_id: loginState.user.id,
      to_user_id: loginState.user.id,
      page: pagination.page,
      perpage: pagination.pageSize,
    }),
  {
    watch: [pagination],
  }
)

const trainList = computed(() => trainListResp.value?.data.items || [])

// 表格列定义
const columns = [
  {
    key: 'id',
    label: 'ID',
  },
  {
    key: 'dh_name',
    label: '数字人名称',
  },
  {
    key: 'organization',
    label: '单位名称',
  },
  {
    key: 'user_id',
    label: '用户ID',
  },
  {
    key: 'create_time',
    label: '创建时间',
  },
  {
    key: 'video_url',
    label: '数字人视频',
  },
  {
    key: 'auth_video_url',
    label: '授权视频',
  },
  {
    key: 'actions',
    label: '操作',
  },
]

// 录入数字人相关状态
const isProcessModalOpen = ref(false)
const currentTrainItem = ref<DigitalHumanTrainItem | null>(null)

const processFormState = reactive({
  name: '',
  model_id: undefined as number | undefined,
  description: '',
  type: 2, // 默认为XSH自有
})

const processFormSchema = object({
  name: string().required('请输入名称'),
  model_id: number().required('请输入数字人ID'),
  description: string().required('请输入描述'),
  type: number().required('请选择类型'),
})

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 avatarFile = ref<File | null>(null)
const isProcessing = ref(false)

// 处理训练素材：录入系统数字人并分配给用户
const handleProcessTrain = (item: DigitalHumanTrainItem) => {
  currentTrainItem.value = item

  // 预填充表单数据
  processFormState.name = item.dh_name
  processFormState.model_id = undefined
  processFormState.description = `基于${item.organization}提交的训练素材创建`
  processFormState.type = 2

  isProcessModalOpen.value = true
}

// 处理文件上传
const handleAvatarUpload = (files: FileList) => {
  const file = files[0]
  if (!file) return

  // 验证文件类型
  if (!file.type.startsWith('image/')) {
    toast.add({
      title: '文件格式错误',
      description: '请上传图片文件',
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
    return
  }

  // 验证文件大小 (10MB)
  if (file.size > 10 * 1024 * 1024) {
    toast.add({
      title: '文件过大',
      description: '图片文件大小不能超过10MB',
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
    return
  }

  avatarFile.value = file
}

// 提交录入表单
const onProcessSubmit = async (
  event: FormSubmitEvent<typeof processFormState>
) => {
  if (!currentTrainItem.value) return

  if (!avatarFile.value) {
    toast.add({
      title: '请上传数字人预览图',
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
    return
  }

  if (isProcessing.value) return

  try {
    isProcessing.value = true

    // 1. 上传预览图
    const avatarUrl = await useFileGo(avatarFile.value, 'material')

    // 2. 创建系统数字人
    const createSystemResult = await useFetchWrapped<
      {
        name: string
        model_id: number
        type: number
        description: string
        avatar: string
      } & AuthedRequest,
      BaseResponse<{ digital_human_id: number }>
    >('App.Digital_Human.Create', {
      token: loginState.token!,
      user_id: loginState.user.id,
      name: event.data.name,
      model_id: event.data.model_id!,
      type: event.data.type,
      description: event.data.description,
      avatar: avatarUrl,
    })

    if (
      createSystemResult.ret !== 200 ||
      !createSystemResult.data.digital_human_id
    ) {
      throw new Error(createSystemResult.msg || '创建系统数字人失败')
    }

    // 3. 分配数字人给提交素材的用户
    const createUserResult = await 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: currentTrainItem.value.user_id,
      digital_human_array: [createSystemResult.data.digital_human_id],
    })

    if (createUserResult.ret !== 200 || createUserResult.data.success === 0) {
      throw new Error(createUserResult.msg || '分配用户数字人失败')
    }

    toast.add({
      title: '录入成功',
      description: `数字人"${event.data.name}"已成功录入并分配给用户 ${currentTrainItem.value.user_id}${
        createUserResult.data.failed
          ? `，失败 ${createUserResult.data.failed} 个`
          : ''
      }`,
      color: 'green',
      icon: 'i-tabler-check',
    })

    // 删除定制记录
    await handleDeleteTrain(currentTrainItem.value)

    // 重置表单和状态
    processFormState.name = ''
    processFormState.model_id = undefined
    processFormState.description = ''
    processFormState.type = 2
    avatarFile.value = null
    currentTrainItem.value = null
    isProcessModalOpen.value = false

    // 刷新列表
    await refreshTrainList()
  } catch (error) {
    console.error('录入数字人失败:', error)
    const errorMessage =
      error instanceof Error ? error.message : '录入失败，请重试'
    toast.add({
      title: '录入失败',
      description: errorMessage,
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
  } finally {
    isProcessing.value = false
  }
}

// 删除定制记录
const handleDeleteTrain = async (item: DigitalHumanTrainItem) => {
  try {
    const result = await useFetchWrapped<
      { train_id: number } & AuthedRequest,
      BaseResponse<{ code: 0 | 1 }>
    >('App.Digital_Train.Delete', {
      token: loginState.token!,
      user_id: loginState.user.id,
      train_id: item.id,
    })

    if (result.ret === 200 && result.data.code === 1) {
      toast.add({
        title: '删除成功',
        description: '定制记录已删除',
        color: 'green',
        icon: 'i-tabler-check',
      })
      await refreshTrainList()
    } else {
      throw new Error(result.msg || '删除失败')
    }
  } catch (error) {
    console.error('删除定制记录失败:', error)
    const errorMessage =
      error instanceof Error ? error.message : '删除失败，请重试'
    toast.add({
      title: '删除失败',
      description: errorMessage,
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
  }
}

// 格式化时间
const formatTime = (timestamp: number) => {
  return new Date(timestamp * 1000).toLocaleString('zh-CN')
}

// 预览视频
const previewVideo = (videoUrl: string, title: string) => {
  // 创建一个简单的视频预览弹窗
  const videoModal = document.createElement('div')
  videoModal.className =
    'fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50'

  const videoContainer = document.createElement('div')
  videoContainer.className =
    'bg-white dark:bg-gray-800 rounded-lg p-4 max-w-4xl max-h-[80vh] overflow-auto'

  const titleElement = document.createElement('h3')
  titleElement.textContent = title
  titleElement.className =
    'text-lg font-semibold mb-4 text-gray-900 dark:text-white'

  const video = document.createElement('video')
  video.src = videoUrl
  video.controls = true
  video.className = 'w-full max-h-[60vh]'

  const closeButton = document.createElement('button')
  closeButton.textContent = '关闭'
  closeButton.className =
    'mt-4 px-4 py-2 bg-gray-500 text-white rounded-sm hover:bg-gray-600'
  closeButton.onclick = () => {
    document.body.removeChild(videoModal)
  }

  videoContainer.appendChild(titleElement)
  videoContainer.appendChild(video)
  videoContainer.appendChild(closeButton)
  videoModal.appendChild(videoContainer)

  videoModal.onclick = (e) => {
    if (e.target === videoModal) {
      document.body.removeChild(videoModal)
    }
  }

  document.body.appendChild(videoModal)
}
</script>

<template>
  <div>
    <div class="p-4 pb-0">
      <BubbleTitle
        title="数字人定制管理"
        subtitle="Digital Human Training Management"
      >
        <template #action>
          <UButton
            color="gray"
            variant="soft"
            icon="i-tabler-refresh"
            label="刷新"
            @click="refreshTrainList"
          />
        </template>
      </BubbleTitle>
      <GradientDivider />
    </div>

    <div class="p-4">
      <UAlert
        v-if="loginState.user.auth_code === 2"
        icon="i-tabler-user-shield"
        title="管理员功能"
        description="当前正在管理用户提交的数字人定制请求，仅管理员可见"
        class="mb-4"
      />

      <div class="flex flex-col gap-4">
        <UTable
          :rows="trainList"
          :columns="columns"
          :loading="trainListStatus === 'pending'"
          :progress="{ color: 'amber', animation: 'carousel' }"
          class="border dark:border-neutral-800 rounded-md"
        >
          <template #create_time-data="{ row }">
            <span class="text-sm">{{ formatTime(row.create_time) }}</span>
          </template>

          <template #video_url-data="{ row }">
            <div class="flex gap-2">
              <UButton
                color="blue"
                variant="soft"
                size="xs"
                icon="i-tabler-download"
                :to="row.video_url"
                target="_blank"
                label="下载"
              />
              <UButton
                color="green"
                variant="soft"
                size="xs"
                icon="i-tabler-eye"
                label="预览"
                @click="previewVideo(row.video_url, '数字人视频')"
              />
            </div>
          </template>

          <template #auth_video_url-data="{ row }">
            <div class="flex gap-2">
              <UButton
                color="blue"
                variant="soft"
                size="xs"
                icon="i-tabler-download"
                :to="row.auth_video_url"
                target="_blank"
                label="下载"
              />
              <UButton
                color="green"
                variant="soft"
                size="xs"
                icon="i-tabler-eye"
                label="预览"
                @click="previewVideo(row.auth_video_url, '授权视频')"
              />
            </div>
          </template>

          <template #actions-data="{ row }">
            <div class="flex gap-2">
              <UButton
                color="amber"
                variant="soft"
                size="xs"
                icon="i-tabler-user-cog"
                label="录入"
                @click="handleProcessTrain(row)"
              />
              <UButton
                color="red"
                variant="soft"
                size="xs"
                icon="i-tabler-trash"
                label="删除"
                @click="handleDeleteTrain(row)"
              />
            </div>
          </template>
        </UTable>

        <div class="flex justify-end">
          <UPagination
            v-model="pagination.page"
            :max="9"
            :page-count="pagination.pageSize"
            :total="trainListResp?.data.total || 0"
          />
        </div>
      </div>
    </div>

    <!-- 录入数字人弹窗 -->
    <USlideover v-model="isProcessModalOpen">
      <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="i-tabler-x"
            padded
            size="sm"
            square
            variant="ghost"
            @click="isProcessModalOpen = false"
          />
          <div>
            <h3 class="text-lg font-semibold">录入数字人</h3>
            <p class="text-sm text-gray-500 mt-1">
              为"{{ currentTrainItem?.dh_name }}"创建系统数字人并分配给用户
              {{ currentTrainItem?.user_id }}
            </p>
          </div>
        </template>

        <UForm
          class="space-y-4"
          :schema="processFormSchema"
          :state="processFormState"
          @submit="onProcessSubmit"
        >
          <UFormGroup
            label="名称"
            name="name"
          >
            <UInput v-model="processFormState.name" />
          </UFormGroup>

          <UFormGroup
            label="数字人ID"
            name="model_id"
            description="请输入五位数字人ID"
          >
            <UInput
              v-model="processFormState.model_id"
              type="number"
              placeholder="请输入数字人ID"
            />
          </UFormGroup>

          <UFormGroup
            label="描述"
            name="description"
          >
            <UTextarea
              v-model="processFormState.description"
              rows="3"
            />
          </UFormGroup>

          <UFormGroup
            label="供应商类型"
            name="type"
          >
            <USelectMenu
              v-model="processFormState.type"
              value-attribute="value"
              :options="sourceTypeList"
            />
          </UFormGroup>

          <UFormGroup
            label="数字人预览图"
            required
          >
            <UniFileDnD
              accept="image/png,image/jpeg,image/jpg"
              @change="handleAvatarUpload"
            >
              <template #default>
                <div class="text-center">
                  <UIcon
                    name="i-heroicons-photo"
                    class="mx-auto h-12 w-12 text-gray-400"
                  />
                  <div class="mt-2">
                    <span class="text-sm text-gray-600 dark:text-gray-400">
                      {{ avatarFile ? avatarFile.name : '点击或拖拽上传图片' }}
                    </span>
                  </div>
                </div>
              </template>
            </UniFileDnD>
          </UFormGroup>

          <div class="flex justify-end gap-2 pt-4">
            <UButton
              type="button"
              color="gray"
              variant="soft"
              @click="isProcessModalOpen = false"
            >
              取消
            </UButton>
            <UButton
              type="submit"
              color="primary"
              :loading="isProcessing"
              :disabled="isProcessing"
            >
              {{ isProcessing ? '录入中...' : '录入并分配' }}
            </UButton>
          </div>
        </UForm>
      </UCard>
    </USlideover>
  </div>
</template>

<style scoped></style>
