(() => {
    let songs, audio, currentIndex = 0;
    let floatingButton, progressRing, playerPanel, coverImg, popupBgImg, animationFrameId;
    let lyricLines = [];
    let isPlayerClosed = false;

    const playlistApiUrl = "https://api.i-meto.com/meting/api?server=netease&type=playlist&id=8034031191";

    // =========================
    // 工具
    // =========================
    const getRandomSongIndex = () => {
        if (!songs || !songs.length) return 0;
        return Math.floor(Math.random() * songs.length);
    };

    const getCoverSrc = () => {
        if (!songs || !songs.length) return "/logo.webp";
        const pic = songs[currentIndex % songs.length]?.pic;
        return pic?.trim() ? pic.trim() : "/logo.webp";
    };

    const setPopupBackground = (src) => {
        if (!popupBgImg) return;

        const fallback = "/logo.webp";
        const nextSrc = src?.trim() ? src.trim() : fallback;
        popupBgImg.src = nextSrc;
    };

    // =========================
    // 封面
    // =========================
    const setCover = () => {
        if (!coverImg) return;
        const cover = getCoverSrc();
        coverImg.src = cover;
        setPopupBackground(cover);
    };

    // =========================
    // audio
    // =========================
    const initAudio = () => {
        if (!audio) {
            audio = new Audio();
            audio.volume = 0.5;

            audio.onplay = () => { syncUI(); setRotate(); };
            audio.onpause = () => { syncUI(); setRotate(); };
            audio.onended = () => next();
        }
    };

    // =========================
    // LRC解析
    // =========================
    const parseLrc = (text) => {
        const lines = text.split("\n");
        const res = [];
        const reg = /\[(\d{2}):(\d{2})\.(\d{2,3})\]/;

        for (let line of lines) {
            const timeMatch = line.match(reg);
            if (!timeMatch) continue;

            const time =
                (+timeMatch[1]) * 60 +
                (+timeMatch[2]) +
                (+timeMatch[3]) / (timeMatch[3].length === 3 ? 1000 : 100);

            const txt = line.replace(reg, "").trim();
            if (txt) res.push({ time, text: txt });
        }

        return res.sort((left, right) => left.time - right.time);
    };

    // =========================
    // 歌词渲染
    // =========================
    const renderLrc = (top, mid, bottom) => {
        const box = playerPanel?.querySelector(".lrc");
        if (!box) return;

        box.innerHTML = `
        <div style="opacity:.4;font-size:12px;line-height:1.2;min-height:16px">${top}</div>
        <div style="font-size:14px;font-weight:600;margin:2px 0;line-height:1.2;min-height:18px">${mid}</div>
        <div style="opacity:.4;font-size:12px;line-height:1.2;min-height:16px">${bottom}</div>
    `;
    };

    const renderLoadingLrc = () => {
        renderLrc("加", "载", "中");
    };

    // =========================
    // loading歌词
    // =========================
    const loadLyric = (song) => {
        lyricLines = [];

        renderLoadingLrc();

        if (!song?.lrc) {
            renderLrc("-", "暂无歌词", "-");
            return;
        }

        fetch(song.lrc)
            .then(response => response.text())
            .then(text => {
                lyricLines = parseLrc(text);
            })
            .catch(() => {
                lyricLines = [];
                renderLrc("-", "加载失败", "-");
            });
    };

    // =========================
    // load song
    // =========================
    const loadSong = () => {
        if (!songs || !songs.length) return;

        const currentSong = songs[currentIndex % songs.length];
        initAudio();

        audio.src = currentSong.url;
        loadLyric(currentSong);
    };

    // =========================
    // UI（标题）
    // =========================
    const syncUI = () => {
        if (!playerPanel) return;

        const titleBox = playerPanel.querySelector(".t");
        if (!titleBox) return;

        const currentSong = songs?.length ? songs[currentIndex % songs.length] : null;

        titleBox.innerHTML = `
        <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:6px">
            <div style="flex:1;line-height:1.2">
                <div style="font-size:13px">${currentSong?.title || "加载中"}</div>
                <div style="font-size:11px;opacity:.7;margin-top:2px">${currentSong?.author || "请稍候"}</div>
            </div>

            <div style="display:flex;gap:6px;align-items:center;flex-shrink:0;">
                <button class="minPlayerBtn" style="
                    width:24px;height:24px;
                    border:none;
                    border-radius:6px;
                    background:rgba(255,255,255,.08);
                    color:#fff;
                    font-size:14px;
                    cursor:pointer;
                ">−</button>

                <button class="closePlayerBtn" style="
                    width:24px;height:24px;
                    border:none;
                    border-radius:6px;
                    background:rgba(255,255,255,.08);
                    color:#fff;
                    font-size:14px;
                    cursor:pointer;
                ">×</button>
            </div>
        </div>
    `;

        const isPlaying = audio && !audio.paused;
        playerPanel.querySelector(".pp").textContent = isPlaying ? "暂停" : "播放";

        // 关闭（彻底关闭）
        titleBox.querySelector(".closePlayerBtn").onclick = (event) => {
            event.stopPropagation();

            if (audio) {
                audio.pause();
                audio.src = "";
            }

            isPlayerClosed = true;

            floatingButton.style.display = "none";
            playerPanel.style.display = "none";
        };

        // 最小化（只收起面板）
        titleBox.querySelector(".minPlayerBtn").onclick = (event) => {
            event.stopPropagation();
            if (playerPanel) playerPanel.style.display = "none";
        };
    };

    // =========================
    // rotate
    // =========================
    const setRotate = () => {
        if (!coverImg) return;
        coverImg.style.animationPlayState = (audio && !audio.paused) ? "running" : "paused";
    };

    // =========================
    // 歌词更新
    // =========================
    const updateLrc = () => {
        if (!lyricLines.length || !audio) return;

        const currentTime = audio.currentTime;

        let lyricIndex = 0;
        for (let lyricLineIndex = 0; lyricLineIndex < lyricLines.length; lyricLineIndex++) {
            if (currentTime >= lyricLines[lyricLineIndex].time) lyricIndex = lyricLineIndex;
            else break;
        }

        renderLrc(
            lyricLines[lyricIndex - 1]?.text || "-",
            lyricLines[lyricIndex]?.text || "-",
            lyricLines[lyricIndex + 1]?.text || "-"
        );
    };

    // =========================
    // progress
    // =========================
    const progress = () => {
        if (!audio || !audio.duration) return;

        const progressPercent = audio.currentTime / audio.duration;

        progressRing.style.background =
            `conic-gradient(#fff ${progressPercent * 360}deg,rgba(255,255,255,.15) 0)`;

        const seek = playerPanel?.querySelector(".seek");
        if (seek && !seek.matches(":active")) {
            seek.value = Math.floor(progressPercent * 1000);
        }

        updateLrc();
    };

    // =========================
    // play / pause / next
    // =========================
    const play = async () => {
        initAudio();
        if (!audio.src) loadSong();

        try { await audio.play(); } catch { }

        syncUI();
        setRotate();

        cancelAnimationFrame(animationFrameId);
        loop();
    };

    const pause = () => {
        if (audio) audio.pause();
        syncUI();
        setRotate();
    };

    const next = () => {
        if (!songs || !songs.length) return;

        let newIndex = getRandomSongIndex();
        if (songs.length > 1) {
            while (newIndex === currentIndex) newIndex = getRandomSongIndex();
        }

        currentIndex = newIndex;

        const currentSong = songs[currentIndex % songs.length];

        loadSong();
        syncUI();
        setRotate();
        setCover();

        loadLyric(currentSong);

        audio.play().catch(() => { });
    };

    // =========================
    // volume
    // =========================
    const volUp = () => {
        if (!audio) return;
        audio.volume = Math.min(1, audio.volume + 0.1);
    };

    const volDown = () => {
        if (!audio) return;
        audio.volume = Math.max(0, audio.volume - 0.1);
    };

    // =========================
    // loop
    // =========================
    const loop = () => {
        progress();
        animationFrameId = requestAnimationFrame(loop);
    };

    // =========================
    // UI init
    // =========================
    const initUI = () => {
        floatingButton = document.createElement("div");
        floatingButton.style.cssText =
            "position:fixed;right:18px;bottom:18px;width:58px;height:58px;border-radius:50%;background:#111;z-index:99999;display:flex;align-items:center;justify-content:center;cursor:pointer;overflow:hidden";

        progressRing = document.createElement("div");
        progressRing.style.cssText =
            "position:absolute;inset:0;border-radius:50%;background:conic-gradient(rgba(255,255,255,.15) 0deg,transparent 0);z-index:0";

        coverImg = document.createElement("img");
        coverImg.src = "/logo.webp";
        coverImg.style.cssText =
            "width:46px;height:46px;border-radius:50%;object-fit:cover;z-index:2;position:relative;animation:spin 6s linear infinite;animation-play-state:paused";

        floatingButton.appendChild(progressRing);
        floatingButton.appendChild(coverImg);

        playerPanel = document.createElement("div");
        playerPanel.style.cssText =
            "position:fixed;right:18px;bottom:90px;width:240px;background:#000;color:#fff;border-radius:12px;display:none;z-index:99999;overflow:hidden";

        playerPanel.innerHTML = `
<div class="t"></div>
<div class="lrc" style="margin:10px 0 8px 0;text-align:center"></div>
<input class="seek" type="range" min="0" max="1000" value="0"
style="width:100%;margin:0 0 8px 0;accent-color:#fff">
<div style="display:flex;justify-content:space-evenly;align-items:center">
<button class="pp">播放</button>
<button class="cc">切歌</button>
<button class="vu">音量+</button>
<button class="vd">音量-</button>
</div>`;

        const popupBg = document.createElement("img");
        popupBg.className = "popupBg";
        popupBg.alt = "";

        const popupShade = document.createElement("div");
        popupShade.className = "popupShade";

        const popupContent = document.createElement("div");
        popupContent.className = "popupContent";

        while (playerPanel.firstChild) popupContent.appendChild(playerPanel.firstChild);

        playerPanel.appendChild(popupBg);
        playerPanel.appendChild(popupShade);
        playerPanel.appendChild(popupContent);

        popupBgImg = popupBg;
        setPopupBackground("/logo.webp");

        document.body.appendChild(floatingButton);
        document.body.appendChild(playerPanel);

        const style = document.createElement("style");
        style.textContent = `
@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

button {
    transition: transform .05s ease, background .05s ease;
}

button:active {
    transform: scale(0.92);
}

.popupBg {
    position:absolute;
    inset:0;
    width:100%;
    height:100%;
    object-fit:cover;
    z-index:0;
}

.popupShade {
    position:absolute;
    inset:0;
    background:rgba(0,0,0,.58);
    z-index:1;
}

.popupContent {
    position:relative;
    z-index:2;
    padding:10px;
}
`;
        document.head.appendChild(style);

        floatingButton.onclick = () => {
            if (isPlayerClosed) return;
            playerPanel.style.display = playerPanel.style.display === "none" ? "block" : "none";
        };

        playerPanel.querySelector(".pp").onclick = (event) => {
            event.stopPropagation();
            if (!audio || audio.paused) play();
            else pause();
        };

        playerPanel.querySelector(".cc").onclick = () => next();
        playerPanel.querySelector(".vu").onclick = () => volUp();
        playerPanel.querySelector(".vd").onclick = () => volDown();

        const seek = playerPanel.querySelector(".seek");
        seek.addEventListener("input", () => {
            if (!audio || !audio.duration) return;
            audio.currentTime = (seek.value / 1000) * audio.duration;
        });

        setInterval(progress, 100);
    };

    // =========================
    // init
    // =========================
    initUI();

    renderLoadingLrc();
    syncUI();

    fetch(playlistApiUrl)
        .then(response => response.json())
        .then(responseSongs => {
            songs = responseSongs;

            if (songs && songs.length) {
                currentIndex = getRandomSongIndex();

                setCover();
                syncUI();

                loadSong();
            } else {
                syncUI();
            }
        });

})();
