<template>
  <div
    ref="playerWrapperRef"
    class="player-wrapper w-full h-full bg-#000 z-50 top-0 left-0"
    :class="noPage ? 'absolute' : 'fixed'"
    tabindex="0"
    @keydown="handleKeydown"
  >
    <!-- 视频标题遮罩（暂停时显示，参考 VideoPlayer） -->
    <div v-if="title && !isPlaying && !loading" class="title-overlay">
      <div class="title-text">{{ title }}</div>
    </div>

    <!-- 加载中遮罩 -->
    <div v-if="loading" class="loading-overlay">
      <div class="loading-spinner"></div>
    </div>

    <!-- Aliplayer 挂载点 -->
    <div :id="playerId" class="w-full h-full z-1"></div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
import { useRoute } from 'vue-router';
import { getTemItem, type TemObj } from './temObjs';

const props = defineProps<{
  url: string;
  cover?: string;
  noPage?: boolean;
  /** 视频标题（参考 VideoPlayer） */
  title?: string;
}>();

const emit = defineEmits<{
  (e: 'ended'): void;
  (e: 'play'): void;
  (e: 'pause'): void;
}>();

const route = useRoute();
const playerWrapperRef = ref<HTMLElement | null>(null);
const playerInstance = ref<any>(null);
const isPlaying = ref(false);
const loading = ref(true);

// 唯一 ID 避免多实例冲突
const playerId = ref(`playerView-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`);

const _temObj = ref<TemObj>({
  id: '',
  name: '',
  isEdit: false,
  url: '',
});

function createPlayer(source?: string, cover?: string) {
  if (!source) return;

  const mountEl = document.getElementById(playerId.value);
  if (!mountEl) return;

  // @ts-ignore
  playerInstance.value = new Aliplayer(
    {
      id: playerId.value,
      width: '100%',
      height: '100%',
      source: source,
      cover: cover || '/long/long.svg',
      skinLayout: [
        { name: 'bigPlayButton', align: 'cc', x: 0, y: 0 },
        { name: 'H5Loading', align: 'cc' },
        {
          name: 'controlBar',
          align: 'blabs',
          x: 0,
          y: 0,
          children: [
            { name: 'progress', align: 'tlabs', x: 0, y: 0 },
            { name: 'playButton', align: 'tl', x: 15, y: 10 },
            { name: 'timeDisplay', align: 'tl', x: 10, y: 2 },
            { name: 'fullScreenButton', align: 'tr', x: 20, y: 12 },
            { name: 'setting', align: 'tr', x: 20, y: 11 },
            { name: 'volume', align: 'tr', x: 20, y: 10 },
          ],
        },
      ],
    },
    (player: any) => {
      player.on('ended', () => {
        isPlaying.value = false;
        emit('ended');
      });
      player.on('play', () => {
        isPlaying.value = true;
        loading.value = false;
        emit('play');
      });
      player.on('pause', () => {
        isPlaying.value = false;
        emit('pause');
      });
      player.on('canplay', () => {
        loading.value = false;
      });
      player.on('waiting', () => {
        loading.value = true;
      });
    });
}

function dispose() {
  if (playerInstance.value) {
    try {
      playerInstance.value.dispose();
    } catch (_) {}
    playerInstance.value = null;
  }
}

function initPlayer() {
  if (!props.noPage) {
    const temObj = getTemItem(route.query._t as string);
    if (!temObj) return;
    _temObj.value = temObj;
    createPlayer(_temObj.value.url, '/long/long.svg');
  } else if (props.url) {
    createPlayer(props.url, props.cover || '/long/long.svg');
  }
}

// 键盘快捷键（参考 VideoPlayer）
function handleKeydown(e: KeyboardEvent) {
  const p = playerInstance.value;
  if (!p) return;

  switch (e.key) {
    case ' ':
      e.preventDefault();
      if (isPlaying.value) p.pause(); else p.play();
      break;
    case 'ArrowLeft':
      e.preventDefault();
      p.seek?.(Math.max(0, (p.getCurrentTime?.() ?? 0) - 10));
      break;
    case 'ArrowRight':
      e.preventDefault();
      const duration = p.getDuration?.() ?? 0;
      p.seek?.(Math.min(duration, (p.getCurrentTime?.() ?? 0) + 10));
      break;
    case 'ArrowUp':
      e.preventDefault();
      p.setVolume?.(Math.min(100, (p.getVolume?.() ?? 100) + 10));
      break;
    case 'ArrowDown':
      e.preventDefault();
      p.setVolume?.(Math.max(0, (p.getVolume?.() ?? 100) - 10));
      break;
    case 'f':
    case 'F':
      e.preventDefault();
      p.requestFullScreen?.();
      break;
    case 'm':
    case 'M':
      e.preventDefault();
      p.mute?.();
      break;
  }
}

watch(() => props.url, (newVal) => {
  if (newVal) {
    dispose();
    loading.value = true;
    nextTick(() => createPlayer(newVal, props.cover || '/long/long.svg'));
  }
});

onMounted(() => {
  nextTick(() => {
    initPlayer();
    playerWrapperRef.value?.focus?.();
  });
});

onBeforeUnmount(() => {
  dispose();
});
</script>

<style scoped lang="scss">
.player-wrapper {
  position: relative;
  outline: none;

  &:focus {
    outline: none;
  }
}

.title-overlay {
  position: absolute;
  bottom: 60px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 15;
  pointer-events: none;

  .title-text {
    padding: 8px 20px;
    background: rgba(0, 0, 0, 0.6);
    color: white;
    font-size: 16px;
    border-radius: 8px;
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
  }
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.5);
  z-index: 10;
}

.loading-spinner {
  width: 48px;
  height: 48px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-top-color: #ff8c42;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
