<template>
  <div class="page">
    <n-carousel autoplay draggable :interval="5000" class="banner-carousel">
      <div v-for="banner in banners" :key="banner.title" class="banner" :style="{ background: banner.gradient }">
        <div class="banner-text">
          <h2>{{ banner.title }}</h2>
          <p>{{ banner.sub }}</p>
        </div>
        <AppIcon name="music" :size="72" class="banner-mark" />
      </div>
    </n-carousel>

    <section class="section">
      <div class="section-head">
        <h3>分类</h3>
        <span class="section-sub">歌单分类</span>
      </div>
      <n-scrollbar x-scrollable class="category-scrollbar">
        <n-radio-group v-model:value="activeCategory" name="playlist-category" @update:value="playList">
          <n-radio-button v-for="category in categories" :key="category.id" :value="category.id" :label="category.name" />
        </n-radio-group>
      </n-scrollbar>
      <div class="card-grid">
        <MusicCard v-for="playlist in recommendedPlaylists" :key="playlist.id" :playlist="playlist" />
      </div>
    </section>

    <section class="section">
      <div class="section-head">
        <h3>推荐歌单</h3>
        <span class="section-sub">为你精选</span>
      </div>
      <!-- <div class="card-grid">
        <MusicCard v-for="playlist in recommendedPlaylists" :key="playlist.id" :playlist="playlist" />
      </div> -->
    </section>

    <section class="section">
      <div class="section-head">
        <h3>新歌速递</h3>
        <span class="section-sub">每日 20:00 更新</span>
      </div>
      <div class="new-song-row">
        <div
          v-for="(song, i) in newSongs"
          :key="song.id"
          class="new-song"
          tabindex="0"
          role="button"
          :aria-label="`播放 ${song.title}`"
          @click="playNewSong(i)"
          @keydown.enter="playNewSong(i)"
        >
          <div class="mini-cover" :style="{ background: song.cover }">
            <AppIcon name="music" :size="18" class="mini-mark" />
            <span class="mini-play"><AppIcon name="play" :size="11" /></span>
          </div>
          <p class="mini-title" :title="song.title">{{ song.title }}</p>
          <p class="mini-artist">{{ song.artist }} · {{ formatTime(song.duration) }}</p>
        </div>
      </div>
    </section>

    <section class="section">
      <div class="section-head">
        <h3>排行榜精选</h3>
        <span class="section-sub">总有一个榜单属于你</span>
      </div>
      <div class="rank-preview-grid">
        <div
          v-for="rank in rankLists.slice(0, 3)"
          :key="rank.id"
          class="rank-preview"
          tabindex="0"
          role="button"
          :aria-label="`查看榜单 ${rank.name}`"
          @click="router.push(`/playlist/${rank.id}`)"
          @keydown.enter="router.push(`/playlist/${rank.id}`)"
        >
          <div class="rank-head" :style="{ background: rank.cover }">
            <span class="rank-name">{{ rank.name }}</span>
            <AppIcon name="chevron-right" :size="16" />
          </div>
          <ol class="rank-list">
            <li v-for="(song, i) in rank.songs.slice(0, 5)" :key="song.id">
              <span class="rank-no" :class="{ top: i < 3 }">{{ i + 1 }}</span>
              <span class="rank-title" :title="song.title">{{ song.title }}</span>
              <span class="rank-artist">{{ song.artist }}</span>
            </li>
          </ol>
        </div>
      </div>
    </section>
  </div>
</template>

<script setup lang="ts">
import { NCarousel, useMessage } from "naive-ui"
import { useRouter } from "vue-router"
import AppIcon from "@/components/AppIcon.vue"
import MusicCard from "@/components/MusicCard.vue"
import { newSongs, rankLists, type Playlist } from "@/mocks/music"
import { playSong } from "@/stores/player"
import { proxyCover } from "@/utils/cover"
import { formatPlayCount } from "@/utils/format"
import { formatTime } from "@/utils/time"
import PlayListApi from "@/api/playlist"
import Source from "@/types/global"
import { cachePlayListSummary, type PlayListCategory } from "@/api/playlist"

const message = useMessage()
const router = useRouter()

const categories = ref<PlayListCategory[]>([])
const activeCategory = ref<string>("")
const recommendedPlaylists = ref<Playlist[]>([])

const banners = [
  {
    title: "本周主打",
    sub: "把耳朵交给这 12 首新单曲",
    gradient: "linear-gradient(120deg, #4338ca 0%, #7c3aed 55%, #ec4899 100%)",
  },
  {
    title: "私人雷达",
    sub: "根据你的口味生成的专属歌单",
    gradient: "linear-gradient(120deg, #0ea5e9 0%, #22d3ee 55%, #22c55e 100%)",
  },
  {
    title: "热歌榜",
    sub: "全站播放量最高的 100 首歌",
    gradient: "linear-gradient(120deg, #f59e0b 0%, #ef4444 55%, #f97316 100%)",
  },
]

function playNewSong(songIndex: number) {
  const song = newSongs[songIndex]
  playSong(song, newSongs)
  message.success(`正在播放：${song.title}`)
}

const list = async () => {
  const res = await PlayListApi.categoryList([Source.KuGou])
  categories.value = res[0].categories
  if (categories.value.length > 0) {
    activeCategory.value = categories.value[1].id
    await playList(activeCategory.value)
  }
}

const playList = async (categoryId: string) => {
  const res = await PlayListApi.categoryPlayList(categoryId, Source.KuGou, 1, 30)
  recommendedPlaylists.value = res.playlists.map((p) => {
    cachePlayListSummary(p)
    return {
      id: p.id,
      name: p.name,
      desc: p.description,
      cover: proxyCover(p.cover),
      tags: [],
      playCount: formatPlayCount(p.play_count),
      songs: [],
    }
  })
}

onMounted(() => {
  list()
})
</script>

<style scoped>
.page {
  max-width: 1200px;
  margin: 0 auto;
}

.banner-carousel {
  height: clamp(150px, 17vw, 200px);
  border-radius: 14px;
  overflow: hidden;
}

.banner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
  padding: 0 clamp(20px, 4vw, 44px);
  overflow: hidden;
}

.banner-text h2 {
  margin: 0 0 8px;
  font-size: clamp(22px, 3.2vw, 30px);
  font-weight: 700;
  color: #fff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
}

.banner-text p {
  margin: 0;
  font-size: 15px;
  color: rgba(255, 255, 255, 0.85);
}

.banner-mark {
  position: absolute;
  right: clamp(16px, 4vw, 36px);
  opacity: 0.28;
  color: #fff;
  transform: rotate(-8deg);
}

.section {
  margin-top: clamp(24px, 3vw, 34px);
}

.section-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 16px;
}

.section-head h3 {
  margin: 0;
  font-size: clamp(17px, 1.8vw, 20px);
  font-weight: 600;
}

.section-sub {
  font-size: 12px;
  color: var(--app-text-muted);
}

.category-scrollbar {
  padding-bottom: 8px;
}

.card-grid {
  display: grid;
  margin-top: 20px;
  grid-template-columns: repeat(auto-fill, minmax(clamp(140px, 14vw, 180px), 1fr));
  gap: 20px 18px;
}

.new-song-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: clamp(150px, 16vw, 200px);
  gap: 14px;
  overflow-x: auto;
  padding-bottom: 8px;
}

.new-song {
  cursor: pointer;
  min-width: 0;
}

.mini-cover {
  position: relative;
  aspect-ratio: 1;
  border-radius: 10px;
  overflow: hidden;
  display: grid;
  place-items: center;
}

.mini-mark {
  color: rgba(255, 255, 255, 0.4);
}

.mini-play {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--app-green);
  color: #052e16;
  opacity: 0;
  transform: translateY(5px);
  transition:
    opacity 0.2s ease,
    transform 0.2s ease;
}

.new-song:hover .mini-play,
.new-song:focus-visible .mini-play {
  opacity: 1;
  transform: translateY(0);
}

.mini-title {
  margin: 8px 0 2px;
  font-size: 13px;
  color: var(--app-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mini-artist {
  margin: 0;
  font-size: 12px;
  color: var(--app-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rank-preview-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.rank-preview {
  border: 1px solid var(--app-border);
  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
  transition:
    transform 0.2s ease,
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}

.rank-preview:hover,
.rank-preview:focus-visible {
  transform: translateY(-2px);
  border-color: rgba(109, 93, 246, 0.45);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.3);
}

.rank-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 52px;
  padding: 0 16px;
  color: rgba(255, 255, 255, 0.9);
}

.rank-name {
  font-size: 16px;
  font-weight: 700;
}

.rank-list {
  margin: 0;
  padding: 8px 16px 12px;
  list-style: none;
}

.rank-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 30px;
  font-size: 13px;
}

.rank-no {
  width: 18px;
  color: var(--app-text-muted);
  font-variant-numeric: tabular-nums;
}

.rank-no.top {
  color: var(--app-green);
  font-weight: 700;
}

.rank-title {
  flex: 1;
  min-width: 0;
  color: var(--app-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rank-artist {
  color: var(--app-text-muted);
  font-size: 12px;
}

@media (max-width: 720px) {
  .banner-mark {
    width: 48px;
    height: 48px;
  }

  .banner-text h2 {
    font-size: 22px;
  }

  .banner-text p {
    font-size: 13px;
  }
}

@media (max-width: 900px) {
  .rank-preview-grid {
    grid-template-columns: 1fr;
  }
}
</style>
