<template>
  <div class="container-fluid qishier-page py-3">
    <div class="row g-3">
      <!-- 顶部标题区 -->
      <div class="col-12">
        <div class="top-card card border-0 shadow-sm">
          <div class="card-body d-flex flex-wrap justify-content-between align-items-start gap-3">
            <div class="page-main-info">
              <template v-if="currentEpisode">
                <div class="episode-badges mb-2">
                  <span class="info-badge playing">当前播放</span>
                  <span class="meta-pill">发布时间：{{ formatDate(currentEpisode.releasedAt) }}</span>
                  <span class="meta-pill">时长：{{ formatDuration(currentEpisode.timeLength) }}</span>
                </div>

                <h2 class="mb-2 page-title">{{ currentEpisode.title }}</h2>
              </template>

              <template v-else>
                <h2 class="mb-2 page-title">{{ columnInfo.name || '七十二家房客播放器' }}</h2>
                <div class="episode-meta mb-2">正在加载节目数据...</div>
              </template>

              <div class="page-subtitle">
                共 {{ allEpisodeList.length }} 条
                <span class="mx-2">｜</span>
                最后更新：{{ updatedAtText }}
              </div>
            </div>

            <div class="header-actions d-flex flex-wrap gap-2">
              <button class="btn btn-dark btn-sm px-3" @click="handleRefresh">
                刷新数据
              </button>

              <button class="btn btn-outline-dark btn-sm px-3" @click="openSource">
                数据来源
              </button>

              <button class="btn btn-outline-primary btn-sm px-3" @click="openGitRepo">
                Git仓库：v163
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 控制区 -->
      <div class="col-12">
        <div class="control-card card border-0 shadow-sm">
          <div class="card-body d-flex flex-wrap justify-content-between align-items-center gap-3">
            <div class="d-flex flex-wrap gap-2 align-items-center">
              <button class="btn btn-outline-dark btn-sm" @click="playPrevEpisode" :disabled="!hasPrevEpisode">
                上一集
              </button>

              <button class="btn btn-outline-dark btn-sm" @click="playNextEpisode" :disabled="!hasNextEpisode">
                下一集
              </button>

              <div class="form-check form-switch ms-1">
                <input id="autoNext" v-model="autoNext" class="form-check-input" type="checkbox" />
                <label class="form-check-label small" for="autoNext">自动下一集</label>
              </div>
            </div>

            <div class="d-flex flex-wrap gap-2 align-items-center">
              <select v-model="playMode" class="form-select form-select-sm mode-select">
                <option value="asc">顺序播放</option>
                <option value="desc">倒序播放</option>
              </select>

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

              <select v-model="selectedMonth" class="form-select form-select-sm filter-select">
                <option value="all">全部月份</option>
                <option v-for="month in months" :key="month" :value="String(month)">
                  {{ month }}月
                </option>
              </select>
            </div>
          </div>
        </div>
      </div>

      <!-- 左侧播放器 -->
      <div class="col-xl-8 col-lg-7">
        <div class="content-card card border-0 shadow-sm">
          <div class="card-body">
            <QishierVideoPlayer
                :episode="currentEpisode"
                :auto-next="autoNext"
                @error="handlePlayerError"
                @ended-next="handleEndedNext"
            />

            <div v-if="errorMsg" class="alert alert-danger mt-3 mb-0">
              {{ errorMsg }}
            </div>

            <QishierShowcase
                v-if="showcaseEpisodes.length > 0"
                :episodes="showcaseEpisodes"
                @select="playEpisode"
            />
          </div>
        </div>
      </div>

      <!-- 右侧列表 -->
      <div class="col-xl-4 col-lg-5">
        <QishierEpisodeList
            :episodes="displayEpisodeList"
            :current-episode-id="currentEpisode?.id || ''"
            :years="years"
            :months="months"
            :selected-year="selectedYear"
            :selected-month="selectedMonth"
            @select="playEpisode"
            @updateYear="handleYearChange"
            @updateMonth="handleMonthChange"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { getAllQishierList, refreshQishierCache, type EpisodeData } from '@/api/qishier'
import { getCurrentEpisodeId, saveCurrentEpisodeId } from '@/utils/playHistory'
import QishierVideoPlayer from '@/components/qishier/QishierVideoPlayer.vue'
import QishierEpisodeList from '@/components/qishier/QishierEpisodeList.vue'
import QishierShowcase from '@/components/qishier/QishierShowcase.vue'

const columnInfo = reactive({
  name: '',
  coverUrl: ''
})

const allEpisodeList = ref<EpisodeData[]>([])
const currentEpisode = ref<EpisodeData | null>(null)
const errorMsg = ref('')
const updatedAt = ref<string | null>(null)
const years = ref<number[]>([])
const selectedYear = ref('all')
const months = ref<number[]>([])
const selectedMonth = ref('all')

const autoNext = ref(true)
const playMode = ref<'asc' | 'desc'>('asc')

const updatedAtText = computed(() => {
  if (!updatedAt.value) return '暂无缓存'
  return new Date(updatedAt.value).toLocaleString('zh-CN')
})

const displayEpisodeList = computed(() => {
  let list = [...allEpisodeList.value]

  if (selectedYear.value !== 'all') {
    const year = Number(selectedYear.value)
    list = list.filter(item => new Date(item.releasedAt).getFullYear() === year)
  }

  if (selectedMonth.value !== 'all') {
    const month = Number(selectedMonth.value)
    list = list.filter(item => new Date(item.releasedAt).getMonth() + 1 === month)
  }

  if (playMode.value === 'desc') {
    list.reverse()
  }

  return list
})

const showcaseEpisodes = computed(() => {
  const list = displayEpisodeList.value.length > 0 ? displayEpisodeList.value : allEpisodeList.value
  return list.slice(0, 8)
})

const currentDisplayIndex = computed(() => {
  if (!currentEpisode.value) return -1
  return displayEpisodeList.value.findIndex(item => item.id === currentEpisode.value?.id)
})

const hasPrevEpisode = computed(() => currentDisplayIndex.value > 0)
const hasNextEpisode = computed(() => {
  return currentDisplayIndex.value >= 0 && currentDisplayIndex.value < displayEpisodeList.value.length - 1
})

function openSource() {
  window.open('https://www1.gdtv.cn/', '_blank')
}

function openGitRepo() {
  window.open('https://git.a-hxin.cn/ahxin/72QishierPlayer.git', '_blank')
}

function getEpisodeIdFromUrl() {
  const path = window.location.pathname
  const match = path.match(/^\/episode\/([^/]+)$/)
  if (match?.[1]) {
    return decodeURIComponent(match[1])
  }

  const queryId = new URLSearchParams(window.location.search).get('episode')
  return queryId || ''
}

function updateUrlByEpisodeId(id: string) {
  const nextUrl = `/episode/${encodeURIComponent(id)}`
  if (window.location.pathname !== nextUrl) {
    window.history.replaceState({}, '', nextUrl)
  }
}

function handlePlayerError(message: string) {
  errorMsg.value = message
}

function handleYearChange(year: string) {
  selectedYear.value = year
}

function handleMonthChange(month: string) {
  selectedMonth.value = month
}

function getEpisodeYear(item: EpisodeData) {
  return String(new Date(item.releasedAt).getFullYear())
}

function getEpisodeMonth(item: EpisodeData) {
  return String(new Date(item.releasedAt).getMonth() + 1)
}

function rebuildMonthsByYear() {
  let source = [...allEpisodeList.value]

  if (selectedYear.value !== 'all') {
    const year = Number(selectedYear.value)
    source = source.filter(item => new Date(item.releasedAt).getFullYear() === year)
  }

  months.value = [
    ...new Set(source.map(item => new Date(item.releasedAt).getMonth() + 1))
  ].sort((a, b) => a - b)

  if (selectedMonth.value !== 'all') {
    const currentMonth = Number(selectedMonth.value)
    if (!months.value.includes(currentMonth)) {
      selectedMonth.value = 'all'
    }
  }
}

async function fetchAllEpisodes() {
  try {
    errorMsg.value = ''
    const res = await getAllQishierList()
    const data = res.data

    columnInfo.name = data.name || '七十二家房客'
    updatedAt.value = data.updatedAt || null
    years.value = Array.isArray(data.years) ? [...data.years].sort((a, b) => b - a) : []
    allEpisodeList.value = Array.isArray(data.list) ? data.list : []

    if (allEpisodeList.value.length === 0) {
      errorMsg.value = '暂无节目数据'
      return
    }

    rebuildMonthsByYear()

    const urlEpisodeId = getEpisodeIdFromUrl()
    const urlEpisode = allEpisodeList.value.find(item => item.id === urlEpisodeId)

    if (urlEpisode) {
      selectedYear.value = getEpisodeYear(urlEpisode)
      rebuildMonthsByYear()
      selectedMonth.value = getEpisodeMonth(urlEpisode)
      currentEpisode.value = urlEpisode
      saveCurrentEpisodeId(urlEpisode.id)
      updateUrlByEpisodeId(urlEpisode.id)
      return
    }

    const savedEpisodeId = getCurrentEpisodeId()
    const savedEpisode = allEpisodeList.value.find(item => item.id === savedEpisodeId)

    if (savedEpisode) {
      selectedYear.value = getEpisodeYear(savedEpisode)
      rebuildMonthsByYear()
      selectedMonth.value = getEpisodeMonth(savedEpisode)
      currentEpisode.value = savedEpisode
      updateUrlByEpisodeId(savedEpisode.id)
      return
    }

    const firstEpisode = allEpisodeList.value[0]
    if (firstEpisode) {
      selectedYear.value = getEpisodeYear(firstEpisode)
      rebuildMonthsByYear()
      selectedMonth.value = getEpisodeMonth(firstEpisode)
      currentEpisode.value = firstEpisode
      saveCurrentEpisodeId(firstEpisode.id)
      updateUrlByEpisodeId(firstEpisode.id)
    }
  } catch (error: any) {
    console.error('fetchAllEpisodes error:', error)
    errorMsg.value = error?.message || '读取数据失败'
  }
}

async function handleRefresh() {
  try {
    await refreshQishierCache()
    await fetchAllEpisodes()
  } catch (error: any) {
    console.error('handleRefresh error:', error)
    errorMsg.value = error?.message || '刷新失败'
  }
}

async function playEpisode(item: EpisodeData) {
  currentEpisode.value = item
  selectedYear.value = getEpisodeYear(item)
  rebuildMonthsByYear()
  selectedMonth.value = getEpisodeMonth(item)
  errorMsg.value = ''
  saveCurrentEpisodeId(item.id)
  updateUrlByEpisodeId(item.id)
}

async function playPrevEpisode() {
  if (!hasPrevEpisode.value) return
  const prev = displayEpisodeList.value[currentDisplayIndex.value - 1]
  if (prev) {
    await playEpisode(prev)
  }
}

async function playNextEpisode() {
  if (!hasNextEpisode.value) return
  const next = displayEpisodeList.value[currentDisplayIndex.value + 1]
  if (next) {
    await playEpisode(next)
  }
}

async function handleEndedNext() {
  if (autoNext.value) {
    await playNextEpisode()
  }
}

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 formatDuration(seconds: number): string {
  if (!seconds && seconds !== 0) return '--'
  const m = Math.floor(seconds / 60)
  const s = seconds % 60
  return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
}

watch(selectedYear, () => {
  rebuildMonthsByYear()
})

onMounted(() => {
  void fetchAllEpisodes()
})
</script>

<style scoped>
.qishier-page {
  min-height: 100vh;
  background:
      radial-gradient(circle at top left, rgba(99, 102, 241, 0.10), transparent 28%),
      radial-gradient(circle at top right, rgba(16, 185, 129, 0.08), transparent 24%),
      linear-gradient(180deg, #f7f8fb 0%, #eef2f7 100%);
}

.top-card,
.control-card,
.content-card {
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(10px);
}

.page-main-info {
  min-width: 0;
}

.page-title {
  font-weight: 800;
  color: #1f2937;
  letter-spacing: -0.02em;
  line-height: 1.35;
}

.page-subtitle {
  color: #6b7280;
  font-size: 14px;
}

.header-actions {
  flex-shrink: 0;
}

.mode-select {
  width: 132px;
}

.filter-select {
  width: 120px;
}

.episode-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.info-badge,
.meta-pill {
  display: inline-flex;
  align-items: center;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
}

.info-badge.playing {
  background: rgba(59, 130, 246, 0.12);
  color: #2563eb;
}

.meta-pill {
  background: rgba(15, 23, 42, 0.06);
  color: #475569;
}

.episode-meta {
  color: #6b7280;
  font-size: 14px;
}

@media (max-width: 991px) {
  .header-actions {
    width: 100%;
  }
}
</style>
