<template>
  <div v-show="props.show" :class="'vivify ' + buttonClass" :style="cardStyle"
    class="kf-lift-container w-100 h-100 flex-column-between-start">
    <div v-if="isStream && initFlag" ref="stream" style="width: 100%; height: 100%">
      <video id="idPlayer" autoplay muted style="width: 100%; height: 100%"></video>
    </div>
    <vue3-video-player autoplay v-else v-bind="options" :src="src" style="width: 100%; height: 100%;display: flex"
      ref="playerDom" :core="HLSCore"></vue3-video-player>
  </div>
</template>

<script>
import { computed, getCurrentInstance, nextTick, onMounted, ref, watch } from 'vue';
import styleManager from '../utils/style.vue';
import eventManager from '../utils/event';
import Const from '@/utils/const';
import pageModel from '../model/page';
import dataModel from '@/components/ui/model/data';
import { runUntil } from '@/utils/tools.js';
import flvjs from 'flv-h265.js';
import deviceService from '@/service/device';
//import HLSCore from '@cloudgeek/playcore-hls'

export default {
  name: 'kfVideo',
  props: {
    props: {
      type: Object,
      default: () => { },
    },
    eventList: {
      type: Array,
      default: () => [],
    },
    eventScript: {
      type: String,
    },
  },
  widgetConfig: {
    parent: 'base',
    rank: 10,
    label: {
      zh: '视频',
    },
    category: '基础',
    component: 'kfVideo',
    display: true,
    version: 1,
    icon: 'icon-anniu',
    defaultSize: {
      x: 300,
      y: 300,
    },
    imgName: 'kfVideo',
  },
  setup(props) {
    let cardStyle = ref({});
    const { proxy } = getCurrentInstance();
    let defaultHandler = ref({});
    let buttonClass = ref('');

    onMounted(() => {
      refreshEvents();
      cardStyle.value = styleManager.updateStyle(proxy);
      if (props?.props?.src) {
        init();
      }
      buttonClass.value = styleManager.updateClass(proxy);
    });

    const refreshEvents = function () {
      eventManager.registerEvent(proxy);
    };

    pageModel.watchProps(props, watch, proxy, (changes) => {
      refreshEvents();
      if (styleManager.styleChanged('kfVideo', changes)) {
        cardStyle.value = styleManager.updateStyle(proxy);
      }
      if (styleManager.classChanged('kfVideo', changes)) {
        buttonClass.value = styleManager.updateClass(proxy);
      }
      if (changes && changes['deviceId']) {
        // 组件绑定的数据ID变化，需要请求新的设备数据和对应的物模型
        // console.log(props.props.deviceId, "===kkkk===");
      }
      init();
    });

    const eventHandler = computed(() => {
      return eventManager.loadEventHandler(
        defaultHandler,
        undefined,
        props.props.pageName,
      );
    });

    const initFlag = ref(false);
    let playerDom = ref(null);

    const options = ref({
      muted: true, //静音
      webFullScreen: true,
      speedRate: ["0.75", "1.0", "1.25", "1.5", "2.0"],
      autoPlay: true,
      loop: true,
      preload: 'auto',
      mirror: false,
      lightOff: false,
      controls: props.props.control,
      title: '',
      src: props.props.outSrc, //视频源
    })

    const init = function () {
      initFlag.value = false;
      options.value.src = props.props.src;
      options.value.control = props.props.control;
      nextTick(() => {
        initFlag.value = true;
        if (playerDom.value) {
          playerDom.value.play();
        }
      });
    };

    const getImageUrl = function (pubUuid) {
      let url =
        Const.servicePath.value +
        '/api/repo/kf-pub-resource/load-file?uuid=' +
        pubUuid;
      return url;
    };

    const srcVersion = ref(0);

    const updateData = () => {
      srcVersion.value++;
    };

    const src = computed(() => {
      let result = null;
      if (props.props.deviceId && srcVersion.value) {
        let newData = dataModel.getData(props.props, true);
        let url = getCameraUrl(newData);
        if (url.indexOf('/') !== -1) {
          result = url;
        } else {
          result = getImageUrl(url);
        }
      } else {
        if (props.props.src?.indexOf('/') !== -1) {
          result = props.props.src;
        } else if (props.props.outSrc?.indexOf('/') !== -1) {
          result = props.props.outSrc;
        } else {
          result = getImageUrl(props.props.src);
        }
      }
      return result;
    });

    const getCameraUrl = (newData) => {
      let url = '';
      if (newData && typeof newData === 'string') {
        url = newData;
      } else if (newData && Array.isArray(newData)) {
        url = newData[0];
      } else if (newData && typeof newData === 'object') {
        if (
          newData?.device &&
          newData.device?.data &&
          newData.device.data?.url
        ) {
          url = newData.device.data.url;
        } else if (newData?.device) {
          let type = window.Kf?.config?.videoType;
          if (type == undefined) {
            type = "hls";
          }
          deviceService.getCameraUrl(newData.device.provider, newData.device.connId, newData.device.deviceId, type, window.location.protocol).
            then((res) => {
              newData.device.data.url = res ? res.streamUrl : 'url';
              srcVersion.value += 1;
            });
        }
      }
      return url;
    };

    let player = null;
    const stream = ref();

    watch(src, (newValue, oldValue) => {
      if (player) {
        try {
          player.pause();
          player.unload();
          player.detachMediaElement();
          player.destroy();
          player = null;
        } catch (e) {
        }
      }
      if (
        src.value &&
        (src.value.startsWith('rtsp://') ||
          src.value.startsWith('rtmp://'))
      ) {
        pageModel.currProject.value.settings =
          pageModel.currProject.value.settings || {};
        //todo: demo data
        //pageModel.currProject.value.settings.streamServer = "ws://dev.kingfisher.live:38888";
        runUntil(
          () => {
            return (
              stream.value != null &&
                pageModel.currProject.value.settings ? pageModel.currProject.value.settings.streamServer !=
              null : false
            );
          },
          () => {
            if (
              pageModel.currProject.value.settings?.streamServer
            ) {
              if (flvjs.isSupported()) {
                nextTick(() => {
                  console.log('创建播放器');
                  let id = new Date().getTime();
                  let video =
                    stream.value.querySelector('#idPlayer');
                  if (video) {
                    player = flvjs.createPlayer({
                      type: 'flv',
                      isLive: true,
                      url: `${pageModel.currProject.value.settings.streamServer}/rtsp/${id}/?url=${src.value}`,
                    });
                    player.attachMediaElement(video);
                    try {
                      player.load();
                      let playPromise = player.play();
                      if (playPromise !== undefined) {
                        playPromise.then(() => {
                          player.play();
                          initFlag.value = true;
                        }).catch(() => { });
                      }
                    } catch (error) {
                      console.log(error);
                    }
                  }
                });
              }
            } else {
              console.warn('需要设置流媒体服务器地址');
            }
          },
        );
      } else {
        options.value.src = src.value;
        nextTick(() => {
          initFlag.value = true;
          playerDom.value.play();
          const errorLayer =
            playerDom.value.$container.querySelector(
              '.error-layer',
            );
          if (errorLayer) {
            errorLayer.style.setProperty('display', 'none');
          }
        });
      }
    });

    const isStream = computed(() => {
      return (
        src.value &&
        (src.value.startsWith('rtsp://') ||
          src.value.startsWith('rtmp://'))
      );
    });

    return {
      cardStyle,
      eventHandler,
      options,
      initFlag,
      playerDom,
      defaultHandler,
      getImageUrl,
      buttonClass,
      src,
      isStream,
      stream,
      updateData,
      HLSCore: props.core
    };
  },
};
</script>

<style scoped>
::v-deep(.vue-core-video-player-layers) {
  z-index: 0;
}
</style>
