import { useQuery } from '@tanstack/react-query' import { ChevronDown, ListMusic, Pause, Play, Repeat2, Rewind, Shuffle, SkipForward, Trash2, Volume2 } from 'lucide-react' import { useMemo, useState } from 'react' import { FavoriteToggle } from '@/components/favorite-toggle' import { coverArtUrl, fetchFavorites } from '@/lib/api' import { usePlayerStore } from '@/stores/player-store' type LyricsLine = { time: number text: string } export function FullPlayer() { const currentTrack = usePlayerStore((state) => state.currentTrack) const queue = usePlayerStore((state) => state.queue) const isPlaying = usePlayerStore((state) => state.isPlaying) const currentTime = usePlayerStore((state) => state.currentTime) const duration = usePlayerStore((state) => state.duration) const volume = usePlayerStore((state) => state.volume) const shuffle = usePlayerStore((state) => state.shuffle) const repeatMode = usePlayerStore((state) => state.repeatMode) const togglePlayback = usePlayerStore((state) => state.togglePlayback) const playNext = usePlayerStore((state) => state.playNext) const playPrevious = usePlayerStore((state) => state.playPrevious) const playAtIndex = usePlayerStore((state) => state.playAtIndex) const removeFromQueue = usePlayerStore((state) => state.removeFromQueue) const toggleShuffle = usePlayerStore((state) => state.toggleShuffle) const cycleRepeatMode = usePlayerStore((state) => state.cycleRepeatMode) const setVolume = usePlayerStore((state) => state.setVolume) const seekTo = usePlayerStore((state) => state.seekTo) const setFullPlayerOpen = usePlayerStore((state) => state.setFullPlayerOpen) const [tab, setTab] = useState<'queue' | 'now' | 'lyrics'>('now') const favoritesQuery = useQuery({ queryKey: ['favorites'], queryFn: fetchFavorites, enabled: !!currentTrack, }) const lyricsQuery = useQuery({ queryKey: ['lrclib', currentTrack?.id], enabled: !!currentTrack, queryFn: async () => { const url = new URL('https://lrclib.net/api/get') url.searchParams.set('track_name', currentTrack?.title ?? '') url.searchParams.set('artist_name', currentTrack?.artistName ?? '') url.searchParams.set('album_name', currentTrack?.albumTitle ?? '') const response = await fetch(url.toString()) if (!response.ok) { throw new Error('lyrics not found') } return response.json() as Promise<{ syncedLyrics?: string; plainLyrics?: string }> }, }) const parsedLyrics = useMemo(() => parseLyrics(lyricsQuery.data?.syncedLyrics ?? lyricsQuery.data?.plainLyrics ?? ''), [lyricsQuery.data]) const favoriteTrackIds = useMemo(() => new Set((favoritesQuery.data?.tracks ?? []).map((item) => item.id)), [favoritesQuery.data]) const activeLine = useMemo(() => { if (parsedLyrics.length === 0) { return -1 } for (let index = parsedLyrics.length - 1; index >= 0; index -= 1) { if (parsedLyrics[index].time <= currentTime) { return index } } return -1 }, [currentTime, parsedLyrics]) if (!currentTrack) { return null } return (