<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-center gap-3">
            <div>
              <h2 class="mb-2 page-title">{{ columnInfo.name || '七十二家房客播放器' }}</h2>
              <div class="page-subtitle">
                共 {{ allEpisodeList.length }} 条 ｜ 最后更新：{{ updatedAtText }}
              </div>
            </div>

            <div class="d-flex flex-wrap gap-2">
              <button class="btn btn-dark btn-sm px-3" @click="handleRefresh">刷新数据</button>
              <button class="btn btn-warning btn-sm px-3" @click="openSource">数据来源：荔枝网</button>
            </div>
          </div>
        </div>
      </div>

      <div class="col-12">
        <div class="toolbar-card card border-0 shadow-sm">
          <div class="card-body 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-2">
              <input id="autoNext" v-model="autoNext" class="form-check-input" type="checkbox" />
              <label class="form-check-label" for="autoNext">自动下一集</label>
            </div>

            <select v-model="playMode" class="form-select form-select-sm mode-select">
              <option value="asc">顺序播放</option>
              <option value="desc">倒序播放</option>
            </select>
          </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="currentEpisode" class="episode-info mt-3">
              <div class="episode-badge mb-2">当前播放</div>
              <h4 class="mb-2 episode-title">{{ currentEpisode.title }}</h4>
              <div class="episode-meta">
                发布时间：{{ formatDate(currentEpisode.releasedAt) }}
                <span class="mx-2">｜</span>
                时长：{{ formatDuration(currentEpisode.timeLength) }}
              </div>
            </div>

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

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

            <QishierProjectLinks />
          </div>
        </div>
      </div>

      <div class="col-xl-4 col-lg-5">
        <QishierEpisodeList
            :episodes="displayEpisodeList"
            :current-episode-id="currentEpisode?.id || ''"
            :years="years"
            :selected-year="selectedYear"
            @select="playEpisode"
            @updateYear="handleYearChange"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } 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'
import QishierProjectLinks from '@/components/qishier/QishierProjectLinks.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 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 (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 handlePlayerError(message: string) {
  errorMsg.value = message
}

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

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

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
    }

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

    if (savedEpisode) {
      selectedYear.value = getEpisodeYear(savedEpisode)
      currentEpisode.value = savedEpisode
      return
    }

    const firstEpisode = allEpisodeList.value[0]
    if (firstEpisode) {
      selectedYear.value = getEpisodeYear(firstEpisode)
      currentEpisode.value = firstEpisode
    }
  } 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)
  errorMsg.value = ''
  saveCurrentEpisodeId(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')}`
}

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

<style scoped>
.qishier-page {
  min-height: 100vh;
  background:
      radial-gradient(circle at top left, rgba(255, 193, 7, 0.12), transparent 28%),
      radial-gradient(circle at top right, rgba(13, 110, 253, 0.1), transparent 24%),
      linear-gradient(180deg, #f8f9fa 0%, #eef1f5 100%);
}

.top-card,
.toolbar-card,
.content-card {
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
}

.page-title {
  font-weight: 700;
  color: #212529;
}

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

.mode-select {
  width: 140px;
}

.episode-info {
  padding: 2px 2px 6px;
}

.episode-badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 193, 7, 0.18);
  color: #9a6a00;
  font-size: 12px;
  font-weight: 600;
}

.episode-title {
  color: #212529;
  font-weight: 700;
}

.episode-meta {
  color: #6c757d;
  font-size: 14px;
}
</style>
