<script lang="ts">
import { onDestroy, onMount } from "svelte";
import { slide } from "svelte/transition";
import Icon from "@iconify/svelte";

import type { MusicPlayerTrack } from "@/types/config";
import { musicPlayerConfig } from "@/config";
import { i18n } from "@i18n/translation";
import Key from "@i18n/i18nKey";
import "@styles/musicplayer.css";


// 音乐播放器模式，可选 "local" 或 "meting"
let mode = $state(musicPlayerConfig.mode ?? "meting");
// Meting API 地址，从配置中获取或使用默认值
let meting_api = musicPlayerConfig.meting?.meting_api ?? "https://api.i-meto.com/meting/api";
// Meting API 的数据源，从配置中获取或使用默认值
let meting_server = musicPlayerConfig.meting?.server ?? "netease";
// Meting API 的类型，从配置中获取或使用默认值
let meting_type = musicPlayerConfig.meting?.type ?? "playlist";
// Meting API 的 ID，从配置中获取或使用默认值
let meting_id = musicPlayerConfig.meting?.id ?? "2161912966";
// 是否启用自动播放，从配置中获取或使用默认值
let isAutoplayEnabled = $state(musicPlayerConfig.autoplay ?? false);

// 当前歌曲信息
let currentSong: MusicPlayerTrack = $state({
    id: 0,
    title: "Music",
    artist: "Artist",
    cover: "/favicon/icon-light.ico",
    url: "",
    duration: 0,
});
let playlist: MusicPlayerTrack[] = $state([]);
let currentIndex = $state(0);
let audio: HTMLAudioElement | undefined = $state();
let progressBar: HTMLElement | undefined = $state();
let volumeBar: HTMLElement | undefined = $state();

// 是否正在播放
let isPlaying = $state(false);
// 是否应该播放（用于切换歌曲时的自动播放）
let shouldPlay = $state(false);
// 是否折叠播放器
let isCollapsed = $state(true);
// 是否显示播放列表
let showPlaylist = $state(false);
// 当前播放时间
let currentTime = $state(0);
// 歌曲总时长
let duration = $state(0);
// 音量
let volume = $state(0.15);
// 是否静音
let isMuted = $state(false);
// 是否正在加载
let isLoading = $state(false);
// 是否随机播放
let isShuffled = $state(false);
// 循环模式，0: 不循环, 1: 单曲循环, 2: 列表循环
let isRepeating = $state(0);
// 待恢复的进度
let pendingProgress = $state(0);
// 上次保存进度的时间，用于节流
let lastSaveTime = 0;
// 错误信息
let errorMessage = $state("");
// 是否显示错误信息
let showError = $state(false);

// 存储键名常量
const STORAGE_KEYS = {
    USER_PAUSED: "player_user_paused",
    VOLUME: "player_volume",
    SHUFFLE: "player_shuffle",
    REPEAT: "player_repeat",
    LAST_SONG_ID: "player_last_song_id",
    LAST_SONG_PROGRESS: "player_last_song_progress",
};

function restoreLastSong() {
    if (playlist.length === 0) return;

    if (typeof localStorage !== 'undefined') {
        const lastId = localStorage.getItem(STORAGE_KEYS.LAST_SONG_ID);
        let index = -1;
        // 优先通过 ID 匹配
        if (lastId) {
            index = playlist.findIndex(s => s.id !== undefined && String(s.id) === String(lastId));
        }
        if (index !== -1) {
            currentIndex = index;
            // 获取保存的进度
            const savedProgress = localStorage.getItem(STORAGE_KEYS.LAST_SONG_PROGRESS);
            if (savedProgress) {
                pendingProgress = parseFloat(savedProgress);
            }
            loadSong(playlist[currentIndex]);
            return;
        }
    }
    // 如果没有找到上次播放的歌曲，或者没有记录，加载第一首
    currentIndex = 0;
    loadSong(playlist[0]);
}

function showErrorMessage(message: string) {
    errorMessage = message;
    showError = true;
    setTimeout(() => {
        showError = false;
    }, 3000);
}

async function fetchMetingPlaylist() {
    if (!meting_api || !meting_id) return;
    isLoading = true;
    const query = new URLSearchParams({
        server: meting_server,
        type: meting_type,
        id: meting_id,
    });
    const separator = meting_api.includes("?") ? "&" : "?";
    const apiUrl = `${meting_api}${separator}${query.toString()}`;
    try {
        const res = await fetch(apiUrl);
        if (!res.ok) throw new Error("meting api error");
        const list = await res.json();
        playlist = list.map((song: any, index: number) => {
            let title = song.name ?? song.title ?? i18n(Key.musicUnknownTrack);
            let artist = song.artist ?? song.author ?? i18n(Key.musicUnknownArtist);
            let dur = song.duration ?? 0;
            if (dur > 10000) dur = Math.floor(dur / 1000);
            if (!Number.isFinite(dur) || dur <= 0) dur = 0;
            return {
                id: song.id ?? `meting-${index}`, // 确保每个歌曲都有 ID
                title,
                artist,
                cover: song.pic ?? "",
                url: song.url ?? "",
                duration: dur,
            };
        });
        if (playlist.length > 0) {
            // 使用 setTimeout 确保 Svelte 响应式变量已更新
            setTimeout(() => {
                restoreLastSong();
            }, 0);
        }
        isLoading = false;
    } catch (e) {
        showErrorMessage(i18n(Key.musicMetingFailed));
        isLoading = false;
    }
}

async function toggleMode() {
    if (!musicPlayerConfig.enable) return;
    mode = mode === "meting" ? "local" : "meting";
    showPlaylist = false;
    isLoading = false;
    isPlaying = false;
    currentIndex = 0;
    playlist = [];
    if (audio) {
        audio.pause();
        audio.currentTime = 0;
    }
    currentTime = 0;
    duration = 0;
    if (mode === "meting") {
        await fetchMetingPlaylist();
    } else {
        playlist = [...(musicPlayerConfig.local?.playlist ?? [])];
        if (playlist.length > 0) {
            setTimeout(() => {
                restoreLastSong();
            }, 0);
        } else {
            showErrorMessage(i18n(Key.musicEmptyPlaylist));
        }
    }
}

function togglePlay() {
    if (!audio || !currentSong.url) return;
    if (isPlaying) {
        audio.pause();
        if (typeof localStorage !== 'undefined') {
            localStorage.setItem(STORAGE_KEYS.USER_PAUSED, "true");
        }
    } else {
        audio.play();
        if (typeof localStorage !== 'undefined') {
            localStorage.setItem(STORAGE_KEYS.USER_PAUSED, "false");
        }
    }
}

function toggleCollapse() {
    isCollapsed = !isCollapsed;
    if (isCollapsed) {
        showPlaylist = false;
    }
}

function togglePlaylist() {
    showPlaylist = !showPlaylist;
}

function toggleShuffle() {
    isShuffled = !isShuffled;
    if (isShuffled) {
        isRepeating = 0;
    }
    if (typeof localStorage !== 'undefined') {
        localStorage.setItem(STORAGE_KEYS.SHUFFLE, String(isShuffled));
        localStorage.setItem(STORAGE_KEYS.REPEAT, String(isRepeating));
    }
}

function toggleRepeat() {
    isRepeating = (isRepeating + 1) % 3;
    if (isRepeating !== 0) {
        isShuffled = false;
    }
    if (typeof localStorage !== 'undefined') {
        localStorage.setItem(STORAGE_KEYS.REPEAT, String(isRepeating));
        localStorage.setItem(STORAGE_KEYS.SHUFFLE, String(isShuffled));
    }
}

function previousSong() {
    if (playlist.length <= 1) return;
    const newIndex = currentIndex > 0 ? currentIndex - 1 : playlist.length - 1;
    playSong(newIndex);
}

function nextSong() {
    if (playlist.length <= 1) return;
    let newIndex: number;
    if (isShuffled) {
        do {
            newIndex = Math.floor(Math.random() * playlist.length);
        } while (newIndex === currentIndex && playlist.length > 1);
    } else {
        newIndex = currentIndex < playlist.length - 1 ? currentIndex + 1 : 0;
    }
    playSong(newIndex);
}

function playSong(index: number) {
    if (index < 0 || index >= playlist.length) return;
    currentIndex = index;
    // 用户手动选择歌曲（或自动切换），标记为应该播放
    shouldPlay = true;
    // 用户手动选择歌曲，清除暂停偏好和待恢复进度
     if (typeof localStorage !== 'undefined') {
         localStorage.setItem(STORAGE_KEYS.USER_PAUSED, "false");
     }
    pendingProgress = 0;
    // 加载歌曲
    loadSong(playlist[currentIndex]);
}

function getAssetPath(path: string): string {
    if (path.startsWith("http://") || path.startsWith("https://")) return path;
    if (path.startsWith("/")) return path;
    return `/${path}`;
}

function loadSong(song: MusicPlayerTrack) {
    if (!song || !audio) return;
    currentSong = { ...song };
    // 记录最后播放的歌曲 ID (排除初始化的占位符 ID 0)
    if (typeof localStorage !== 'undefined' && song.id !== undefined && song.id !== 0) {
        localStorage.setItem(STORAGE_KEYS.LAST_SONG_ID, String(song.id));
        // 如果不是恢复进度的情况，重置保存的进度
        if (pendingProgress <= 0) {
            localStorage.setItem(STORAGE_KEYS.LAST_SONG_PROGRESS, "0");
        }
    }
    if (song.url) {
        isLoading = true;
        // 如果有待恢复的进度，先不要重置为 0，以免进度条跳变
        if (pendingProgress > 0) {
            currentTime = pendingProgress;
        } else {
            audio.currentTime = 0;
            currentTime = 0;
        }
        duration = song.duration ?? 0;
        audio.removeEventListener("canplay", handleLoadSuccess);
        audio.removeEventListener("error", handleLoadError);
        audio.removeEventListener("loadstart", handleLoadStart);
        audio.addEventListener("canplay", handleLoadSuccess, { once: true });
        audio.addEventListener("error", handleLoadError, { once: true });
        audio.addEventListener("loadstart", handleLoadStart, { once: true });
        audio.src = getAssetPath(song.url);
        audio.load();
    } else {
        isLoading = false;
    }
}

let autoplayFailed = $state(false);

function handleLoadSuccess() {
    isLoading = false;
    if (audio?.duration && audio.duration > 1) {
        duration = Math.floor(audio.duration);
        if (playlist[currentIndex]) playlist[currentIndex].duration = duration;
        currentSong.duration = duration;
    }
    // 恢复进度
    if (pendingProgress > 0 && audio) {
        // 确保进度不超出总时长
        const targetTime = Math.min(pendingProgress, duration > 0 ? duration : Infinity);
        audio.currentTime = targetTime;
        currentTime = targetTime;
        pendingProgress = 0; // 恢复后清除
    }
    // 如果是自动播放模式，或者当前处于播放状态（如切换歌曲），则尝试播放
    if (isAutoplayEnabled || isPlaying || shouldPlay) {
        const playPromise = audio?.play();
        if (playPromise !== undefined) {
            playPromise.then(() => {
                // 播放成功后，关闭自动播放标记，后续由用户控制
                isAutoplayEnabled = false;
                autoplayFailed = false;
                shouldPlay = false;
            }).catch((error) => {
                showErrorMessage(i18n(Key.musicAutoplayBlocked));
                autoplayFailed = true;
                // 确保 UI 状态为暂停
                isPlaying = false;
                shouldPlay = false;
            });
        }
    }
}

function handleUserInteraction() {
    // 如果自动播放失败且尚未开始播放，则在用户交互时尝试播放
    if (autoplayFailed && audio && !isPlaying) {
        const playPromise = audio.play();
        if (playPromise !== undefined) {
            playPromise.then(() => {
                autoplayFailed = false;
            }).catch(() => {});
        }
    }
}

function handleLoadError(event: Event) {
    isLoading = false;
    showErrorMessage(i18n(Key.musicPlayFailed).replace("{0}", currentSong.title));
    if (playlist.length > 1) setTimeout(() => nextSong(), 1000);
    else showErrorMessage(i18n(Key.musicNoSongsAvailable));
}

function handleLoadStart() {}

function hideError() {
    showError = false;
}

function setProgress(event: MouseEvent) {
    if (!audio || !progressBar) return;
    const rect = progressBar.getBoundingClientRect();
    const percent = (event.clientX - rect.left) / rect.width;
    const newTime = percent * duration;
    audio.currentTime = newTime;
    currentTime = newTime;
}

let isVolumeDragging = $state(false);
let isMouseDown = $state(false);
let volumeBarRect: DOMRect | null = $state(null);
let rafId: number | null = $state(null);

function startVolumeDrag(event: MouseEvent) {
    if (!volumeBar) return;
    isMouseDown = true;
    volumeBarRect = volumeBar.getBoundingClientRect();
    updateVolumeLogic(event.clientX);
}

function handleVolumeMove(event: MouseEvent) {
    if (!isMouseDown) return;
    isVolumeDragging = true;
    if (rafId) return;
    rafId = requestAnimationFrame(() => {
        updateVolumeLogic(event.clientX);
        rafId = null;
    });
}

function stopVolumeDrag() {
    isMouseDown = false;
    isVolumeDragging = false;
    volumeBarRect = null;
    if (rafId) {
        cancelAnimationFrame(rafId);
        rafId = null;
    }
}

function updateVolumeLogic(clientX: number) {
    if (!audio || !volumeBar) return;
    const rect = volumeBarRect || volumeBar.getBoundingClientRect();
    const percent = Math.max(
        0,
        Math.min(1, (clientX - rect.left) / rect.width),
    );
    volume = percent;
    audio.volume = volume;
    isMuted = volume === 0;
    if (typeof localStorage !== 'undefined') {
        localStorage.setItem(STORAGE_KEYS.VOLUME, String(volume));
    }
}

function toggleMute() {
    if (!audio) return;
    isMuted = !isMuted;
    audio.muted = isMuted;
}

function formatTime(seconds: number): string {
    if (!Number.isFinite(seconds) || seconds < 0) return "0:00";
    const mins = Math.floor(seconds / 60);
    const secs = Math.floor(seconds % 60);
    return `${mins}:${secs.toString().padStart(2, "0")}`;
}

function handleAudioEvents() {
    if (!audio) return;
    audio.addEventListener("play", () => {
        isPlaying = true;
        autoplayFailed = false;
        isAutoplayEnabled = false;
        if (typeof localStorage !== 'undefined') {
            localStorage.setItem(STORAGE_KEYS.USER_PAUSED, "false");
        }
    });
    audio.addEventListener("pause", () => {
        isPlaying = false;
        // 注意：这里不自动设置 userPaused 为 true，因为音频结束或切换也可能触发 pause。（只在 togglePlay 中显式记录用户的暂停操作。）
    });
    audio.addEventListener("timeupdate", () => {
        if (!audio) return;
        currentTime = audio.currentTime;
        // 每 2.1 秒保存一次进度，或者在歌曲接近结束时（虽然结束时可能不需要记忆，但为了保险）
        const now = Date.now();
        if (now - lastSaveTime > 2100) {
            if (typeof localStorage !== 'undefined' && currentSong.id !== 0) {
                localStorage.setItem(STORAGE_KEYS.LAST_SONG_PROGRESS, String(currentTime));
                lastSaveTime = now;
            }
        }
    });
    audio.addEventListener("ended", () => {
        if (!audio) return;
        // 歌曲结束，重置保存的进度
        if (typeof localStorage !== 'undefined') {
            localStorage.setItem(STORAGE_KEYS.LAST_SONG_PROGRESS, "0");
        }
        // 单曲循环时，重置进度到开始
        if (isRepeating === 1) {
            audio.currentTime = 0;
            audio.play().catch(() => {});
        } else if (
            isRepeating === 2 ||
            isShuffled ||
            (isRepeating === 0 && currentIndex < playlist.length - 1)
        ) {
            nextSong();
        } else {
            isPlaying = false;
        }
    });
    audio.addEventListener("error", (event) => {
        isLoading = false;
    });
    audio.addEventListener("stalled", () => {});
    audio.addEventListener("waiting", () => {});
}

const interactionEvents = ['click', 'keydown', 'touchstart'];

onMount(() => {
    // 从缓存中读取用户偏好
    if (typeof localStorage !== 'undefined') {
        const userPaused = localStorage.getItem(STORAGE_KEYS.USER_PAUSED) === "true";
        if (userPaused) {
            isAutoplayEnabled = false;
        }
        const savedVolume = localStorage.getItem(STORAGE_KEYS.VOLUME);
        if (savedVolume !== null) {
            volume = parseFloat(savedVolume);
        }
        const savedShuffle = localStorage.getItem(STORAGE_KEYS.SHUFFLE);
        if (savedShuffle !== null) {
            isShuffled = savedShuffle === "true";
        }
        const savedRepeat = localStorage.getItem(STORAGE_KEYS.REPEAT);
        if (savedRepeat !== null) {
            isRepeating = parseInt(savedRepeat);
        }
    }

    audio = new Audio();
    audio.volume = volume;
    handleAudioEvents();
    interactionEvents.forEach(event => {
        document.addEventListener(event, handleUserInteraction, { capture: true });
    });
    if (!musicPlayerConfig.enable) {
        return;
    }
    if (mode === "meting") {
        fetchMetingPlaylist();
    } else {
        // 使用本地播放列表，不发送任何API请求
        playlist = [...(musicPlayerConfig.local?.playlist ?? [])];
        if (playlist.length > 0) {
            setTimeout(() => {
                restoreLastSong();
            }, 0);
        } else {
            showErrorMessage(i18n(Key.musicEmptyPlaylist));
        }
    }
});

onDestroy(() => {
    if (typeof document !== 'undefined') {
        interactionEvents.forEach(event => {
            document.removeEventListener(event, handleUserInteraction, { capture: true });
        });
    }
    if (audio) {
        audio.pause();
        audio.src = "";
    }
});
</script>

<svelte:window
    onmousemove={handleVolumeMove}
    onmouseup={stopVolumeDrag}
/>

{#if musicPlayerConfig.enable}
{#if showError}
<div class="music-player-error fixed bottom-20 right-4 z-60 max-w-sm onload-animation-up">
    <div class="bg-red-500 text-white px-4 py-3 rounded-lg shadow-lg flex items-center gap-3 animate-slide-up">
        <Icon icon="material-symbols:error" class="text-xl shrink-0" />
        <span class="text-sm flex-1">{errorMessage}</span>
        <button onclick={hideError} class="text-white/80 hover:text-white transition-colors">
            <Icon icon="material-symbols:close" class="text-lg" />
        </button>
    </div>
</div>
{/if}

<div class="music-player fixed bottom-4 right-4 z-101 transition-all duration-300 ease-in-out onload-animation-up flex flex-col items-end pointer-events-none"
     class:expanded={!isCollapsed}
     class:collapsed={isCollapsed}>
    {#if showPlaylist}
        <div class="playlist-panel float-panel w-80 max-h-96 overflow-hidden z-50 mb-4 pointer-events-auto"
             transition:slide={{ duration: 300, axis: 'y' }}>
            <div class="playlist-header flex items-center justify-between p-4 border-b border-(--line-divider)">
                <h3 class="text-lg font-semibold text-90">{i18n(Key.playlist)}</h3>
                <button class="btn-plain w-8 h-8 rounded-lg" onclick={togglePlaylist}>
                    <Icon icon="material-symbols:close" class="text-lg" />
                </button>
            </div>
            <div class="playlist-content overflow-y-auto max-h-80">
                {#each playlist as song, index}
                    <div class="playlist-item flex items-center gap-3 p-3 hover:bg-(--btn-plain-bg-hover) cursor-pointer transition-colors"
                        class:bg-(--btn-plain-bg)={index === currentIndex}
                        class:text-(--primary)={index === currentIndex}
                        onclick={() => playSong(index)}
                        onkeydown={(e) => {
                            if (e.key === 'Enter' || e.key === ' ') {
                                e.preventDefault();
                                playSong(index);
                            }
                        }}
                        role="button"
                        tabindex="0"
                        aria-label="播放 {song.title} - {song.artist}">
                        <div class="w-6 h-6 flex items-center justify-center">
                            {#if index === currentIndex && isPlaying}
                                <Icon icon="material-symbols:graphic-eq" class="text-(--primary) animate-pulse" />
                            {:else if index === currentIndex}
                                <Icon icon="material-symbols:pause" class="text-(--primary)" />
                            {:else}
                                <span class="text-sm text-(--content-meta)">{index + 1}</span>
                            {/if}
                        </div>
                        <!-- 歌单列表内封面仍为圆角矩形 -->
                        <div class="w-10 h-10 rounded-lg overflow-hidden shrink-0 shadow-sm">
                            <img src={getAssetPath(song.cover)} alt={song.title} class="w-full h-full object-cover" />
                        </div>
                        <div class="flex-1 min-w-0">
                            <div class="font-medium truncate" class:text-(--primary)={index === currentIndex} class:text-90={index !== currentIndex}>
                                {song.title}
                            </div>
                            <div class="text-sm text-(--content-meta) truncate" class:text-(--primary)={index === currentIndex}>
                                {song.artist}
                            </div>
                        </div>
                    </div>
                {/each}
            </div>
        </div>
    {/if}
    <!-- 折叠状态的小圆球 -->
    <div class="orb-player w-12 h-12 bg-(--primary) rounded-full shadow-lg cursor-pointer transition-all duration-500 ease-in-out flex items-center justify-center hover:scale-110 active:scale-95"
         class:opacity-0={!isCollapsed}
         class:scale-0={!isCollapsed}
         class:pointer-events-auto={isCollapsed}
         class:pointer-events-none={!isCollapsed}
         onclick={toggleCollapse}
         onkeydown={(e) => {
            if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                toggleCollapse();
            }
         }}
         role="button"
         tabindex="0"
         aria-label={i18n(Key.musicExpand)}>
        {#if isLoading}
            <Icon icon="eos-icons:loading" class="text-white text-lg" />
        {:else if isPlaying}
            <div class="flex space-x-0.5">
                <div class="w-0.5 h-3 bg-white rounded-full animate-pulse"></div>
                <div class="w-0.5 h-4 bg-white rounded-full animate-pulse" style="animation-delay: 150ms;"></div>
                <div class="w-0.5 h-2 bg-white rounded-full animate-pulse" style="animation-delay: 300ms;"></div>
            </div>
        {:else}
            <Icon icon="material-symbols:music-note" class="text-white text-lg" />
        {/if}
    </div>
    <!-- 展开状态的完整播放器（封面圆形） -->
    <div class="expanded-player card-base bg-(--float-panel-bg) shadow-xl rounded-2xl p-4 transition-all duration-500 ease-in-out"
         class:opacity-0={isCollapsed}
         class:scale-95={isCollapsed}
         class:pointer-events-auto={!isCollapsed}
         class:pointer-events-none={isCollapsed}>
        <div class="flex items-center gap-4 mb-4">
            <div class="cover-container relative w-16 h-16 rounded-full overflow-hidden shrink-0">
                <img src={getAssetPath(currentSong.cover)} alt="封面"
                     class="w-full h-full object-cover transition-transform duration-300"
                     class:spinning={isPlaying && !isLoading}
                     class:animate-pulse={isLoading} />
            </div>
            <div class="flex-1 min-w-0">
                <div class="song-title text-lg font-bold text-90 truncate mb-1">{currentSong.title}</div>
                <div class="song-artist text-sm text-50 truncate">{currentSong.artist}</div>
                <div class="text-xs text-30 mt-1">
                    {formatTime(currentTime)} / {formatTime(duration)}
                </div>
            </div>
            <div class="flex items-center gap-1">
                <button class="btn-plain w-8 h-8 rounded-lg flex items-center justify-center"
                        onclick={toggleMode}
                        title={mode === "meting" ? i18n(Key.musicSwitchToLocal) : i18n(Key.musicSwitchToMeting)}>
                    <Icon icon={mode === "meting" ? "material-symbols:cloud" : "material-symbols:folder"} class="text-lg" />
                </button>
                <button class="btn-plain w-8 h-8 rounded-lg flex items-center justify-center"
                        class:text-(--primary)={showPlaylist}
                        onclick={togglePlaylist}
                        title={i18n(Key.playlist)}>
                    <Icon icon="material-symbols:queue-music" class="text-lg" />
                </button>
            </div>
        </div>
        <div class="progress-section mb-4">
            <div class="progress-bar flex-1 h-2 bg-(--btn-regular-bg) rounded-full cursor-pointer"
                bind:this={progressBar}
                onclick={setProgress}
                onkeydown={(e) => {
                    if (e.key === 'Enter' || e.key === ' ') {
                        e.preventDefault();
                        const rect = progressBar?.getBoundingClientRect();
                        if (rect) {
                            const percent = 0.5;
                            const newTime = percent * duration;
                            if (audio) {
                                audio.currentTime = newTime;
                                currentTime = newTime;
                            }
                        }
                    }
                }}
                role="slider"
                tabindex="0"
                aria-label={i18n(Key.musicProgress)}
                aria-valuemin="0"
                aria-valuemax="100"
                aria-valuenow={duration > 0 ? (currentTime / duration * 100) : 0}>
                <div class="h-full bg-(--primary) rounded-full transition-all duration-100"
                    style="width: {duration > 0 ? (currentTime / duration) * 100 : 0}%">
                </div>
            </div>
        </div>
        <div class="controls flex items-center justify-center gap-2 mb-4">
            <!-- 随机按钮高亮 -->
            <button class="w-10 h-10 rounded-lg"
                    class:btn-regular={isShuffled}
                    class:btn-plain={!isShuffled}
                    onclick={toggleShuffle}
                    disabled={playlist.length <= 1}>
                <Icon icon="material-symbols:shuffle" class="text-lg" />
            </button>
            <button class="btn-plain w-10 h-10 rounded-lg" onclick={previousSong}
                    disabled={playlist.length <= 1}>
                <Icon icon="material-symbols:skip-previous" class="text-xl" />
            </button>
            <button class="btn-regular w-12 h-12 rounded-full"
                    class:opacity-50={isLoading}
                    disabled={isLoading}
                    onclick={togglePlay}>
                {#if isLoading}
                    <Icon icon="eos-icons:loading" class="text-xl" />
                {:else if isPlaying}
                    <Icon icon="material-symbols:pause" class="text-xl" />
                {:else}
                    <Icon icon="material-symbols:play-arrow" class="text-xl" />
                {/if}
            </button>
            <button class="btn-plain w-10 h-10 rounded-lg" onclick={nextSong}
                    disabled={playlist.length <= 1}>
                <Icon icon="material-symbols:skip-next" class="text-xl" />
            </button>
            <!-- 循环按钮高亮 -->
            <button class="w-10 h-10 rounded-lg"
                    class:btn-regular={isRepeating > 0}
                    class:btn-plain={isRepeating === 0}
                    onclick={toggleRepeat}>
                {#if isRepeating === 1}
                    <Icon icon="material-symbols:repeat-one" class="text-lg" />
                {:else if isRepeating === 2}
                    <Icon icon="material-symbols:repeat" class="text-lg" />
                {:else}
                    <Icon icon="material-symbols:repeat" class="text-lg opacity-50" />
                {/if}
            </button>
        </div>
        <div class="bottom-controls flex items-center gap-2">
            <button class="btn-plain w-8 h-8 rounded-lg" onclick={toggleMute}>
                {#if isMuted || volume === 0}
                    <Icon icon="material-symbols:volume-off" class="text-lg" />
                {:else if volume < 0.5}
                    <Icon icon="material-symbols:volume-down" class="text-lg" />
                {:else}
                    <Icon icon="material-symbols:volume-up" class="text-lg" />
                {/if}
            </button>
            <div class="flex-1 h-2 bg-(--btn-regular-bg) rounded-full cursor-pointer"
                bind:this={volumeBar}
                onmousedown={startVolumeDrag}
                onkeydown={(e) => {
                    if (e.key === 'Enter' || e.key === ' ') {
                        e.preventDefault();
                        if (e.key === 'Enter') toggleMute();
                    }
                }}
                role="slider"
                tabindex="0"
                aria-label={i18n(Key.musicVolume)}
                aria-valuemin="0"
                aria-valuemax="100"
                aria-valuenow={volume * 100}>
                <div class="h-full bg-(--primary) rounded-full transition-all"
                    class:duration-100={!isVolumeDragging}
                    class:duration-0={isVolumeDragging}
                    style="width: {volume * 100}%">
                </div>
            </div>
            <button class="btn-plain w-8 h-8 rounded-lg flex items-center justify-center"
                    onclick={toggleCollapse}
                    title={i18n(Key.musicCollapse)}>
                <Icon icon="material-symbols:expand-more" class="text-lg" />
            </button>
        </div>
    </div>
</div>

{/if}