<template>
  <div style="display: block; width: 1000px">
    <div style="display: flex; margin-bottom: 10px">
      <el-row>
        <span style="margin-left: 10px" prop="channelName">通道：</span>
        <el-select
          v-model="channelId"
          placeholder="请选择"
          @change="changeChannel"
          style="width: 200px; margin-right: 10px"
          size="small"
        >
          <el-option
            v-for="option in channelList"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
        <span style="overflow: auto; margin-left: 10px">日期：</span>
        <el-date-picker
          v-model="queryDate"
          type="date"
          size="small"
          value-format="YYYY-MM-DD"
          clearable
          placeholder="选择日期"
          style="width: 180px; margin-right: 10px"
        />
        <el-button-group style="margin: 0">
          <el-button
            size="small"
            type="success"
            title="查看录像"
            @click="loadDevRecord()"
            :disabled="channelId === '' || !queryDate"
          >
            <el-icon><VideoCamera /></el-icon>
            <span class="pl-1">查看</span>
          </el-button>
        </el-button-group>

        <span style="margin-left: 82px; overflow: auto">时间：</span>
        <el-button-group>
          <el-time-picker
            size="small"
            is-range
            align="left"
            v-model="timeRange"
            value-format="YYYY-MM-DD HH:mm:ss"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            placeholder="选择时间范围"
            @change="timePickerChange"
            style="width: 200px"
            :disabled="channelId === '' || !queryDate"
          />
        </el-button-group>
        <el-button-group style="margin: 0 0 0 10px">
          <el-button
            size="small"
            type="primary"
            title="下载选定录像"
            @click="downloadRecord()"
            :disabled="channelId === '' || !timeRange"
          >
            <el-icon><Download /></el-icon>
            <span class="pl-1">转存</span>
          </el-button>
        </el-button-group>
      </el-row>
    </div>
    <player ref="playbacker" :playerinfo="playinfo" class="components-container" />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import { VideoCamera, Download } from '@element-plus/icons-vue'
import player from '@/views/pms/video_center/sip/components/player/player.vue'
import { listChannel, playbackvideo, closeStream, playbackSeek } from '@/api/pms/video/channel'
import { getDevRecord, startDownloadRecord } from '@/api/pms/video/record'

// 定义props
interface Device {
  deviceId: number
  serialNumber: string
  [key: string]: any
}

const props = defineProps<{
  device: Device
}>()

// 响应式数据
const deviceId = ref('')
const channelId = ref('')
const streamId = ref('')
const ssrc = ref('')
const playurl = ref('')
const queryDate = ref('')
const playing = ref(false)
const vodData = ref({})
const hisData = ref([])
const playinfo = ref({
  playtype: 'playback',
  deviceId: '',
  channelId: ''
})
const channelList = ref<{ value: string; label: string }[]>([])
const playbackinfo = ref({})
const timeRange = ref<[string, string] | null>(null)
const startTime = ref<string | null>(null)
const endTime = ref<string | null>(null)

// 查询参数
const queryParams = ref({
  pageNo: 1,
  pageSize: 10,
  deviceSipId: null as string | null,
  channelSipId: null as string | null
})

const deviceInfo = ref<Device | null>(null)
const playbacker = ref()

// 监听设备变化
watch(
  () => props.device,
  (newVal) => {
    deviceInfo.value = newVal
    if (deviceInfo.value && deviceInfo.value.deviceId !== 0) {
      queryParams.value.deviceSipId = deviceInfo.value.serialNumber
      deviceId.value = deviceInfo.value.serialNumber
    }
  },
  { immediate: true }
)

// 初始化
const init = () => {
  queryParams.value.deviceSipId = props.device.serialNumber
  deviceId.value = props.device.serialNumber
  getList()
  playinfo.value = {
    playtype: 'playback',
    deviceId: props.device.serialNumber,
    channelId: ''
  }
}

// 组件挂载时执行初始化
init()

// 查询监控设备通道信息列表
async function getList() {
  try {
    const response = await listChannel(queryParams.value)
    channelList.value = response.list.map((item: any) => {
      return { value: item.channelSipId, label: item.channelName }
    })
  } catch (error) {
    console.error('获取通道列表失败:', error)
  }
}

// 改变通道
const changeChannel = () => {
  playinfo.value.channelId = channelId.value
}

// 初始化URL
const initUrl = (data: any) => {
  if (data) {
    streamId.value = data.ssrc
    ssrc.value = data.ssrc
    playurl.value = data.playurl
  } else {
    streamId.value = ''
    ssrc.value = ''
    playurl.value = ''
  }
}

// 获取北京时间
const getBeijingTime = (queryDate: string) => {
  // 计算与UTC的时区差，对于北京时间来说是8小时
  let offset = 8 * 60 * 60 * 1000
  // 加上时区差，得到北京时间
  let beijingTime = new Date(new Date(queryDate).getTime() - offset)
  return beijingTime.getTime()
}

// 录像控制
const loadDevRecord = async () => {
  playbacker.value.registercallback('playbackSeek', seekPlay)
  if (queryDate.value === '' || queryDate.value === null) {
    ElMessage.error('请选择日期')
    return
  }
  if (deviceId.value && channelId.value) {
    const date = getBeijingTime(queryDate.value)
    const start = Math.floor(date / 1000)
    const end = Math.floor((date + 24 * 60 * 60 * 1000 - 1) / 1000)
    const query = {
      start: start,
      end: end
    }
    vodData.value = {
      start: start,
      end: end,
      base: start
    }
    setTime(queryDate.value + ' 00:00:00', queryDate.value + ' 23:59:59')

    try {
      const res = await getDevRecord(deviceId.value, channelId.value, query)
      console.log('res :>> ', res)
      hisData.value = res.recordItems
      if (res.recordItems) {
        const len = hisData.value.length
        if (len > 0) {
          if (hisData.value[0].start < start) {
            hisData.value[0].start = start
            vodData.value.start = start
          } else {
            vodData.value.start = hisData.value[0].start
          }
          if (hisData.value[0].end !== 0 && hisData.value[0].end < end) {
            vodData.value.end = hisData.value[0].end
          }
          playback()
        } else {
          ElMessage({
            type: 'warning',
            message: '请确认设备是否支持录像，或者设备SD卡是否正确插入！'
          })
        }
      } else {
        ElMessage({
          type: 'warning',
          message: '请确认设备是否支持录像，或者设备SD卡是否正确插入！'
        })
      }
    } catch (error) {
      console.error('获取录像记录失败:', error)
    }
  }
}

// 录像播放
const playback = async () => {
  const query = {
    start: (vodData.value as any).start,
    end: (vodData.value as any).end
  }

  try {
    if (ssrc.value) {
      await closeStream(deviceId.value, channelId.value, ssrc.value)
      const res = await playbackvideo(deviceId.value, channelId.value, query)

      console.log('res :>>>>>>>>>>>>>>>> ', res)
      initUrl(res)
    } else {
      const res = await playbackvideo(deviceId.value, channelId.value, query)
      console.log('***********************', res)
      initUrl(res)
    }
    triggerPlay(hisData.value)
  } catch (error) {
    console.error('播放录像失败:', error)
  }
}

// 触发播放
const triggerPlay = (playTimes: any) => {
  playbacker.value.playback(playurl.value, playTimes)
  playing.value = true
}

// 录像播放
const seekPlay = (s: any) => {
  const curTime = (vodData.value as any).base + s.hour * 3600 + s.min * 60 + s.second
  const seekRange = curTime - (vodData.value as any).start
  if (ssrc.value) {
    const query = {
      seek: seekRange
    }
    playbackSeek(deviceId.value, channelId.value, streamId.value, query).then((res) => {
      playbacker.value.setPlaybackStartTime(curTime)
    })
  }
}

// 关闭播放流
const closeStreamFunc = async () => {
  if (playing.value && streamId.value) {
    try {
      await closeStream(deviceId.value, channelId.value, streamId.value)
      streamId.value = ''
      ssrc.value = ''
      playurl.value = ''
      playing.value = false
    } catch (error) {
      console.error('关闭流失败:', error)
    }
  }
}

// 销毁录像播放器
const destroy = () => {
  if (playing.value && streamId.value) {
    playbacker.value.destroy()
  }
}

// 关闭并销毁
const closeDestroy = () => {
  closeStreamFunc()
  destroy()
}

// 设置时间
const timePickerChange = (val: [string, string] | null) => {
  if (val) {
    setTime(val[0], val[1])
  }
}

const setTime = (startTimeVal: string, endTimeVal: string) => {
  startTime.value = startTimeVal
  endTime.value = endTimeVal
  timeRange.value = [startTimeVal, endTimeVal]
}

// 下载录像
const downloadRecord = async () => {
  if (!startTime.value || !endTime.value) {
    ElMessage.error('请选择时间范围')
    return
  }

  const start = Math.floor(new Date(startTime.value).getTime() / 1000)
  const end = Math.floor(new Date(endTime.value).getTime() / 1000)
  const query = {
    startTime: start,
    endTime: end,
    speed: '4'
  }

  try {
    const res = await startDownloadRecord(deviceId.value, channelId.value, query)
    console.log('开始转存到流服务器：' + deviceId.value + ' : ' + channelId.value)
    if (res.code === 200) {
      ElMessage({
        type: 'success',
        message: '转存到流服务器,请前往视频中心->录像管理查看！'
      })
    }
  } catch (error) {
    console.error('开始下载录像失败:', error)
  }
}

// 组件卸载前执行
onBeforeUnmount(() => {
  closeStreamFunc()
})

defineExpose({
  loadDevRecord,
  closeStreamFunc,
  closeDestroy,
  timePickerChange,
  downloadRecord,
  destroy,
  queryDate
})
</script>
