<template>
  <div class="min-h-screen relative">
    <el-form :model="form" :rules="rules" ref="formRef" label-position="top">
      <div class="max-w-6xl mx-auto grid gap-6 relative">
        <!-- 左侧主要内容 -->
        <BackButton />

        <div class="col-span-8 space-y-6">
          <!-- 视频上传区域 -->
          <div
            class="bg-white rounded-lg shadow-lg border border-gray-100 p-8 hover:shadow-xl transition-shadow duration-300"
          >
            <div class="flex items-center justify-between mb-6">
              <h3 class="text-xl font-bold text-gray-800">上传视频</h3>
            </div>
            <el-form-item prop="videoUrl">
              <UploadVideo
                v-model="form.videoUrl"
                @uploadSuccess="handleVideoChange"
                ref="uploadVideoRef"
              />
            </el-form-item>
          </div>

          <!-- 基本设置 -->
          <div
            class="bg-white rounded-lg shadow-lg border border-gray-100 p-8 hover:shadow-xl transition-shadow duration-300"
          >
            <div class="flex items-center justify-between mb-6">
              <h3 class="text-xl font-bold text-gray-800">基本设置</h3>
            </div>

            <!-- 封面设置 -->
            <div class="mb-8">
              <el-form-item prop="faceUrl">
                <div class="">
                  <label class="block text-sm font-semibold text-gray-700 mb-3">封面选择</label>
                  <div class="flex gap-6">
                    <!-- 主封面预览 -->
                    <div class="relative group">
                      <div
                        class="w-48 h-28 bg-gradient-to-br from-gray-100 to-gray-200 rounded-lg shadow-md hover:shadow-lg transition-shadow duration-300 cursor-pointer overflow-hidden"
                        @click="handleOpenCoverDialog"
                      >
                        <img
                          v-if="form.faceUrl"
                          :src="form.faceUrl"
                          alt="视频封面"
                          class="w-full h-full object-cover"
                        />
                        <div
                          v-else
                          class="w-full h-full flex items-center justify-center text-gray-400"
                        >
                          <el-icon :size="32">
                            <IEpPicture />
                          </el-icon>
                        </div>
                        <div
                          class="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center shadow-lg"
                        >
                          <span class="text-white text-sm font-medium">点击选择封面</span>
                        </div>
                        <div
                          v-if="form.faceUrl"
                          class="absolute bottom-2 left-2 bg-gradient-to-r from-indigo-500 to-purple-600 text-white text-xs px-2 py-1 rounded-md font-medium"
                        >
                          当前封面
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </el-form-item>
            </div>

            <!-- 标题 -->
            <div class="mb-8">
              <el-form-item prop="title">
                <label class="block text-sm font-semibold text-gray-700 mb-3">视频标题</label>
                <el-input
                  v-model="form.title"
                  placeholder="请输入视频标题..."
                  maxlength="80"
                  show-word-limit
                  class="title-input"
                />
              </el-form-item>
            </div>

            <div class="mb-8">
              <el-form-item prop="content">
                <label class="block text-sm font-semibold text-gray-700 mb-3">视频简介</label>
                <el-input
                  v-model="form.content"
                  type="textarea"
                  :rows="5"
                  placeholder="请写上您希望介绍的内容，让更多的人了解您的作品吧！"
                />
              </el-form-item>
            </div>

            <template v-if="showSpecialInput">
              <div class="mb-8">
                <el-form-item prop="mainTagId">
                  <label class="block text-sm font-semibold text-gray-700 mb-3">
                    主标签
                    <el-tooltip content="主标签最多添加一个" placement="top">
                      <el-icon class="text-gray-400 cursor-help">
                        <IEpQuestionFilled />
                      </el-icon>
                    </el-tooltip>
                  </label>
                  <SelectTags class="w-full" v-model="form.mainTagId" :max-selected-tags="1" />
                </el-form-item>
              </div>

              <div class="mb-8">
                <el-form-item prop="tagList">
                  <label class="block text-sm font-semibold text-gray-700 mb-3">
                    副标签
                    <el-tooltip content="副标签最多添加3个" placement="top">
                      <el-icon class="text-gray-400 cursor-help">
                        <IEpQuestionFilled />
                      </el-icon>
                    </el-tooltip>
                  </label>
                  <SelectTags
                    class="w-full"
                    v-model="form.tagList"
                    :max-selected-tags="3"
                    :filter-tags-fn="filterTagsFn"
                  />
                </el-form-item>
              </div>

              <!-- 新增推送设置 -->
              <template v-if="userInfo.isOfficialAccount">
                <div class="mb-8">
                  <el-form-item>
                    <label class="block text-sm font-semibold text-gray-700 mb-3"> 推送对象 </label>
                    <div class="w-full">
                      <el-button
                        class="button-new-tag"
                        size="small"
                        @click="handleSelectUserAndDept"
                      >
                        + 添加部门
                      </el-button>
                      <span class="ml-2 text-sm text-gray-600">
                        {{ selectedText }}已选择下属部门</span
                      >
                    </div>
                  </el-form-item>
                </div>
                <div class="mb-8">
                  <el-form-item prop="pushType">
                    <label class="block text-sm font-semibold text-gray-700 mb-3"> 推送类型 </label>
                    <div class="w-full">
                      <el-radio-group v-model="form.pushType">
                        <el-radio :value="SendTypeEnum.IMMEDIATE">立即推送</el-radio>
                        <el-radio :value="SendTypeEnum.SCHEDULED">定时推送</el-radio>
                      </el-radio-group>
                    </div>
                  </el-form-item>
                </div>
                <div class="mb-8">
                  <el-form-item v-if="form.pushType === SendTypeEnum.SCHEDULED" prop="pushTime">
                    <label class="block text-sm font-semibold text-gray-700 mb-3"> 推送时间 </label>
                    <div class="w-full">
                      <el-date-picker
                        v-model="form.pushTime"
                        type="datetime"
                        placeholder="请选择推送时间"
                        value-format="X"
                        :disabled-date="
                          (time: Date) => {
                            return time.getTime() < Date.now() - 1000 * 60 * 60 * 24
                          }
                        "
                      />
                    </div>
                  </el-form-item>
                </div>
              </template>
              <div class="mb-8">
                <el-form-item prop="relateColumnId">
                  <label class="block text-sm font-semibold text-gray-700 mb-3">
                    视频栏目选择
                  </label>
                  <el-select v-model="form.relateColumnId" placeholder="请选择视频栏目">
                    <el-option
                      v-for="item in videoList"
                      :key="item.id"
                      :label="item.title"
                      :value="item.id"
                    />
                  </el-select>
                </el-form-item>
              </div>
            </template>
          </div>

          <div
            class="bg-white rounded-lg shadow-lg border border-gray-100 p-6 hover:shadow-xl transition-shadow duration-300"
          >
            <h4 class="text-lg font-bold text-gray-800 mb-4">发布设置</h4>

            <div class="space-y-4">
              <div class="flex items-center justify-between p-3 rounded-lg">
                <div>
                  <div class="text-sm font-medium text-gray-800">定时发布</div>
                  <div class="text-xs text-gray-500">设置发布时间</div>
                </div>
                <div>
                  <el-date-picker
                    v-if="form.sendType === SendTypeEnum.SCHEDULED"
                    v-model="form.sendTime"
                    type="datetime"
                    placeholder="选择发布时间"
                    size="small"
                    value-format="X"
                    :disabled-date="
                      (time: Date) => {
                        return time.getTime() < Date.now() - 1000 * 60 * 60 * 24
                      }
                    "
                    style="width: 250px"
                  />
                  <el-switch
                    v-model="form.sendType"
                    :active-value="SendTypeEnum.SCHEDULED"
                    :inactive-value="SendTypeEnum.IMMEDIATE"
                  />
                </div>
              </div>
            </div>
          </div>

          <div class="bg-white rounded-lg shadow-lg border border-gray-100 p-6">
            <div class="space-y-3 flex justify-center items-center gap-4">
              <el-button
                @click="handleSubmit(ReleaseStatusTypeEnum.DRAFT)"
                size="large"
                class="w-full !border-gray-200 hover:!border-indigo-300 hover:!text-indigo-600 transition-colors duration-200"
              >
                <el-icon class="mr-2">
                  <IEpDocument />
                </el-icon>
                保存草稿
              </el-button>
              <el-button
                type="primary"
                size="large"
                class="w-full !bg-gradient-to-r !from-indigo-500 !to-purple-600 !border-none shadow-lg hover:shadow-xl transition-shadow duration-300"
                @click="handleSubmit(ReleaseStatusTypeEnum.PUBLISH)"
              >
                <el-icon class="mr-2">
                  <IEpUpload />
                </el-icon>
                立即发布
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </el-form>

    <!-- 封面选择弹窗 -->
    <el-dialog
      v-model="showCoverDialog"
      title="选择视频封面"
      width="800px"
      :close-on-click-modal="false"
    >
      <!-- 这个用blob是因为 转为canvas 防止跨域污染 -->
      <div v-if="locationVideoBlolUrl" class="space-y-6">
        <!-- 视频预览 -->
        <div class="relative">
          <video
            ref="videoRef"
            :src="locationVideoBlolUrl"
            class="w-full max-h-96 rounded-lg bg-black"
            @loadedmetadata="onVideoLoaded"
            @timeupdate="onTimeUpdate"
          />
          <div class="absolute bottom-4 left-4 right-4 bg-black/60 rounded-lg p-3">
            <div class="text-white text-sm mb-2">
              当前时间：{{ formatTime(currentTime) }} / {{ formatTime(videoDuration) }}
            </div>
            <el-slider
              v-model="currentTime"
              :max="videoDuration"
              :step="0.1"
              @input="(time) => seekVideo(time as number)"
              class="custom-slider"
            />
          </div>
        </div>
        <div class="flex justify-end items-center gap-2">
          <p class="text-sm text-gray-500">拖动进度条找到合适的画面，点击截取按钮生成封面</p>
          <el-button type="primary" @click="captureFrame">
            <el-icon class="mr-2"> <IEpCamera /> </el-icon>截取当前帧
          </el-button>
          or
          <el-button type="primary" @click="coverInputRef?.click()">
            手动上传封面
            <input
              ref="coverInputRef"
              class="hidden"
              type="file"
              accept="image/*"
              @change="handleFileChange"
            />
          </el-button>
        </div>

        <!-- 封面预览 -->
        <div class="bg-gray-50 rounded-lg p-4">
          <div class="text-sm font-semibold text-gray-700 mb-3">封面预览</div>
          <div class="flex items-center gap-6">
            <div class="relative w-60 h-34 bg-gray-200 rounded-lg overflow-hidden">
              <img v-if="form.faceUrl" :src="form.faceUrl" class="w-full h-full object-cover" />
              <div v-else class="w-full h-full flex items-center justify-center text-gray-400">
                <el-icon :size="40">
                  <IEpPicture />
                </el-icon>
              </div>
              <canvas ref="canvasRef" class="hidden" />
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="flex justify-end gap-3">
          <el-button @click="showCoverDialog = false">取消</el-button>
          <el-button type="primary" @click="confirmCover" :disabled="!form.faceUrl">
            确认使用
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import UploadVideo from '@/components/common/UploadVideo/index.vue'
import { useResetData } from '@/hooks'
import { ArticleTypeEnum, ReleaseStatusTypeEnum, SendTypeEnum } from '@/constants'
import { addOrUpdateArticle, uploadFile, getArticleDetail } from '@/api'
import SelectTags from '@/components/common/SelectTags/index.vue'
import type { TagItemDto, AddOrUpdateVideoDto } from '@/api'
import { useVideoStore, useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
import { selectDepOrUser, fetchOssBlob } from '@/utils'
import BackButton from '@/components/common/BackButton/index.vue'
import { push } from 'notivue'

const route = useRoute()
const videoStore = useVideoStore()
const { videoList } = storeToRefs(videoStore)

const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const showSpecialInput = computed(
  () => userInfo.value?.isAdmin || userInfo.value?.isOfficialAccount,
)

const router = useRouter()
const formRef = useTemplateRef('formRef')
const coverInputRef = useTemplateRef('coverInputRef')
const uploadVideoRef = useTemplateRef('uploadVideoRef')
const [form, resetData] = useResetData({
  id: undefined as number | undefined,
  videoUrl: '',
  title: '',
  type: ArticleTypeEnum.VIDEO,
  content: '',
  mainTagId: '',
  tagList: [] as number[],
  sendType: SendTypeEnum.IMMEDIATE,
  sendTime: '',
  releaseStatus: ReleaseStatusTypeEnum.PUBLISH,
  faceUrl: '', // 封面URL
  videoDuration: '',
  relateColumnId: '' as string | number,

  // 推送设置
  pushType: SendTypeEnum.IMMEDIATE,
  pushTime: '',
  pushList: [] as { valueId: string; valueType: number; valueName: string }[],
})

const selectedDepts = ref<{ id: string; name: string }[]>([])
const selectedUsers = ref<{ id: string; name: string }[]>([])
const selectedText = computed(() => {
  let text = ''
  if (selectedDepts.value.length > 0) {
    text += `已选择${selectedDepts.value.length}个部门`
  }
  if (selectedUsers.value.length > 0) {
    text += `已选择${selectedUsers.value.length}个成员`
  }
  return text
})
const handleSelectUserAndDept = async () => {
  const { departmentList, userList } = await selectDepOrUser({
    mode: 'multi',
    type: ['user', 'department'],
    selectedDepartmentIds: selectedDepts.value.map((item) => item.id),
    selectedUserIds: selectedUsers.value.map((item) => item.id),
  })
  selectedDepts.value = departmentList.map((item) => ({
    id: item.id,
    name: item.name,
  }))
  selectedUsers.value = userList.map((item) => ({
    id: item.id,
    name: item.name,
  }))
}

// 封面选择相关

const locationVideoBlolUrl = ref('')

const showCoverDialog = ref(false)
const videoRef = ref<HTMLVideoElement>()
const canvasRef = ref<HTMLCanvasElement>()
const videoDuration = ref(0)
const currentTime = ref(0)

const handleOpenCoverDialog = () => {
  if (!locationVideoBlolUrl.value) return push.warning('请先上传视频')
  showCoverDialog.value = true
}
// 视频加载完成
const onVideoLoaded = () => {
  if (videoRef.value) {
    videoDuration.value = videoRef.value.duration
    currentTime.value = 1 // 默认第1秒
    seekVideo(1)
  }
}

// 视频时间更新
const onTimeUpdate = () => {
  if (videoRef.value) {
    currentTime.value = videoRef.value.currentTime
  }
}

// 跳转到指定时间
const seekVideo = (time: number) => {
  if (videoRef.value) {
    videoRef.value.currentTime = time
  }
}

// 截取当前帧
const captureFrame = () => {
  const video = videoRef.value
  const canvas = canvasRef.value

  if (!video || !canvas) return

  // 用canvas 绘制 视频当前帧的图片 然后上传
  canvas.width = video.videoWidth
  canvas.height = video.videoHeight

  // 绘制当前帧
  const ctx = canvas.getContext('2d')
  if (ctx) {
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
    // 转换为Blob
    canvas.toBlob(
      async (blob) => {
        if (blob) {
          // 直接在这里上传 不转为本地了
          const { promise } = uploadFile(new File([blob], `video${Date.now()}.jpg`))
          const data = await promise
          form.value.faceUrl = data.filePath
          push.success('封面截取成功')
        }
      },
      'image/jpeg',
      0.9,
    )
  }
}

// 确认使用封面
const confirmCover = async () => {
  if (!form.value.faceUrl) return

  showCoverDialog.value = false
  push.success('封面设置成功')
}

// 格式化时间
const formatTime = (seconds: number) => {
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

const filterTagsFn = (tags: TagItemDto[]) => {
  return tags.filter((tag) => tag.id !== Number(form.value.mainTagId))
}

const rules = {
  videoUrl: [{ required: true, message: '请上传视频', trigger: 'change' }],
  title: [{ required: true, message: '请输入视频标题', trigger: 'blur' }],
  content: [{ required: true, message: '请输入视频简介', trigger: 'blur' }],
  mainTagId: [{ required: true, message: '请选择主标签', trigger: 'change' }],
  faceUrl: [{ required: true, message: '请选择视频封面', trigger: 'change' }],
  relateColumnId: [{ required: true, message: '请选择视频栏目', trigger: 'change' }],

  // 推送设置
  pushType: [{ required: true, message: '请选择推送类型', trigger: 'trigger' }],
  pushTime: [{ required: true, message: '请选择推送时间', trigger: 'trigger' }],
  pushList: [{ required: true, message: '请选择推送对象', trigger: 'trigger' }],
}

const tansformData = (releaseStatus: ReleaseStatusTypeEnum): AddOrUpdateVideoDto => {
  const data = {
    ...form.value,
    tagList: [form.value.mainTagId, ...form.value.tagList].map((item, index) => ({
      tagId: Number(item),
      sort: index,
    })),
    mainTagId: Number(form.value.mainTagId),
    releaseStatus,
  }
  if (userInfo.value.isOfficialAccount) {
    data.pushList = [
      ...selectedDepts.value.map((item) => ({
        valueId: item.id,
        valueType: 1,
        valueName: item.name,
      })),
      ...selectedUsers.value.map((item) => ({
        valueId: item.id,
        valueType: 2,
        valueName: item.name,
      })),
    ]
  }
  return data as AddOrUpdateVideoDto
}

const loading = ref(false)
const resetPageData = () => {
  resetData()
  locationVideoBlolUrl.value = ''
}
const handleSubmit = async (releaseStatus: ReleaseStatusTypeEnum) => {
  await formRef.value?.validate()
  loading.value = true
  try {
    addOrUpdateArticle(tansformData(releaseStatus))
    push.success(releaseStatus === ReleaseStatusTypeEnum.PUBLISH ? '发布成功' : '存草稿成功')
    resetPageData()
    router.push('/')
    // 重置数据
  } catch (e) {
    console.log(e)
  } finally {
    loading.value = false
  }
}

const handleVideoChange = ({
  file,
  videoDuration,
}: {
  file: File
  url: string
  videoDuration: string
}) => {
  if (locationVideoBlolUrl.value) {
    URL.revokeObjectURL(locationVideoBlolUrl.value)
  }
  if (file) {
    locationVideoBlolUrl.value = URL.createObjectURL(file)
  }
  form.value.videoDuration = videoDuration
}

// 手动上传
const handleFileChange = async (e: Event) => {
  const target = e.target as HTMLInputElement
  const file = target.files?.[0]
  if (!file) return
  const { promise } = uploadFile(file)
  const data = await promise
  form.value.faceUrl = data.filePath
}
onDeactivated(() => {
  // 清空页面的数据
  resetPageData()
  uploadVideoRef.value?.reset()
})

// 处理编辑回显
onActivated(async () => {
  if (route.query.id) {
    const { data } = await getArticleDetail(route.query.id as string)
    const blobUrl = await fetchOssBlob(data.videoUrl)
    locationVideoBlolUrl.value = blobUrl
    form.value = {
      ...form.value,
      ...data,
      mainTagId: String(data.tagIdList?.[0]),
      tagList: data.tagIdList?.slice(1),
    }
    // 回显推送的部门 这个后端没有返回相关数据 需要返回
    console.log(data.pushList, 'data.pushList')
    selectedDepts.value =
      data.pushList
        ?.filter((item) => item.valueType === 1)
        .map((item) => ({
          id: item.valueId,
          name: item.valueName,
        })) || []
    selectedUsers.value =
      data.pushList
        ?.filter((item) => item.valueType === 2)
        .map((item) => ({
          id: item.valueId,
          name: item.valueName,
        })) || []
  }
})
</script>

<style scoped>
/* 自定义滑块样式 */
:deep(.custom-slider .el-slider__runway) {
  background-color: rgba(255, 255, 255, 0.3);
}

:deep(.custom-slider .el-slider__bar) {
  background-color: #6366f1;
}

:deep(.custom-slider .el-slider__button) {
  border-color: #6366f1;
}
</style>
