<template>
  <SlideVertical
    v-model:index="currentIndex"
    class="video-feed"
    name="home-feed"
  >
    <SlideItem
      v-for="(item, index) in list"
      :key="item.aweme_id"
      class="feed-item"
    >
      <BaseVideo
        :item="item"
        :index="index"
        :position="{ uniqueId: UNIQUE_ID, index }"
        :is-play="active && currentIndex === index"
        @update:item="(val) => onItemUpdate(index, val)"
      />
    </SlideItem>
  </SlideVertical>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue'
import SlideVertical from '@/components/slide/SlideVertical.vue'
import SlideItem from '@/components/slide/SlideItem.vue'
import BaseVideo from '@/components/video/BaseVideo.vue'
import { recommendVideos, type RecommendVideo } from '@/mock/homeData'
import bus, { EVENT_KEY } from '@/utils/bus'

const UNIQUE_ID = 'home'

const props = defineProps({
  active: { type: Boolean, default: false },
})

const list = ref<RecommendVideo[]>([...recommendVideos])
const currentIndex = ref(0)

function onItemUpdate(index: number, val: unknown) {
  list.value[index] = val as RecommendVideo
}

function onUpdateItem(val?: unknown) {
  const payload = val as {
    position?: { uniqueId: string; index: number }
    item?: RecommendVideo
  }
  if (payload?.position?.uniqueId === UNIQUE_ID && payload.item) {
    list.value[payload.position.index] = payload.item
  }
}

function broadcastPlay(index: number) {
  bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
    uniqueId: UNIQUE_ID,
    index,
    type: EVENT_KEY.ITEM_PLAY,
  })
}

function broadcastStop(index: number) {
  bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
    uniqueId: UNIQUE_ID,
    index,
    type: EVENT_KEY.ITEM_STOP,
  })
}

function togglePlay() {
  if (!props.active) return
  bus.emit(EVENT_KEY.SINGLE_CLICK_BROADCAST, {
    uniqueId: UNIQUE_ID,
    index: currentIndex.value,
    type: EVENT_KEY.ITEM_TOGGLE,
  })
}

watch(currentIndex, (newVal, oldVal) => {
  if (!props.active) return
  bus.emit(EVENT_KEY.CURRENT_ITEM, list.value[newVal])
  broadcastPlay(newVal)
  if (oldVal !== undefined && oldVal !== newVal) {
    setTimeout(() => broadcastStop(oldVal), 200)
  }
})

watch(
  () => props.active,
  (newVal) => {
    const t = newVal ? 0 : 200
    if (newVal) {
      bus.emit(EVENT_KEY.CURRENT_ITEM, list.value[currentIndex.value])
    }
    setTimeout(() => {
      if (newVal) broadcastPlay(currentIndex.value)
      else broadcastStop(currentIndex.value)
    }, t)
  },
  { immediate: true },
)

onMounted(() => {
  bus.on(EVENT_KEY.TOGGLE_CURRENT_VIDEO, togglePlay)
  bus.on(EVENT_KEY.UPDATE_ITEM, onUpdateItem)
})

onUnmounted(() => {
  bus.off(EVENT_KEY.TOGGLE_CURRENT_VIDEO, togglePlay)
  bus.off(EVENT_KEY.UPDATE_ITEM, onUpdateItem)
})
</script>

<style scoped lang="less">
.video-feed {
  height: 100%;
  width: 100%;
  background: #000;

  :deep(.feed-item) {
    position: relative;
    height: 100%;
    width: 100%;
  }
}
</style>
