<script lang="ts" setup>
import type { PropType } from 'vue'

const props = defineProps({
  video: {
    type: Object as PropType<GBVideoItem>,
    required: true,
  },
})

const emit = defineEmits({
  delete: (video: GBVideoItem) => video,
})

const dayjs = useDayjs()
const toast = useToast()

const isFailed = computed(() => {
  return props.video.progress === -1
})
const isPreviewModalOpen = ref(false)
const isVideoBackgroundPreviewOpen = ref(false)
const isFullContentOpen = ref(false)
const downloadingState = reactive({
  subtitle: 0,
  video: 0,
})

// 背景选择相关状态
const selectedBackgroundFile = ref<File | null>(null)
const selectedBackgroundPreview = ref<string>('')
const isCombinatorLoading = ref(false)
const compositingProgress = ref(0)
const compositingPhase = ref<
  'loading' | 'analyzing' | 'preparing' | 'executing' | 'finalizing'
>('loading')
const combinatorError = ref<string>('')
const fileInputRef = ref<HTMLInputElement | null>(null)
const compositedVideoBlob = ref<Blob | null>(null)

// 阶段显示文本
const phaseText = computed(() => {
  const phaseMap: Record<typeof compositingPhase.value, string> = {
    loading: '加载资源...',
    analyzing: '分析图片...',
    preparing: '准备合成...',
    executing: '合成中...',
    finalizing: '完成处理...',
  }
  return phaseMap[compositingPhase.value]
})

const handleBackgroundFileSelect = (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]

  if (!file) return

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

  selectedBackgroundFile.value = file
  const reader = new FileReader()
  reader.onload = (e) => {
    selectedBackgroundPreview.value = e.target?.result as string
  }
  reader.readAsDataURL(file)
  combinatorError.value = ''
  compositedVideoBlob.value = null
}

const composeBackgroundVideo = async () => {
  if (!selectedBackgroundFile.value) {
    toast.add({
      title: '未选择图片',
      description: '请先选择一个背景图片',
      color: 'orange',
      icon: 'i-tabler-alert-circle',
    })
    return
  }

  try {
    isCombinatorLoading.value = true
    compositingProgress.value = 0
    combinatorError.value = ''

    // 使用 FFmpeg WASM 进行视频背景合成
    const resultBlob = await useVideoBackgroundCompositing(
      props.video.video_alpha_url!,
      selectedBackgroundFile.value,
      {
        onProgress: (info) => {
          compositingProgress.value = info.progress
          compositingPhase.value = info.phase
        },
      }
    )

    compositedVideoBlob.value = resultBlob

    toast.add({
      title: '合成成功',
      description: '背景已成功合成，可预览或下载',
      color: 'green',
      icon: 'i-tabler-check',
    })
  } catch (err: any) {
    combinatorError.value = err.message || '合成失败，请重试'
    toast.add({
      title: '合成失败',
      description: combinatorError.value,
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
  } finally {
    isCombinatorLoading.value = false
  }
}

const downloadCompositedVideo = () => {
  if (!compositedVideoBlob.value) return

  const url = URL.createObjectURL(compositedVideoBlob.value)
  const link = document.createElement('a')
  link.href = url
  link.download = `${props.video.title || props.video.task_id}_composited.mp4`
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  URL.revokeObjectURL(url)
}

const compositedVideoUrl = computed(() => {
  return compositedVideoBlob.value
    ? URL.createObjectURL(compositedVideoBlob.value)
    : ''
})

const startDownload = (url: string, filename: string) => {
  if (url.endsWith('.ass')) {
    downloadingState.subtitle = 0
  } else {
    downloadingState.video = 0
  }

  const { download, progressEmitter } = useDownload(url, filename)

  progressEmitter.on('progress', (progress) => {
    if (url.endsWith('.ass')) {
      downloadingState.subtitle = progress
    } else {
      downloadingState.video = progress
    }
    console.log(downloadingState)
  })

  progressEmitter.on('done', () => {
    if (url.endsWith('.ass')) {
      downloadingState.subtitle = 100
    } else {
      downloadingState.video = 100
    }
    toast.add({
      title: '下载完成',
      description: '资源下载已完成',
      color: 'green',
      icon: 'i-tabler-check',
    })
  })

  progressEmitter.on('error', (err) => {
    if (url.endsWith('.ass')) {
      downloadingState.subtitle = 0
    } else {
      downloadingState.video = 0
    }
    toast.add({
      title: '下载失败',
      description: err.message || '下载失败，未知错误',
      color: 'red',
      icon: 'i-tabler-alert-triangle',
    })
  })

  download()
}
</script>

<template>
  <div
    class="w-full flex gap-2 rounded-xl border border-neutral-200 dark:border-neutral-700 hover:shadow transition overflow-hidden p-3"
  >
    <div
      class="flex-0 h-48 aspect-[10/16] flex flex-col items-center justify-center rounded-lg shadow overflow-hidden relative group"
    >
      <div
        v-if="!video.video_cover"
        class="w-full h-full flex flex-col justify-center items-center gap-2"
        :class="!isFailed ? 'bg-primary' : 'bg-rose-400'"
      >
        <UIcon
          v-if="!isFailed"
          class="animate-spin text-4xl text-white"
          name="tabler:loader"
        />
        <UIcon
          v-else
          class="text-4xl text-white"
          name="tabler:alert-triangle"
        />
        <div class="flex flex-col items-center gap-0.5">
          <span class="text-sm font-bold text-white/90">
            {{ isFailed ? '生成失败' : '火速生成中...' }}
          </span>
          <span
            v-if="!isFailed"
            class="text-xs font-medium text-white/50"
          >
            {{ video.progress }}%
          </span>
        </div>
      </div>
      <NuxtImg
        v-else
        :src="video.video_cover"
        class="w-full h-full brightness-90 object-cover"
      />
      <div
        class="absolute inset-0 bg-black/10 backdrop-blur-md flex justify-center items-center rounded-lg opacity-0 group-hover:opacity-100 duration-300"
      >
        <div
          class="rounded-full w-14 aspect-square bg-gray-300/50 backdrop-blur-md flex justify-center items-center cursor-pointer"
          @click="isPreviewModalOpen = true"
        >
          <Icon
            name="i-tabler-play"
            class="text-white text-3xl"
          />
        </div>
      </div>
    </div>
    <div class="flex-1 flex flex-col justify-between gap-2">
      <div
        class="flex-1 rounded-lg bg-neutral-100 dark:bg-neutral-800 p-2 px-2.5"
      >
        <ul class="grid grid-cols-2 gap-1.5">
          <li class="col-span-2">
            <!--            <h2 class="text-2xs font-medium text-primary-500">标题</h2>-->
            <p class="text-sm font-bold line-clamp-1">
              {{ video.title || '无标题' }}
            </p>
          </li>
          <li class="">
            <h2 class="text-2xs font-medium text-primary-500">完成时间</h2>
            <p class="text-xs line-clamp-1">
              {{
                video.complete_time
                  ? dayjs(video.complete_time * 1000).format(
                      'YYYY-MM-DD HH:mm:ss'
                    )
                  : '进行中'
              }}
            </p>
          </li>
          <li class="">
            <h2 class="text-2xs font-medium text-primary-500">生成耗时</h2>
            <p class="text-xs line-clamp-1">
              {{
                video.duration
                  ? dayjs.duration(video.duration || 0).format('HH:mm:ss')
                  : '进行中'
              }}
            </p>
          </li>
          <li
            class="col-span-2 cursor-pointer"
            @click="isFullContentOpen = true"
          >
            <h2 class="text-2xs font-medium text-primary-500">驱动文本</h2>
            <p class="text-xs line-clamp-4 text-justify">{{ video.content }}</p>
          </li>
        </ul>
      </div>
      <div
        class="flex justify-end sm:justify-between items-center group flex-nowrap whitespace-nowrap"
      >
        <!--        <div-->
        <!--          class="hidden sm:flex items-center gap-1 transition-all group-hover:opacity-0 group-hover:pointer-events-none">-->
        <!--          <UIcon class="text-primary text-lg" name="i-tabler-user-square-rounded"/>-->
        <!--          <p class="text-xs">数字人 {{ video.digital_human_id }}</p>-->
        <!--        </div>-->
        <div
          class="w-fit hidden sm:flex items-center gap-1 transition-all group-hover:opacity-0 group-hover:pointer-events-none"
        >
          <p class="text-2xs text-neutral-400 dark:text-neutral-500">
            {{ video.digital_human_id }}
          </p>
        </div>
        <div class="space-x-2">
          <UButton
            class="transition-all sm:opacity-0 sm:translate-x-4 sm:pointer-events-none group-hover:opacity-100 group-hover:translate-x-0 group-hover:pointer-events-auto"
            color="red"
            icon="i-tabler-trash"
            size="xs"
            variant="soft"
            @click="emit('delete', video)"
          />
          <UButtonGroup size="xs">
            <UButton
              :label="
                downloadingState.subtitle > 0 && downloadingState.subtitle < 100
                  ? `${downloadingState.subtitle.toFixed(0)}%`
                  : '字幕'
              "
              :loading="
                downloadingState.subtitle > 0 && downloadingState.subtitle < 100
              "
              :disabled="!video.subtitle"
              color="primary"
              leading-icon="i-tabler-file-download"
              variant="soft"
              @click="
                startDownload(
                  video.subtitle!,
                  (video.title || video.task_id) + '.ass'
                )
              "
            />
            <UDropdown
              :items="[
                [
                  {
                    label: '绿幕视频下载',
                    icon: 'tabler:download',
                    click: () => {
                      startDownload(
                        video.video_url!,
                        (video.title || video.task_id) + '.mp4'
                      )
                    },
                  },
                  {
                    label: '合成背景图片',
                    icon: 'tabler:background',
                    click: () => {
                      isVideoBackgroundPreviewOpen = true
                    },
                    disabled: !video.video_alpha_url,
                  },
                ],
              ]"
            >
              <UButton
                :label="
                  downloadingState.video > 0 && downloadingState.video < 100
                    ? `${downloadingState.video.toFixed(0)}%`
                    : '视频'
                "
                :loading="
                  downloadingState.video > 0 && downloadingState.video < 100
                "
                :disabled="!video.video_url"
                color="primary"
                leading-icon="i-tabler-download"
                variant="soft"
              />
            </UDropdown>
          </UButtonGroup>
        </div>
      </div>
    </div>
    <!-- Full video content -->
    <UModal v-model="isFullContentOpen">
      <UCard
        :ui="{
          ring: '',
          divide: 'divide-y divide-gray-100 dark:divide-gray-800',
        }"
      >
        <template #header>
          <div class="flex items-center justify-between">
            <h3
              class="text-base font-semibold leading-6 text-gray-900 dark:text-white"
            >
              {{ video.title || '无标题' }}
              <span class="block text-xs text-primary">驱动内容</span>
            </h3>
            <UButton
              color="gray"
              icon="i-tabler-x"
              variant="ghost"
              @click="isFullContentOpen = false"
            />
          </div>
        </template>

        <div>
          <article class="prose">
            <p class="text-justify">{{ video.content }}</p>
          </article>
        </div>

        <template #footer>
          <div class="flex justify-end gap-2">
            <UButton
              color="primary"
              @click="isFullContentOpen = false"
            >
              关闭
            </UButton>
          </div>
        </template>
      </UCard>
    </UModal>
    <UModal v-model="isPreviewModalOpen">
      <UCard
        :ui="{
          ring: '',
          divide: 'divide-y divide-gray-100 dark:divide-gray-800',
        }"
      >
        <template #header>
          <div class="flex items-center justify-between">
            <div
              class="text-base font-semibold leading-6 text-gray-900 dark:text-white overflow-hidden"
            >
              <p>绿幕视频预览</p>
              <p
                class="text-xs text-blue-500 w-full overflow-hidden text-nowrap text-ellipsis"
              >
                {{ video.title }}
              </p>
            </div>
            <UButton
              class="-my-1"
              color="gray"
              icon="i-tabler-x"
              variant="ghost"
              @click="isPreviewModalOpen = false"
            />
          </div>
        </template>

        <video
          class="w-full rounded shadow"
          controls
          autoplay
          :src="video.video_url"
        />
      </UCard>
    </UModal>
    <UModal v-model="isVideoBackgroundPreviewOpen">
      <UCard
        :ui="{
          ring: '',
          divide: 'divide-y divide-gray-100 dark:divide-gray-800',
        }"
      >
        <template #header>
          <div class="flex items-center justify-between">
            <div
              class="text-base font-semibold leading-6 text-gray-900 dark:text-white overflow-hidden"
            >
              <p>视频背景合成</p>
              <p
                class="text-xs text-blue-500 w-full overflow-hidden text-nowrap text-ellipsis"
              >
                {{ video.title }}
              </p>
            </div>
            <UButton
              class="-my-1"
              color="gray"
              icon="i-tabler-x"
              variant="ghost"
              @click="isVideoBackgroundPreviewOpen = false"
            />
          </div>
        </template>

        <div class="space-y-4">
          <!-- 背景图片选择区域 -->
          <div
            v-if="!compositedVideoBlob && !isCombinatorLoading"
            class="border-2 border-dashed border-neutral-200 dark:border-neutral-700 rounded-lg p-4"
          >
            <div class="space-y-3">
              <div class="text-sm font-medium text-gray-900 dark:text-white">
                选择背景图片
              </div>

              <!-- 预览区域 -->
              <!-- <div v-if="selectedBackgroundPreview" class="relative w-full aspect-video rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-800">
                <img :src="selectedBackgroundPreview" alt="背景预览" class="w-full h-full object-cover" />
              </div>
              <div v-else class="w-full aspect-video rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-800 flex flex-col items-center justify-center gap-2">
                <UIcon class="text-3xl text-neutral-400" name="tabler:photo" />
                <span class="text-xs text-neutral-400">点击选择图片</span>
              </div> -->

              <!-- 文件输入 -->
              <input
                ref="fileInputRef"
                type="file"
                accept="image/*"
                class="hidden"
                @change="handleBackgroundFileSelect"
              />

              <!-- 选择按钮 -->
              <UButton
                block
                color="primary"
                icon="i-tabler-photo-plus"
                label="选择图片"
                variant="soft"
                @click="fileInputRef?.click()"
              />

              <!-- 选中的文件名 -->
              <div
                v-if="selectedBackgroundFile"
                class="text-xs text-neutral-500 dark:text-neutral-400"
              >
                已选择: {{ selectedBackgroundFile.name }}
              </div>
            </div>
          </div>

          <!-- 错误提示 -->
          <UAlert
            v-if="combinatorError"
            color="red"
            icon="i-tabler-alert-triangle"
            title="合成失败"
            :description="combinatorError"
          />

          <!-- 合成进度 -->
          <div
            v-if="isCombinatorLoading"
            class="space-y-2"
          >
            <div class="flex justify-between items-center">
              <span class="text-sm font-medium text-gray-900 dark:text-white">
                {{ phaseText }}
              </span>
              <span class="text-xs text-neutral-500">
                {{ compositingProgress }}%
              </span>
            </div>
            <UProgress :value="compositingProgress" />
          </div>

          <!-- 合成预览 -->
          <div
            v-if="compositedVideoBlob"
            class="space-y-2"
          >
            <div class="text-sm font-medium text-gray-900 dark:text-white">
              视频预览
            </div>
            <video
              class="w-full rounded-lg shadow bg-black"
              controls
              autoplay
              muted
              :src="compositedVideoUrl"
            />
          </div>
        </div>

        <template #footer>
          <div class="flex justify-end gap-2">
            <UButton
              color="gray"
              label="取消"
              :disabled="isCombinatorLoading"
              @click="isVideoBackgroundPreviewOpen = false"
            />
            <UButton
              v-if="compositedVideoBlob"
              color="gray"
              label="重新选择"
              @click="
                () => {
                  selectedBackgroundFile = null
                  selectedBackgroundPreview = ''
                  compositedVideoBlob = null
                  combinatorError = ''
                  isCombinatorLoading = false
                }
              "
            />
            <UButton
              v-if="compositedVideoBlob"
              color="green"
              icon="i-tabler-download"
              label="下载合成视频"
              @click="downloadCompositedVideo"
            />
            <UButton
              v-else
              :disabled="!selectedBackgroundFile || isCombinatorLoading"
              :loading="isCombinatorLoading"
              color="primary"
              icon="i-tabler-wand"
              :label="isCombinatorLoading ? '合成中' : '开始合成'"
              @click="composeBackgroundVideo"
            />
          </div>
        </template>
      </UCard>
    </UModal>
  </div>
</template>

<style scoped></style>
