<template>
  <BasicDrawer v-bind="$attrs" @register="playbackDrawer" @close="onClose" destroyOnClose>
    <a-row type="flex">
      <a-col ref="colWidth" :xl="leftCol" :lg="leftCol" :md="leftCol">
        <div ref="videoWidth" style="width: 100%; height: calc(100vh - 280px); background: black">
          <div v-if="videoUrl === ''" style="height: 100%"></div>
          <Jessibuca ref="jessibuca" v-if="videoUrl" :src="videoUrl" fluent autoplay />
          <!-- 时间轴 -->
          <div style="width: 100%">
            <div ref="dateId" style="background-color: rgb(46, 49, 54)">
              <div
                style="
                  color: white;
                  background-color: rgb(66, 69, 74);
                  margin: auto;
                  text-align: center;
                  white-space: nowrap;
                  font-size: small;
                  width: 20%;
                  line-height: 26px;
                "
              >
                {{ currentTime }}
              </div>
            </div>
            <!--<div style="width: 1440px;">-->
            <canvas
              ref="canvas"
              width="1440"
              height="82"
              style="width: 100%; position: relative; cursor: pointer; border: 1px solid #2b2f33; background-color: rgb(36, 39, 43)"
              ondragstart="return false;"
            ></canvas>
          </div>
        </div>
      </a-col>
      <a-col :xl="rightCol" :lg="rightCol" :md="rightCol" style="padding-left: 15px">
        <a-date-picker v-model:value="datePickerValue" @change="datePickerChange" valueFormat="YYYY-MM-DD" style="width: 100%" />
        <BasicTable @register="recordTable">
          <template #action="{ record }">
            <TableAction :actions="getTableAction(record)" />
          </template>
        </BasicTable>
      </a-col>
    </a-row>
  </BasicDrawer>
</template>

<script lang="ts" setup>
  import { ref, nextTick, computed, onUnmounted } from 'vue';
  import { BasicTable, TableAction, BasicDrawer, useDrawerInner, useListPage, Jessibuca } from '@jdlinker/ui';
  import { dateUtil } from '@jdlinker/utils';
  import { playBackStart } from '../../realtimeMonitor/DeviceService';
  import { getRecordList, seekPlayback } from "../JgbDevice_api";
  import dayjs from 'dayjs';
  import { useMessage } from '@jdlinker/func';

  // Emits声明
  const emit = defineEmits(['register', 'success']);
  const loading = ref<boolean>(false);
  const jessibuca = ref(null);
  const videoUrl = ref('');
  const streamId = ref('');
  const startTime = ref('');
  const endTime = ref('');
  const leftCol = ref(16);
  const rightCol = ref(8);
  const datePickerValue = ref('');
  const recordList = ref([]);
  const { createMessage } = useMessage();
  const columns = [
    { title: '名称', dataIndex: 'name', key: 'name' },
    { title: '文件', dataIndex: 'filePath', key: 'filePath' },
    { title: '开始时间', dataIndex: 'startTime', key: 'startTime' },
    { title: '结束时间', dataIndex: 'endTime', key: 'endTime' }
  ];

  /*模拟数据*/
  let timecell = ref([
    {
      beginTime: new Date().getTime() - 3 * 3600 * 1000,
      endTime: new Date().getTime() - 3600 * 1000,
      style: {
        background: 'rgba(132, 244, 180, 0.498039)'
      }
    },
    {
      beginTime: new Date().getTime() - 6 * 3600 * 1000,
      endTime: new Date().getTime() - 4 * 3600 * 1000,
      style: {
        background: 'rgba(132, 244, 180, 0.498039)'
      }
    }
  ]);
  /*模拟数据 end*/

  //canvas相关
  const colWidth = ref();
  const videoWidth = ref();
  const canvas = ref<null | HTMLElement>(null);
  let ctx = ref();
  let canvansW = ref();
  let canvansH = ref();
  let dateId = ref();
  let tempW = ref();
  let minutes_per_step = ref([1, 2, 5, 10, 15, 20, 30, 60, 120, 180, 240, 360, 720, 1440]); // min/格
  let graduation_step = ref(40); //刻度间最小宽度，单位px
  let hours_per_ruler = ref(24); //时间轴显示24小时
  let start_timestamp = ref(new Date().getTime() - 12 * 60 * 60 * 1000);
  let distance_between_gtitle = ref(80);
  let zoom = ref(24);
  let g_isMousedown = ref(false); //拖动mousedown标记
  let g_isMousemove = ref(false); //拖动mousemove标记
  let g_mousedownCursor = ref(null); //拖动mousedown的位置
  let returnTime = ref(null); //mouseup返回时间
  let currentTime = ref(dateUtil(new Date()).format('YYYY-MM-DD HH:mm:ss'));
  let recordData = ref();
  let setTimeMoveInterval = ref<any>(null);

  const changeDate: any = computed({
    get() {
      return dateUtil(returnTime.value).format('YYYY-MM-DD HH:mm:ss');
    },
    set(newValue) {
      currentTime.value = newValue;
    }
  });

  //表单赋值
  const [playbackDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
    setDrawerProps({ title: '回放', isDetail: true, closable: false });
    await nextTick();
    tempW.value = dateId.value.offsetWidth;
    canvansW.value = canvas.value.width;
    canvansH.value = canvas.value.height;
    console.log(' 视频回放：data.record', data.record);
    ctx.value = canvas.value.getContext('2d');
    init(start_timestamp.value, timecell.value);
    recordData.value = data.record;
    // sendDevicePush(data.record);
  });

  //注册table数据
  const { tableContext } = useListPage({
    tableProps: {
      dataSource: recordList,
      columns,
      inset: true,
      useSearchForm: false,
      showTableSetting: false,
      maxHeight: 420,
      pagination: {
        showQuickJumper: false
      },
      actionColumn: {
        width: 100,
        fixed: 'right'
      }
    }
  });

  const [recordTable] = tableContext;

  function onClose() {
    datePickerValue.value = '';
    videoUrl.value = '';
    changeDate.value = dateUtil(new Date()).format('YYYY-MM-DD HH:mm:ss');
    set_time_to_middle(new Date(changeDate.value).getTime());
    recordList.value = [];
    clearInterval(setTimeMoveInterval.value);
  }

  /**
   * 初始化
   * @param {*} start_timestamp 最左侧时间
   * @param {*} timecell 录像段数组
   */
  function init(start_timestamp, timecell) {
    // drawCellBg();
    add_graduations(start_timestamp);
    // add_cells(timecell);
    drawLine(0, canvansH, canvansW, canvansH, 'rgb(151, 158, 167)', 1); //底线
    drawLine(canvansW.value / 2, 0, canvansW.value / 2, 80, 'rgb(64, 196, 255)', 2); //中间播放点时间线颜色
    add_events();
    let time = start_timestamp + (hours_per_ruler.value * 3600 * 1000) / 2;
    ctx.value.fillStyle = 'rgb(64, 196, 255)'; //中间刻度时间颜色
    ctx.value.fillText(changeTime(time), canvansW.value / 2 - 95, 60); //中间刻度线时间
  }

  //通知设备上传媒体流
  function sendDevicePush(itemData, startTime, endTime) {
    console.log('itemData', itemData);
    let deviceId = itemData.deviceId;
    let channelId = itemData.channelId;
    if (deviceId && channelId && deviceId !== '' && channelId !== '') {
      console.log('通知设备推流1：' + deviceId + ' : ' + channelId);
      playBackStart(deviceId, channelId, startTime, endTime)
        .then((res) => {
          console.log('success', res);
          if (res) {
            console.log(res.ws_flv);
            videoUrl.value = res.ws_flv;
            streamId.value = res.stream;
            clearInterval(setTimeMoveInterval.value);
            timeInterval(startTime);
          } else {
            console.log('error');
          }
        })
        .catch(function (e) {});
    }
  }

  function datePickerChange(date) {
    if (date && date !== '') {
      let startTime = date + ' 00:00:00';
      let endTime = date + ' 23:59:59';
      console.log(startTime, endTime);
      recordQuery(startTime, endTime);
    }
  }

  /**
   * 录像查询
   */
  function recordQuery(startTime, endTime) {
    try {
      loading.value = true;
      let params = {
        startTime: startTime,
        endTime: endTime
      };
      getRecordList(recordData.value.deviceId, recordData.value.channelId, params).then((res) => {
        console.log('recordQuery', res);
        if (Array.isArray(res.recordList) && res.recordList.length > 0) {
          recordList.value = res.recordList;
        }
      });
    } finally {
      loading.value = false;
    }
  }

  /**
   * 播放
   */
  function handlePlay(record: Recordable) {
    if (videoUrl.value && '' !== videoUrl.value) {
      videoUrl.value = '';
    }
    startTime.value = record.startTime;
    endTime.value = record.endTime;
    let itemData = {
      channelId: recordData.value.channelId,
      deviceId: recordData.value.deviceId
    };
    sendDevicePush(itemData, record.startTime, record.endTime);
  }

  /**
   * 计时器实现时间每秒递增
   */
  function timeInterval(startTime) {
    timeProgress(startTime, startTime);
    let i = 1;
    setTimeMoveInterval.value = setInterval(function () {
      let time = new Date(startTime).getTime() + i * 1000;
      timeProgress(dateUtil(time).format('YYYY-MM-DD HH:mm:ss'), time);
      i = i + 1;
    }, 1000);
  }

  function timeProgress(time1, time2) {
    changeDate.value = time1;
    set_time_to_middle(new Date(time2).getTime());
  }

  /**
   * 下载
   */
  function handleDownload(record: any) {}

  function pause(ifPause) {
    if (ifPause) {
      clearInterval(setTimeMoveInterval);
    }
  }

  /**
   * 操作栏
   */
  function getTableAction(record) {
    return [
      {
        icon: 'ant-design:play-circle-outlined',
        tooltip: '播放',
        onClick: handlePlay.bind(null, record)
      },
      {
        icon: 'ant-design:download-outlined',
        tooltip: '下载',
        onClick: handleDownload.bind(null, record)
      }
    ];
  }

  /**
   * 绘制添加刻度
   */
  function add_graduations(start_timestamp) {
    let px_per_min = canvansW.value / (hours_per_ruler.value * 60); // px/min
    let px_per_ms = canvansW.value / (hours_per_ruler.value * 60 * 60 * 1000); // px/ms
    let px_per_step = graduation_step.value; // px/格 默认最小值20px
    let min_per_step = px_per_step / px_per_min; // min/格
    for (let i = 0; i < minutes_per_step.value.length; i++) {
      if (min_per_step <= minutes_per_step[i]) {
        //让每格时间在minutes_per_step规定的范围内
        min_per_step = minutes_per_step[i];
        px_per_step = px_per_min * min_per_step;
        break;
      }
    }

    let medium_step = 30;
    for (let i = 0; i < minutes_per_step.value.length; i++) {
      if (distance_between_gtitle.value / px_per_min <= minutes_per_step[i]) {
        medium_step = minutes_per_step[i];
        break;
      }
    }

    let num_steps = canvansW.value / px_per_step; //总格数
    let graduation_left;
    let graduation_time;
    let caret_class;
    let lineH;
    let ms_offset = ms_to_next_step(start_timestamp, min_per_step * 60 * 1000); //开始的偏移时间 ms
    let px_offset = ms_offset * px_per_ms; //开始的偏移距离 px
    let ms_per_step = px_per_step / px_per_ms; // ms/step
    for (let i = 0; i < num_steps; i++) {
      graduation_left = px_offset + i * px_per_step; // 距离=开始的偏移距离+格数*px/格
      graduation_time = start_timestamp + ms_offset + i * ms_per_step; //时间=左侧开始时间+偏移时间+格数*ms/格
      let date = new Date(graduation_time);
      if (date.getUTCHours() === 0 && date.getUTCMinutes() === 0) {
        caret_class = 'big';
        lineH = 25;
        let big_date = graduation_title(date);
        ctx.value.fillText(big_date, graduation_left - 23, 30);
      } else if ((graduation_time / (60 * 1000)) % medium_step === 0) {
        caret_class = 'middle';
        lineH = 15;
        let middle_date = graduation_title(date);
        ctx.value.fillText(middle_date, graduation_left - 23, 30);
      } else {
        lineH = 10;
      }
      ctx.value.fillStyle = '#FFFFFF';
      ctx.value.font = '15px Verdana';
      drawLine(graduation_left, 0, graduation_left, lineH, '#FFFFFF', 1); //刻度尺竖线颜色
    }
  }

  /**
   * 绘制线
   * @param {*} beginX
   * @param {*} beginY
   * @param {*} endX
   * @param {*} endY
   * @param {*} color
   * @param {*} width
   */
  function drawLine(beginX, beginY, endX, endY, color, width) {
    ctx.value.beginPath();
    ctx.value.moveTo(beginX, beginY);
    ctx.value.lineTo(endX, endY);
    ctx.value.strokeStyle = color;
    ctx.value.lineWidth = width;
    ctx.value.stroke();
  }

  /**
   * 添加录像段
   * @param {*} cells 录像数组
   */
  function add_cells(cells) {
    cells.forEach((cell) => {
      draw_cell(cell);
    });
  }

  /**
   * 绘制录像块
   * @param {*} cell cell包括beginTime ms;endTime ms;style
   */
  function draw_cell(cell) {
    let px_per_ms = canvansW.value / (hours_per_ruler.value * 60 * 60 * 1000); // px/ms
    let beginX = (cell.beginTime - start_timestamp.value) * px_per_ms;
    let cell_width = (cell.beginTime - cell.endTime) * px_per_ms;
    ctx.value.fillStyle = cell.style.background;
    ctx.value.fillRect(beginX, 0, cell_width, 15);
  }

  /**
   * 绘制录像块背景
   */
  function drawCellBg() {
    ctx.value.fillStyle = 'rgba(69, 72, 76, 0.5)';
    ctx.value.fillRect(0, 0, canvansW, 15);
  }

  /**
   * 时间轴事件
   */
  function add_events() {
    canvas.value.removeEventListener('mousewheel', mousewheelFunc);
    canvas.value.removeEventListener('mousedown', mousedownFunc);
    canvas.value.removeEventListener('mousemove', mousemoveFunc);
    canvas.value.removeEventListener('mouseup', mouseupFunc);
    canvas.value.removeEventListener('mouseout', mouseoutFunc);

    canvas.value.addEventListener('mousewheel', mousewheelFunc, { passive: false });
    canvas.value.addEventListener('mousedown', mousedownFunc, { passive: false });
    canvas.value.addEventListener('mousemove', mousemoveFunc, { passive: false });
    canvas.value.addEventListener('mouseup', mouseupFunc, { passive: false });
    canvas.value.addEventListener('mouseout', mouseoutFunc, { passive: false });
  }

  /**
   * 拖动/点击 mousedown事件
   */
  function mousedownFunc(e) {
    g_isMousedown.value = true;
    g_mousedownCursor.value = get_cursor_x_position(e); //记住mousedown的位置
  }

  /**
   * 拖动/鼠标hover显示 mousemove事件
   */
  function mousemoveFunc(e) {
    tempW.value = dateId.value.offsetWidth;
    let pos_x = get_cursor_x_position(e);
    let px_per_ms = canvansW.value / (hours_per_ruler.value * 60 * 60 * 1000); // px/ms
    clearCanvas();
    if (g_isMousedown.value) {
      let diff_x = pos_x - g_mousedownCursor.value;
      start_timestamp.value = start_timestamp.value - Math.round(diff_x / px_per_ms);
      init(start_timestamp.value, timecell.value);
      g_isMousemove.value = true;
      g_mousedownCursor.value = pos_x;
      ctx.value.fillStyle = '#FFFFFF';
    } else {
      let time = start_timestamp.value + pos_x / px_per_ms;
      init(start_timestamp.value, timecell.value);
      drawLine(pos_x, 0, pos_x, 80, '#FFFFFF', 1); //拖动鼠标时竖线颜色
      ctx.value.fillStyle = '#FFFFFF'; //拖动鼠标时时间显示颜色
      ctx.value.fillText(changeTime(time), pos_x - 95, 45);
    }
  }

  /**
   * 拖动/点击 mouseup事件
   */
  function mouseupFunc(e) {
    if (g_isMousemove.value) {
      //拖动 事件
      g_isMousemove.value = false;
      g_isMousedown.value = false;
      returnTime.value = start_timestamp.value + (hours_per_ruler.value * 3600 * 1000) / 2;
      seekPlay();
    } else {
      // click 事件
      g_isMousedown.value = false;
      let posx = get_cursor_x_position(e); //鼠标距离 px
      let ms_per_px = (zoom.value * 3600 * 1000) / canvansW.value; // ms/px
      returnTime.value = start_timestamp.value + posx * ms_per_px;
      seekPlay();
    }
  }

  function seekPlay() {
    //判断是否存在流
    if (streamId.value && streamId.value !== '') {
      if (ifTimePeriod(returnTime.value, startTime.value, endTime.value)) {
        clearInterval(setTimeMoveInterval.value);
        //拖动偏移量 /s
        let seekTime = dayjs(returnTime.value).diff(currentTime.value, 'second');
        console.log('拖动前时间', currentTime.value);
        console.log('拖动后时间', dateUtil(returnTime.value).format('YYYY-MM-DD HH:mm:ss'));
        console.log('拖动偏移量', seekTime + 's');
        seekPlayback(streamId.value, seekTime);
        timeInterval(dateUtil(returnTime.value).format('YYYY-MM-DD HH:mm:ss'));
      } else {
        clearInterval(setTimeMoveInterval.value);
        set_time_to_middle(new Date(currentTime.value).getTime());
        createMessage.warning('暂无录像');
      }
    } else {
      currentTime.value = dateUtil(returnTime.value).format('YYYY-MM-DD HH:mm:ss');
      set_time_to_middle(returnTime.value);
    }
  }

  /**
   * 判断当前选中时间是否在某个时间段内
   * @param nowTime 当前选中时间
   * @param startTime 时间段开始时间
   * @param endTime 时间段结束时间
   */
  function ifTimePeriod(nowTime, startTime, endTime) {
    var now = new Date(nowTime);
    var start = new Date(startTime);
    var end = new Date(endTime);
    var a = now.getTime() - start.getTime();
    var b = now.getTime() - end.getTime();
    if (a < 0 || b > 0) {
      return false;
    } else {
      return true;
    }
  }

  /**
   * 鼠标移出隐藏时间 mouseout事件
   * @param {*} e
   */
  function mouseoutFunc(e) {
    clearCanvas();
    init(start_timestamp.value, timecell.value);
  }

  /**
   * 滚轮放大缩小，以时间轴中心为准 mousewheel事件
   */
  function mousewheelFunc() {
    if (event && event.preventDefault) {
      event.preventDefault();
    } else {
      window.event.returnValue = false;
      return false;
    }

    let e = window.event || event;
    let delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
    let middle_time = start_timestamp.value + (hours_per_ruler.value * 3600 * 1000) / 2; //ms 记住当前中间的时间
    if (delta < 0) {
      zoom.value = zoom.value + 4;
      if (zoom.value >= 24) {
        zoom.value = 24; //放大最大24小时
      }
      hours_per_ruler.value = zoom.value;
    } else if (delta > 0) {
      // 放大
      zoom.value = zoom.value - 4;
      if (zoom.value <= 1) {
        zoom.value = 1; //缩小最小1小时
      }
      hours_per_ruler.value = zoom.value;
    }

    clearCanvas();
    start_timestamp.value = middle_time - (hours_per_ruler.value * 3600 * 1000) / 2; //start_timestamp = 当前中间的时间 - zoom/2
    init(start_timestamp.value, timecell.value);
  }

  /**
   * 获取鼠标posx
   * @param {*} e
   */
  function get_cursor_x_position(e) {
    let posx = 0;
    if (!e) {
      console.log('window.event', window.event);
      e = window.event;
    }
    if (e.offsetX || e.offsetX === 0) {
      posx = (e.offsetX * canvas.value.width) / tempW.value;
      //posx =  e.offsetX + e.offsetX * canvas.value.width/2110;
    } else if (e.layerX || e.layerX === 0) {
      console.log('e.layerX', e.layerX);
      posx = e.layerX;
    } else if (e.pageX || e.pageY) {
      console.log('e.pageX', e.pageX);
      posx = e.pageX;
    } else if (e.clientX || e.clientY) {
      console.log('e.clientX', e.clientX);
      posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    }
    return posx;
  }

  /**
   * 返回时间轴上刻度的时间
   * @param {*} datetime new Date 格式
   */
  function graduation_title(datetime) {
    if (datetime.getHours() == 0 && datetime.getMinutes() == 0 && datetime.getMilliseconds() == 0) {
      let month = datetime.getMonth() + 1;
      let date = datetime.getDate();
      if (month < 10) {
        month = '0' + month;
      }
      if (date < 10) {
        date = '0' + date;
      }
      return datetime.getFullYear() + '-' + month + '-' + date;
    }
    let hour = datetime.getHours();
    let minute = datetime.getMinutes();
    if (hour < 10) {
      hour = '0' + hour;
    }
    if (minute < 10) {
      minute = '0' + minute;
    }
    return hour + ':' + minute;
  }

  /**
   * 返回 YYYY-MM-DD HH:mm:ss 格式时间
   * @param {*} time
   * time: 1669257558730
   * newTime: Thu Nov 24 2022 10:39:18 GMT+0800 (中国标准时间)
   */
  function changeTime(time) {
    let newTime = new Date(time);
    let year;
    year = newTime.getFullYear();
    let month;
    month = newTime.getMonth() + 1;
    if (month < 10) {
      month = '0' + month;
    }
    let date;
    date = newTime.getDate();
    if (date < 10) {
      date = '0' + date;
    }
    let hour;
    hour = newTime.getHours();
    if (hour < 10) {
      hour = '0' + hour;
    }
    let minute;
    minute = newTime.getMinutes();
    if (minute < 10) {
      minute = '0' + minute;
    }
    let second;
    second = newTime.getSeconds();
    if (second < 10) {
      second = '0' + second;
    }
    return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second;
  }

  /**
   * 左侧开始时间的偏移，返回单位ms
   * @param {*} timestamp
   * @param {*} step
   */
  function ms_to_next_step(timestamp, step) {
    let remainder = timestamp % step;
    return remainder ? step - remainder : 0;
  }

  /**
   * 设置时间，让这个时间点跳到中间刻度线处
   *  @param {*} time 单位ms
   */
  function set_time_to_middle(time) {
    clearCanvas();
    start_timestamp.value = time - (hours_per_ruler.value * 60 * 60 * 1000) / 2;
    init(start_timestamp.value, timecell.value);
  }

  function returnMouseupTime() {
    if (returnTime.value != null) {
      return returnTime.value;
    }
  }

  /**
   * 清除canvas 每次重新绘制需要先清除
   */
  function clearCanvas() {
    ctx.value.clearRect(0, 0, 1500, 150);
  }

  onUnmounted(() => {
    clearInterval(setTimeMoveInterval.value);
  });
</script>
<style lang="less" scoped>
  .ant-row {
    flex-flow: row nowrap;
  }

  .show_hide_col {
    height: calc(100vh - 195px);
    display: contents;
  }

  .show_hide {
    height: 100%;
    width: 100%;
    display: flex;
    margin: auto 0;
    z-index: 2;
  }

  :global(.ant-picker-time-panel-column) {
    width: 40px !important;
  }
</style>
