<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue';

import Player from 'xgplayer';

import 'xgplayer/dist/index.min.css';

interface Props {
  src: string;
  autoplay?: boolean;
  controls?: boolean;
  thumbnail?: boolean;
  width?: number | string;
  height?: number | string;
  poster?: string;
}

const props = withDefaults(defineProps<Props>(), {
  autoplay: false,
  controls: true,
  thumbnail: false,
  width: '100%',
  height: '100%',
  poster: undefined,
});

const emit = defineEmits<{
  ready: [player: Player];
  error: [error: any];
  ended: [];
}>();

const containerRef = ref<HTMLDivElement>();
const player = shallowRef<Player | null>(null);

function createPlayer() {
  if (!containerRef.value || !props.src) return;

  player.value?.destroy();
  player.value = null;

  const ignores = props.thumbnail
    ? [
        'cssfullscreen',
        'screenshot',
        'pip',
        'miniscreen',
        'keyboard',
        'download',
        'playbackrate',
        'time',
        'definition',
        'fullscreen',
        'loading',
        'mobile',
        'pc',
        'play',
        'poster',
        'progress',
        'replay',
        'start',
        'volume',
      ]
    : [];

  const p = new Player({
    el: containerRef.value,
    url: props.src,
    autoplay: props.autoplay,
    controls: props.thumbnail ? false : props.controls,
    closeVideoClick: props.thumbnail,
    closeVideoDblclick: props.thumbnail,
    ignores,
    fluid: true,
    fitVideoSize: 'fixWidth',
    videoInit: true,
    poster: props.poster,
    playsinline: true,
    enableContextmenu: !props.thumbnail,
  });

  p.on('ready', () => {
    emit('ready', p);
  });

  p.on('error', (e: any) => {
    emit('error', e);
  });

  p.on('ended', () => {
    emit('ended');
  });

  player.value = p;
}

onMounted(() => {
  createPlayer();
});

onBeforeUnmount(() => {
  player.value?.destroy();
  player.value = null;
});

watch(
  () => props.src,
  () => {
    createPlayer();
  },
);

defineExpose({
  getPlayer: () => player.value,
  play: () => player.value?.play(),
  pause: () => player.value?.pause(),
  destroy: () => {
    player.value?.destroy();
    player.value = null;
  },
});
</script>

<template>
  <div ref="containerRef" class="xg-video-player"></div>
</template>

<style scoped>
.xg-video-player {
  width: v-bind(width);
  height: v-bind(height);
}
</style>
