<template>
  <div class="nvr-camera-view">
    <div class="nvr-tips">
      <el-icon size="18" color="#409eff" style="margin: 11px 8px 11px 16px"><InfoFilled /></el-icon>
      默认播放当前实时视频画面，可选择具体日期和时间进行回看，最长支持90天内视频内容回看</div
    >
    <div class="nvr-date-picker">
      <el-date-picker
        v-model="dateRange"
        type="datetimerange"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
        range-separator="至"
        format="YYYY-MM-DD HH:mm:ss"
        :prefix-icon="Calendar"
        :disabled-date="disableDate"
        :clearable="false"
        @change="judgeDate"
      />
      <el-button style="margin-left: 10px" type="primary" @click="handleNvrUrl(null)"
        >查看回放</el-button
      >
    </div>
    <div style="width: 960px; height: 540px">
      <LiveVideo v-if="videoUrl" :url="videoUrl" @time-update="handleTimeUpdate" />
    </div>
    <div class="nvr-slider" v-if="confirmDate">
      <NvrSlider
        ref="nvrSliderRef"
        :start-time="dateRange[0]"
        :end-time="dateRange[1]"
        :start-position="100"
        :violations="violationsList"
        @update-nvr="handleNvrUrl"
      />
    </div>
    <div class="nvr-setting-bar">
      <NvrVioCheckbox :available="confirmDate" :camera-id="cameraId" @check-tags="handleVioTags" />
      <NvrTimeSelect
        ref="nvrTimeSelectRef"
        @set-Time="handleSetTime"
        @download-nvr="handleDownloadNvr"
      />
    </div>
    <a ref="downloadRef" style="display: none" :href="downloadUrl" download />
  </div>
</template>

<script setup lang="ts">
  import NvrVioCheckbox from './NvrCheckbox.vue';
  import NvrTimeSelect from './NvrTimeSelect.vue';
  import NvrSlider from './NvrSlider.vue';
  // import CameraLiveVideo from '@/views/cameras/preview/components/CameraLiveVideo/CameraLiveVideo.vue';
  import { ref } from 'vue';
  import LiveVideo from '@/components/LiveVideo/LiveVideo.vue';
  import useCameraDetailStore from '@/views/cameras/preview/store/useCameraDetailStore';
  import { dayjs, ElMessage } from 'element-plus';
  import { computed } from 'vue';
  import { InfoFilled, Calendar } from '@element-plus/icons-vue';
  import {
    getReplayNvr,
    GetReplayNvrBody,
    getRecordByTime,
    GetRecordByTimeBody,
    ViolationRecordItem,
    getNvrDownloadUrl,
  } from '@/api/datamanagement/playback';
  import useCameraAlgoStore from '@/views/cameras/preview/store/useCameraAlgoStore';

  const cameraAlgoStore = useCameraAlgoStore();
  defineProps<{ cameraId: number }>();
  const cameraDetailStore = useCameraDetailStore();

  // 日期范围
  const dateRange = ref();
  // 确认查看回放
  const confirmDate = ref(false);
  // 回放nvr地址
  const nvrUrl = ref();
  // 违例点列表
  const violationsList = ref<ViolationRecordItem[]>([]);
  // nvr滑动组件引用
  const nvrSliderRef = ref();
  // nvr下载组件引用
  const nvrTimeSelectRef = ref();
  // 下载
  const downloadRef = ref();
  const downloadUrl = ref();

  const judgeDate = (date: Date[]) => {
    confirmDate.value = false;
    nvrUrl.value = undefined;
    cameraAlgoStore.selectedAlgoList = [];

    if (date && date.length === 2) {
      const startTime = new Date(date[0]);
      const endTime = new Date(date[1]);
      if ((endTime.getTime() - startTime.getTime()) / (1000 * 60) < 1) {
        ElMessage({
          message: `选择回放时间范围需大于1分钟`,
          type: 'error',
        });
        dateRange.value = undefined;
        return;
      }
      if (endTime > new Date()) {
        ElMessage({
          message: `结束时间不能在当前时间之后`,
          type: 'error',
        });
        dateRange.value = undefined;
        return;
      }
    }
  };

  // 播放时间变化前秒数
  const secondMargin = ref<number>();
  const handleNvrUrl = (nowTime?: Date | null) => {
    if (!dateRange.value) {
      return;
    }
    if (cameraDetailStore.detail?.pushstreamIp) {
      cameraDetailStore.clear();
    }
    const nvrParams: GetReplayNvrBody = {
      cameraId: cameraDetailStore.cameraId,
      startTime: dayjs(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss'),
      endTime: dayjs(dateRange.value[1]).format('YYYY-MM-DD HH:mm:ss'),
    };
    secondMargin.value = dateRange.value[0].getSeconds();
    confirmDate.value = true;
    if (nowTime) {
      const nowTimeMin = new Date(nowTime.setSeconds(0));
      if (nowTimeMin < dateRange.value[0]) {
        nvrParams.startTime = dayjs(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss');
        // secondMargin.value = dateRange.value[0].getSeconds();
      } else {
        nvrParams.startTime = dayjs(nowTimeMin).format('YYYY-MM-DD HH:mm:ss');
        secondMargin.value = nowTimeMin.getSeconds();
      }
    }
    getReplayNvr(nvrParams).then((res) => {
      min = 0;
      nvrUrl.value = res.data;
    });
  };

  const clearNvrUrl = () => {
    nvrUrl.value = undefined;
    confirmDate.value = false;
    dateRange.value = undefined;
    nvrTimeSelectRef.value.clearTime();
  };

  const handleVioTags = (tags: string[]) => {
    if (tags.length === 0) {
      violationsList.value = [];
      return;
    }
    const violationsParams: GetRecordByTimeBody = {
      algoList: tags.map((tag) => Number(tag)),
      cameraId: cameraDetailStore.cameraId,
      startTime: dayjs(dateRange.value[0]).format('YYYY-MM-DD HH:mm:ss'),
      endTime: dayjs(dateRange.value[1]).format('YYYY-MM-DD HH:mm:ss'),
    };
    getRecordByTime(violationsParams).then((res) => {
      violationsList.value = res;
    });
  };

  const handleSetTime = (isStart: boolean) => {
    if (!confirmDate.value) {
      return;
    }
    const nowTimeMin = new Date(nvrSliderRef.value.onTime.setSeconds(0));
    if (isStart) {
      const end = nvrTimeSelectRef.value.endTime;
      if (end.length > 0 && new Date(end) <= nowTimeMin) {
        ElMessage({
          message: `结束时间不早于开始时间`,
          type: 'error',
        });
        return;
      }
      nvrTimeSelectRef.value.startTime = dayjs(
        nowTimeMin < dateRange.value[0] ? dateRange.value[0] : nowTimeMin,
      ).format('YYYY-MM-DD HH:mm:ss');
    } else {
      const start = nvrTimeSelectRef.value.startTime;
      if (start.length > 0 && new Date(start) >= nowTimeMin) {
        ElMessage({
          message: `开始时间不晚于结束时间`,
          type: 'error',
        });
        return;
      }
      nvrTimeSelectRef.value.endTime = dayjs(
        new Date(nowTimeMin.setMinutes(nowTimeMin.getMinutes() + 1)) > dateRange.value[1]
          ? dateRange.value[1]
          : nowTimeMin.setMinutes(nowTimeMin.getMinutes() - 1),
      ).format('YYYY-MM-DD HH:mm:ss');
    }
  };

  let min = 0;
  const handleTimeUpdate = (playSeconds: number) => {
    if (secondMargin.value !== undefined) {
      const currentTime = Math.floor(playSeconds) + secondMargin.value;
      if (currentTime > min && currentTime % 60 === 0) {
        min = currentTime;
        nvrSliderRef.value.pushTime();
      }
    }
  };

  const handleDownloadNvr = () => {
    if (
      !confirmDate.value ||
      nvrTimeSelectRef.value.startTime.length === 0 ||
      nvrTimeSelectRef.value.endTime.length === 0
    ) {
      return;
    }
    const nvrParams: GetReplayNvrBody = {
      cameraId: cameraDetailStore.cameraId,
      startTime: dayjs(nvrTimeSelectRef.value.startTime).format('YYYY-MM-DD HH:mm:ss'),
      endTime: dayjs(nvrTimeSelectRef.value.endTime).format('YYYY-MM-DD HH:mm:ss'),
    };
    getNvrDownloadUrl(nvrParams).then((res) => {
      downloadUrl.value = res;
      downloadRef.value.click();
    });
  };

  const disableDate = (time: Date) => {
    const now = new Date();
    return time > now || time < new Date(now.setDate(now.getDate() - 90));
  };

  const videoUrl = computed(() => {
    return nvrUrl.value
      ? nvrUrl.value
      : cameraDetailStore.detail?.pushstreamIp
      ? cameraDetailStore.detail?.pushstreamIp
      : '';
  });

  defineExpose({
    clearNvrUrl,
  });
</script>

<style scoped lang="scss">
  .nvr-tips {
    margin: 5px 0;
    width: 100%;
    height: 40px;
    background: #ecf5ff;
    border-radius: 2px;
    font-family: 'PingFangSC', 'PingFang SC';
    font-weight: 400;
    font-size: 13px;
    color: #606266;
    line-height: 40px;
    text-align: left;
    font-style: normal;
    text-transform: none;
    display: flex;
    align-items: center;
  }

  .nvr-date-picker {
    margin: 10px 0 10px 20px;
  }

  .nvr-slider {
    height: 80px;
    position: relative;
  }

  .nvr-setting-bar {
    display: flex;
    justify-content: center;
  }
</style>
