<template>
  <div class="episode-card card border-0 shadow-sm h-100">
    <div class="card-header bg-transparent border-0 pt-3 pb-2 px-3">
      <div class="d-flex justify-content-between align-items-center gap-2 flex-wrap">
        <div class="fw-bold text-dark">剧集列表</div>

        <select v-model="innerYear" class="form-select form-select-sm year-select">
          <option value="all">全部年份</option>
          <option v-for="year in years" :key="year" :value="String(year)">
            {{ year }}
          </option>
        </select>
      </div>
    </div>

    <div ref="listPanelRef" class="card-body pt-2 episode-panel">
      <button
          v-for="item in pagedEpisodes"
          :key="item.id"
          :data-episode-id="item.id"
          type="button"
          class="episode-row btn w-100 text-start mb-2"
          :class="currentEpisodeId === item.id ? 'btn-warning current-row' : 'btn-light'"
          @click="handleSelect(item, $event)"
      >
        <div class="episode-date mb-1">{{ formatDate(item.releasedAt) }}</div>
        <div class="episode-title">{{ item.title }}</div>
      </button>

      <div v-if="pagedEpisodes.length === 0" class="empty-tip text-center py-4">
        当前筛选没有数据
      </div>
    </div>

    <div class="card-footer bg-transparent border-0 px-3 pb-3 pt-1">
      <div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
        <div class="small text-secondary">
          共 {{ filteredEpisodes.length }} 条，当前第 {{ currentPage }} / {{ totalPages || 1 }} 页
        </div>

        <div class="btn-group btn-group-sm">
          <button class="btn btn-outline-secondary" :disabled="currentPage <= 1" @click="prevPage">
            上一页
          </button>
          <button class="btn btn-outline-secondary" :disabled="currentPage >= totalPages" @click="nextPage">
            下一页
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, ref, watch } from 'vue'
import type { EpisodeData } from '@/api/qishier'

const props = defineProps<{
  episodes: EpisodeData[]
  currentEpisodeId: string
  years: number[]
  selectedYear: string
}>()

const emit = defineEmits<{
  select: [episode: EpisodeData]
  updateYear: [year: string]
}>()

const listPanelRef = ref<HTMLElement | null>(null)
const innerYear = ref(props.selectedYear || 'all')
const pageSize = 20
const currentPage = ref(1)

watch(
    () => props.selectedYear,
    (val) => {
      const nextVal = val || 'all'
      if (innerYear.value !== nextVal) {
        innerYear.value = nextVal
      }
    }
)

watch(innerYear, (val) => {
  if (val === props.selectedYear) return
  currentPage.value = 1
  emit('updateYear', val)
})

const filteredEpisodes = computed(() => {
  if (innerYear.value === 'all') return props.episodes
  const year = Number(innerYear.value)
  return props.episodes.filter(item => new Date(item.releasedAt).getFullYear() === year)
})

const totalPages = computed(() => {
  return Math.ceil(filteredEpisodes.value.length / pageSize)
})

const pagedEpisodes = computed(() => {
  const start = (currentPage.value - 1) * pageSize
  return filteredEpisodes.value.slice(start, start + pageSize)
})

function prevPage() {
  if (currentPage.value > 1) currentPage.value--
}

function nextPage() {
  if (currentPage.value < totalPages.value) currentPage.value++
}

function formatDate(timestamp: number): string {
  if (!timestamp) return '--'
  const d = new Date(timestamp)
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return `${y}-${m}-${day}`
}

function isMobileDevice() {
  return window.innerWidth < 992
}

function handleSelect(item: EpisodeData, event: MouseEvent) {
  ;(event.currentTarget as HTMLButtonElement | null)?.blur()
  emit('select', item)
}
async function locateCurrentEpisode() {
  if (!props.currentEpisodeId) return

  const fullList = filteredEpisodes.value
  const idx = fullList.findIndex(item => item.id === props.currentEpisodeId)
  if (idx < 0) return

  const targetPage = Math.floor(idx / pageSize) + 1
  if (currentPage.value !== targetPage) {
    currentPage.value = targetPage
    await nextTick()
  }

  const panel = listPanelRef.value
  if (!panel) return

  const activeEl = panel.querySelector(
      `[data-episode-id="${props.currentEpisodeId}"]`
  ) as HTMLElement | null

  if (!activeEl) return

  // 手机端不自动滚整个页面
  if (isMobileDevice()) {
    const panelTop = panel.scrollTop
    const itemTop = activeEl.offsetTop
    const itemHeight = activeEl.offsetHeight
    const panelHeight = panel.clientHeight

    panel.scrollTo({
      top: itemTop - panelHeight / 2 + itemHeight / 2,
      behavior: 'smooth'
    })
    return
  }

  activeEl.scrollIntoView({
    behavior: 'smooth',
    block: 'center',
    inline: 'nearest'
  })
}

watch(
    () => props.currentEpisodeId,
    async () => {
      await locateCurrentEpisode()
    },
    { immediate: true }
)

watch(
    () => props.episodes.length,
    async () => {
      await locateCurrentEpisode()
    }
)

watch(
    () => props.selectedYear,
    async () => {
      await locateCurrentEpisode()
    }
)
</script>

<style scoped>
.episode-card {
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
}

.episode-panel {
  max-height: 72vh;
  overflow-y: auto;
}

.episode-row {
  border-radius: 14px;
  border: 1px solid rgba(0, 0, 0, 0.06);
  padding: 12px 14px;
  transition: all 0.2s ease;
}

.episode-row:hover {
  transform: translateY(-1px);
}

.current-row {
  box-shadow: 0 8px 20px rgba(255, 193, 7, 0.22);
}

.episode-date {
  font-size: 12px;
  color: #6c757d;
}

.episode-title {
  line-height: 1.45;
  font-size: 14px;
  font-weight: 600;
  white-space: normal;
}

.year-select {
  width: 120px;
}

.empty-tip {
  color: #6c757d;
}
</style>
