import { SongType, PlayModeType } from "@/types/main";
import type { MessageReactive } from "naive-ui";
import { Howl, Howler } from "howler";
import { cloneDeep } from "lodash-es";
import { useMusicStore, useStatusStore, useDataStore, useSettingStore } from "@/stores";
import { useIntervalFn } from "@vueuse/core";
import { calculateProgress } from "./time";
import { shuffleArray, runIdle, handleSongQuality } from "./helper";
import { heartRateList } from "@/api/playlist";
import { formatSongsList } from "./format";
import { isLogin } from "./auth";
import { openUserLogin } from "./modal";
import { personalFm, personalFmToTrash } from "@/api/rec";
import {
  getCoverColor,
  getOnlineUrl,
  getPlayerInfo,
  getPlaySongData,
  getUnlockSongUrl,
  getNextSongUrl,
  NextPrefetchSong,
} from "./player-utils/song";
import { isDev, isElectron } from "./env";
// import { getLyricData } from "./player-utils/lyric";
import audioContextManager from "@/utils/player-utils/context";
import lyricManager from "./lyricManager";
import blob from "./blob";
import { IFormat } from "music-metadata";

/* *允许播放格式 */
const allowPlayFormat = ["mp3", "flac", "webm", "ogg", "wav"];

/**
 * 播放器核心
 * Howler.js 音频库
 */
class Player {
  /** 播放器 */
  private player: Howl;
  /** 定时器 */
  private readonly playerInterval = useIntervalFn(
    () => {
      if (!this.player?.playing()) return;
      const musicStore = useMusicStore();
      const statusStore = useStatusStore();
      const settingStore = useSettingStore();
      const currentTime = this.getSeek();
      const duration = this.getDuration();
      // 计算进度条距离
      const progress = calculateProgress(currentTime, duration);
      // 计算歌词索引（支持 LRC 与逐字 YRC，对唱重叠处理）
      const lyricIndex = lyricManager.calculateLyricIndex(currentTime);
      // 更新状态
      statusStore.$patch({ currentTime, duration, progress, lyricIndex });
      // 客户端事件
      if (isElectron) {
        // 歌词变化
        window.electron.ipcRenderer.send(
          "play-lyric-change",
          cloneDeep({
            lyricIndex,
            currentTime,
            songId: musicStore.playSong?.id,
            songOffset: statusStore.getSongOffset(musicStore.playSong?.id),
          }),
        );
        // 进度条
        if (settingStore.showTaskbarProgress) {
          window.electron.ipcRenderer.send("set-bar", progress);
        }
      }
    },
    250,
    { immediate: false },
  );
  /** 自动关闭定时器 */
  private autoCloseInterval: ReturnType<typeof setInterval> | undefined;
  /** 频谱数据 */
  private audioContext: AudioContext | null = null;
  private analyser: AnalyserNode | null = null;
  private dataArray: Uint8Array<ArrayBuffer> | null = null;
  /** 其他数据 */
  private message: MessageReactive | null = null;
  /** 预载下一首歌曲播放地址缓存（仅存 URL，不创建 Howl） */
  private nextPrefetch: NextPrefetchSong = null;
  /** 当前曲目重试信息（按歌曲维度计数） */
  private retryInfo: { songId: number; count: number } = { songId: 0, count: 0 };
  constructor() {
    // 创建播放器实例
    this.player = new Howl({ src: [""], format: allowPlayFormat, autoplay: false });
    // 初始化媒体会话
    this.initMediaSession();
    // 挂载全局
    window.$player = this;
  }
  /**
   * 重置底层播放器与定时器（幂等）
   */
  private resetPlayerCore() {
    try {
      // 仅卸载当前播放器实例
      if (this.player) {
        this.player.stop();
        this.player.off();
        this.player.unload();
      }
      Howler.unload();
    } catch {
      /* empty */
    }
    this.cleanupAllTimers();
  }
  /**
   * 创建播放器
   * @param src 播放地址
   * @param autoPlay 是否自动播放
   * @param seek 播放位置
   */
  private async createPlayer(src: string, autoPlay: boolean = true, seek: number = 0) {
    // 获取数据
    const dataStore = useDataStore();
    const musicStore = useMusicStore();
    const statusStore = useStatusStore();
    const settingStore = useSettingStore();
    // 播放信息
    const { id, path, type } = musicStore.playSong;
    // 统一重置底层播放器
    this.resetPlayerCore();
    // 创建播放器
    this.player = new Howl({
      src,
      format: allowPlayFormat,
      html5: true,
      autoplay: false,
      preload: "metadata",
      pool: 1,
      volume: statusStore.playVolume,
      rate: statusStore.playRate,
    });
    // 播放器事件
    this.playerEvent({ seek });
    // 播放设备
    if (!settingStore.showSpectrums) this.toggleOutputDevice();
    // 自动播放
    if (autoPlay) await this.play();
    // 获取歌词数据
    lyricManager.handleLyric(id, path);
    // 新增播放历史
    if (type !== "radio") dataStore.setHistory(musicStore.playSong);
    // 获取歌曲封面主色
    if (!path) runIdle(() => getCoverColor(musicStore.songCover));
    // 更新 MediaSession
    if (!path) this.updateMediaSession();
    // 开发模式
    if (isDev) window.player = this.player;
    // 预载下一首播放地址
    this.nextPrefetch = await getNextSongUrl();
  }
  /**
   * 播放器事件
   */
  private playerEvent(
    options: {
      // 恢复进度
      seek?: number;
    } = { seek: 0 },
  ) {
    // 获取数据
    const dataStore = useDataStore();
    const statusStore = useStatusStore();
    const settingStore = useSettingStore();
    const playSongData = getPlaySongData();
    // 获取配置
    const { seek } = options;
    // 初次加载
    this.player.once("load", () => {
      // 允许跨域
      if (settingStore.showSpectrums) {
        const audioDom = this.getAudioDom();
        if (audioDom) audioDom.crossOrigin = "anonymous";
      }
      // 恢复均衡器：如持久化为开启，则在音频节点可用后立即构建 EQ 链
      if (isElectron && statusStore.eqEnabled) {
        try {
          this.enableEq({ bands: statusStore.eqBands });
        } catch {
          /* empty */
        }
      }
      // 恢复进度（仅在明确指定且大于0时才恢复，避免切换歌曲时意外恢复进度）
      if (seek && seek > 0) {
        const duration = this.getDuration();
        // 确保恢复的进度有效且距离歌曲结束大于2秒
        if (duration && seek < duration - 2000) {
          this.setSeek(seek);
        }
      }
      // 更新状态
      statusStore.playLoading = false;
      // 重置当前曲目重试计数
      try {
        const current = getPlaySongData();
        const sid = current?.type === "radio" ? current?.dj?.id : current?.id;
        this.retryInfo = { songId: Number(sid || 0), count: 0 };
      } catch {
        /* empty */
      }
      // ipc
      if (isElectron) {
        window.electron.ipcRenderer.send("play-song-change", getPlayerInfo());
        window.electron.ipcRenderer.send(
          "like-status-change",
          dataStore.isLikeSong(playSongData?.id || 0),
        );
      }
    });
    // 播放
    this.player.on("play", () => {
      window.document.title = getPlayerInfo() || "SPlayer";
      this.playerInterval.resume();
      // 重置重试计数
      try {
        const current = getPlaySongData();
        const sid = current?.type === "radio" ? current?.dj?.id : current?.id;
        this.retryInfo = { songId: Number(sid || 0), count: 0 };
      } catch {
        /* empty */
      }
      // ipc
      if (isElectron) {
        window.electron.ipcRenderer.send("play-status-change", true);
        window.electron.ipcRenderer.send("play-song-change", getPlayerInfo());
      }
      console.log("▶️ song play:", playSongData);
    });
    // 暂停
    this.player.on("pause", () => {
      if (!isElectron) window.document.title = "SPlayer";
      this.playerInterval.pause();
      // ipc
      if (isElectron) {
        window.electron.ipcRenderer.send("play-status-change", false);
      }
      console.log("⏸️ song pause:", playSongData);
    });
    // 结束
    this.player.on("end", () => {
      this.playerInterval.pause();
      // statusStore.playStatus = false;
      console.log("⏹️ song end:", playSongData);
      // 检查是否需要在歌曲结束时执行自动关闭
      const statusStore = useStatusStore();
      if (
        statusStore.autoClose.enable &&
        statusStore.autoClose.waitSongEnd &&
        statusStore.autoClose.remainTime <= 0
      ) {
        // 执行自动关闭
        this.executeAutoClose();
        return;
      }
      this.nextOrPrev("next", true, true);
    });
    // 错误
    this.player.on("loaderror", (sourceid, err: unknown) => {
      const code = typeof err === "number" ? err : undefined;
      this.handlePlaybackError(code);
      console.error("❌ song error:", sourceid, playSongData, err);
    });
    this.player.on("playerror", (sourceid, err: unknown) => {
      const code = typeof err === "number" ? err : undefined;
      this.handlePlaybackError(code);
      console.error("❌ song play error:", sourceid, playSongData, err);
    });
  }
  /**
   * 初始化 MediaSession
   */
  private initMediaSession() {
    if (!("mediaSession" in navigator)) return;
    navigator.mediaSession.setActionHandler("play", () => this.play());
    navigator.mediaSession.setActionHandler("pause", () => this.pause());
    navigator.mediaSession.setActionHandler("previoustrack", () => this.nextOrPrev("prev"));
    navigator.mediaSession.setActionHandler("nexttrack", () => this.nextOrPrev("next"));
    // 跳转进度
    navigator.mediaSession.setActionHandler("seekto", (event) => {
      if (event.seekTime) this.setSeek(event.seekTime);
    });
  }
  /**
   * 更新 MediaSession
   */
  private updateMediaSession() {
    if (!("mediaSession" in navigator)) return;
    const musicStore = useMusicStore();
    const settingStore = useSettingStore();
    // 获取播放数据
    const playSongData = getPlaySongData();
    if (!playSongData) return;
    // 播放状态
    const isRadio = playSongData.type === "radio";
    // 获取数据
    const metaData: MediaMetadataInit = {
      title: playSongData.name,
      artist: isRadio
        ? "播客电台"
        : // 非本地歌曲且歌手列表为数组
          Array.isArray(playSongData.artists)
          ? playSongData.artists.map((item) => item.name).join(" / ")
          : String(playSongData.artists),
      album: isRadio
        ? "播客电台"
        : // 是否为对象
          typeof playSongData.album === "object"
          ? playSongData.album.name
          : String(playSongData.album),
      artwork: settingStore.smtcOutputHighQualityCover
        ? [
            {
              src: musicStore.getSongCover("xl"),
              sizes: "1920x1920",
              type: "image/jpeg",
            },
          ]
        : [
            {
              src: musicStore.getSongCover("cover"),
              sizes: "512x512",
              type: "image/jpeg",
            },
            {
              src: musicStore.getSongCover("s"),
              sizes: "100x100",
              type: "image/jpeg",
            },
            {
              src: musicStore.getSongCover("m"),
              sizes: "300x300",
              type: "image/jpeg",
            },
            {
              src: musicStore.getSongCover("l"),
              sizes: "1024x1024",
              type: "image/jpeg",
            },
            {
              src: musicStore.getSongCover("xl"),
              sizes: "1920x1920",
              type: "image/jpeg",
            },
          ],
    };
    // 更新数据
    navigator.mediaSession.metadata = new window.MediaMetadata(metaData);
  }
  // 生成频谱数据
  private generateSpectrumData() {
    const statusStore = useStatusStore();
    if (!this.analyser || !this.dataArray) {
      this.initSpectrumData();
    }
    // 更新频谱数据
    const updateSpectrumData = () => {
      if (this.analyser && this.dataArray) {
        this.analyser.getByteFrequencyData(this.dataArray);
        // 保存数据
        statusStore.spectrumsData = Array.from(this.dataArray);
      }
      requestAnimationFrame(updateSpectrumData);
    };
    updateSpectrumData();
  }
  /**
   * 集中处理播放错误与重试策略
   */
  private async handlePlaybackError(errCode?: number) {
    const dataStore = useDataStore();
    const playSongData = getPlaySongData();
    const currentSongId = playSongData?.type === "radio" ? playSongData.dj?.id : playSongData?.id;
    // 初始化/切换曲目时重置计数
    if (!this.retryInfo.songId || this.retryInfo.songId !== Number(currentSongId || 0)) {
      this.retryInfo = { songId: Number(currentSongId || 0), count: 0 };
    }
    this.retryInfo.count += 1;
    // 错误码 2：资源过期或临时网络错误，允许较少次数的刷新
    if (errCode === 2 && this.retryInfo.count <= 2) {
      await this.initPlayer(true, this.getSeek());
      return;
    }
    // 其它错误：最多 3 次
    if (this.retryInfo.count <= 3) {
      await this.initPlayer(true, 0);
      return;
    }
    // 超过次数：切到下一首或清空
    this.retryInfo.count = 0;
    if (dataStore.playList.length > 1) {
      window.$message.error("当前歌曲播放失败，已跳至下一首");
      await this.nextOrPrev("next");
    } else {
      window.$message.error("当前列表暂无可播放歌曲");
      this.cleanPlayList();
    }
  }
  /**
   * 获取 Audio Dom
   */
  private getAudioDom(): HTMLMediaElement | null {
    try {
      const sounds = (this.player as any)?._sounds;
      const node = sounds && sounds.length ? sounds[0]?._node : null;
      return node || null;
    } catch {
      return null;
    }
  }
  /**
   * 获取本地歌曲元信息
   * @param path 歌曲路径
   */
  private async parseLocalMusicInfo(path: string) {
    try {
      const musicStore = useMusicStore();
      // 获取封面数据
      const coverData = await window.electron.ipcRenderer.invoke("get-music-cover", path);
      if (coverData) {
        const { data, format } = coverData;
        const blobURL = blob.createBlobURL(data, format, path);
        if (blobURL) {
          musicStore.playSong.cover = blobURL;
        }
      } else {
        musicStore.playSong.cover = "/images/song.jpg?assest";
      }
      // 更新媒体会话
      this.updateMediaSession();
      // 获取元数据
      const infoData: { format: IFormat } = await window.electron.ipcRenderer.invoke(
        "get-music-metadata",
        path,
      );
      // 更新音质
      musicStore.playSong.quality = handleSongQuality(infoData.format.bitrate ?? 0);
      // 获取主色
      runIdle(() => getCoverColor(musicStore.playSong.cover));
    } catch (error) {
      window.$message.error("获取本地歌曲元信息失败");
      console.error("Failed to parse local music info:", error);
    }
  }
  /**
   * 重置状态
   */
  resetStatus() {
    const musicStore = useMusicStore();
    const statusStore = useStatusStore();
    const settingStore = useSettingStore();
    // 重置状态
    statusStore.$patch({
      currentTime: 0,
      duration: 0,
      progress: 0,
      lyricIndex: -1,
      playStatus: false,
      playLoading: false,
    });
    musicStore.playPlaylistId = 0;
    musicStore.resetMusicData();
    if (settingStore.showTaskbarProgress) {
      window.electron.ipcRenderer.send("set-bar", "none");
    }
  }
  /**
   * 初始化播放器
   * 核心外部调用
   * @param autoPlay 是否自动播放
   * @param seek 播放位置
   */
  async initPlayer(autoPlay: boolean = true, seek: number = 0) {
    const dataStore = useDataStore();
    const musicStore = useMusicStore();
    const statusStore = useStatusStore();
    const settingStore = useSettingStore();

    try {
      // 获取播放数据
      const playSongData = getPlaySongData();
      if (!playSongData) {
        statusStore.playLoading = false;
        return;
      }
      const { id, dj, path, type } = playSongData;

      // 更改当前播放歌曲
      musicStore.playSong = playSongData;
      statusStore.playLoading = true;

      // 清理旧播放器与计时器
      this.resetPlayerCore();

      // 本地歌曲
      if (path) {
        try {
          await this.createPlayer(`file://${path}`, autoPlay, seek);
          await this.parseLocalMusicInfo(path);
        } catch (err) {
          console.error("播放器初始化错误（本地）：", err);
        }
      }
      // 在线歌曲
      else if (id && (dataStore.playList.length || statusStore.personalFmMode)) {
        // 播放地址
        let playerUrl: string | null = null;

        // 获取歌曲 URL 单独 try-catch
        try {
          const songId = type === "radio" ? dj?.id : id;
          if (!songId) throw new Error("获取歌曲 ID 失败");

          // 使用预载缓存
          const cached = this.nextPrefetch;
          if (cached && cached.id === songId && cached.url) {
            playerUrl = cached.url;
            statusStore.playUblock = cached.ublock;
            statusStore.songQuality = cached.quality;
          } else {
            const canUnlock = isElectron && type !== "radio" && settingStore.useSongUnlock;
            const { url: officialUrl, isTrial, quality } = await getOnlineUrl(songId);
            // 更新音质
            statusStore.songQuality = quality;
            // 更新播放地址
            if (officialUrl && !isTrial) {
              playerUrl = officialUrl;
              statusStore.playUblock = false;
            } else if (canUnlock) {
              const unlockUrl = await getUnlockSongUrl(playSongData);
              if (unlockUrl) {
                playerUrl = unlockUrl;
                statusStore.playUblock = true;
                console.log("🎼 Song unlock successfully:", unlockUrl);
              } else if (officialUrl && isTrial && settingStore.playSongDemo) {
                window.$message.warning("当前歌曲仅可试听，请开通会员后重试");
                playerUrl = officialUrl;
                statusStore.playUblock = false;
              } else {
                playerUrl = null;
              }
            } else {
              playerUrl = null;
            }
          }

          if (!playerUrl) {
            window.$message.error("该歌曲暂无音源，跳至下一首");
            await this.nextOrPrev("next");
            return;
          }
        } catch (err) {
          console.error("❌ 获取歌曲地址出错：", err);
          window.$message.error("获取歌曲地址失败，跳至下一首");
          await this.nextOrPrev("next");
          return;
        }

        // 有有效 URL 才创建播放器
        if (playerUrl) {
          try {
            await this.createPlayer(playerUrl, autoPlay, seek);
          } catch (err) {
            console.error("播放器初始化错误（在线）：", err);
          }
        }
      }
    } catch (err) {
      console.error("❌ 初始化音乐播放器出错：", err);
      window.$message.error("播放遇到错误，尝试下一首");
      await this.nextOrPrev("next");
    }
  }
  /**
   * 播放
   */
  async play() {
    const statusStore = useStatusStore();
    const settingStore = useSettingStore();
    // 检查播放器状态
    if (!this.player || this.player.state() === "unloaded") {
      window.$message.warning("播放器未加载完成，请稍后重试");
      return;
    }
    // 已在播放
    if (this.player.playing()) {
      statusStore.playStatus = true;
      return;
    }
    this.player.play();
    // 淡入
    await new Promise<void>((resolve) => {
      this.player.once("play", () => {
        // 在淡入开始时立即设置播放状态
        statusStore.playStatus = true;
        this.player.fade(0, statusStore.playVolume, settingStore.getFadeTime);
        resolve();
      });
    });
  }
  /**
   * 暂停
   * @param changeStatus 是否更改播放状态
   */
  async pause(changeStatus: boolean = true) {
    const statusStore = useStatusStore();
    const settingStore = useSettingStore();

    // 播放器未加载完成或不存在
    if (!this.player || this.player.state() !== "loaded") {
      window.$message.warning("播放器未加载完成，请稍后重试");
      return;
    }
    // 立即设置播放状态
    if (changeStatus) statusStore.playStatus = false;
    // 淡出
    await new Promise<void>((resolve) => {
      this.player.fade(statusStore.playVolume, 0, settingStore.getFadeTime);
      this.player.once("fade", () => {
        this.player.pause();
        resolve();
      });
    });
  }
  /**
   * 播放或暂停
   */
  async playOrPause() {
    const statusStore = useStatusStore();
    if (statusStore.playStatus) await this.pause();
    else await this.play();
  }
  /**
   * 下一首或上一首
   * @param type 切换类别 next 下一首 prev 上一首
   * @param play 是否立即播放
   * @param autoEnd 是否为歌曲自动播放结束
   */
  async nextOrPrev(type: "next" | "prev" = "next", play: boolean = true, autoEnd: boolean = false) {
    const statusStore = useStatusStore();
    const dataStore = useDataStore();
    const musicStore = useMusicStore();
    try {
      // 立即更新UI状态，防止用户重复点击
      statusStore.playLoading = true;
      statusStore.playStatus = false;

      // 获取数据
      const { playList } = dataStore;
      const { playSong } = musicStore;
      const { playSongMode, playHeartbeatMode } = statusStore;
      // 若为私人FM
      if (statusStore.personalFmMode) {
        await this.initPersonalFM(true);
        return;
      }
      // 列表长度
      const playListLength = playList.length;
      // 播放列表是否为空
      if (playListLength === 0) {
        window.$message.error("播放列表为空，请添加歌曲");
        return;
      }
      // 只有一首歌的特殊处理
      if (playListLength === 1) {
        statusStore.playLoading = false;
        this.setSeek(0);
        await this.play();
        return;
      }
      // 单曲循环
      if (playSongMode === "repeat-once" && autoEnd && !playHeartbeatMode) {
        statusStore.playLoading = false;
        this.setSeek(0);
        await this.play();
        return;
      }
      // 列表循环、单曲循环（手动切歌）、处于心动模式或随机模式
      if (
        playSongMode === "repeat" ||
        playSongMode === "repeat-once" ||
        playSongMode === "shuffle" ||
        playHeartbeatMode ||
        playSong.type === "radio"
      ) {
        statusStore.playIndex += type === "next" ? 1 : -1;
      } else {
        throw new Error("The play mode is not supported");
      }
      // 索引是否越界
      if (statusStore.playIndex < 0) {
        statusStore.playIndex = playListLength - 1;
      } else if (statusStore.playIndex >= playListLength) {
        statusStore.playIndex = 0;
      }
      // 立即清理定时器，防止旧定时器继续更新UI
      this.cleanupAllTimers();
      // 重置播放进度（切换歌曲时必须重置）
      statusStore.currentTime = 0;
      statusStore.progress = 0;
      // 初始化播放器（不传入seek参数，确保从头开始播放）
      await this.initPlayer(play, 0);
    } catch (error) {
      console.error("Error in nextOrPrev:", error);
      statusStore.playLoading = false;
      throw error;
    }
  }
  /**
   * 切换播放模式
   * @param mode 播放模式 repeat / repeat-once / shuffle
   */
  async togglePlayMode(mode: PlayModeType | false) {
    const statusStore = useStatusStore();
    const dataStore = useDataStore();
    const musicStore = useMusicStore();
    // 退出心动模式
    if (statusStore.playHeartbeatMode) this.toggleHeartMode(false);
    // 计算目标模式
    let targetMode: PlayModeType;
    if (mode) {
      targetMode = mode;
    } else {
      switch (statusStore.playSongMode) {
        case "repeat":
          targetMode = "repeat-once";
          break;
        case "shuffle":
          targetMode = "repeat";
          break;
        case "repeat-once":
          targetMode = "shuffle";
          break;
        default:
          targetMode = "repeat";
      }
    }
    // 进入随机模式：保存原顺序并打乱当前歌单
    if (targetMode === "shuffle" && statusStore.playSongMode !== "shuffle") {
      const currentList = dataStore.playList;
      if (currentList && currentList.length > 1) {
        const currentSongId = musicStore.playSong?.id;
        await dataStore.setOriginalPlayList(currentList);
        const shuffled = shuffleArray(currentList);
        await dataStore.setPlayList(shuffled);
        if (currentSongId) {
          const newIndex = shuffled.findIndex((s) => s?.id === currentSongId);
          if (newIndex !== -1) useStatusStore().playIndex = newIndex;
        }
      }
    }
    // 离开随机模式：恢复到原顺序
    if (
      statusStore.playSongMode === "shuffle" &&
      (targetMode === "repeat" || targetMode === "repeat-once")
    ) {
      const original = await dataStore.getOriginalPlayList();
      if (original && original.length) {
        const currentSongId = musicStore.playSong?.id;
        await dataStore.setPlayList(original);
        if (currentSongId) {
          const origIndex = original.findIndex((s) => s?.id === currentSongId);
          useStatusStore().playIndex = origIndex !== -1 ? origIndex : 0;
        } else {
          useStatusStore().playIndex = 0;
        }
        await dataStore.clearOriginalPlayList();
      }
    }
    // 应用模式
    statusStore.playSongMode = targetMode;
    this.playModeSyncIpc();
  }
  /**
   * 播放模式同步 ipc
   */
  playModeSyncIpc() {
    const statusStore = useStatusStore();
    if (isElectron) {
      window.electron.ipcRenderer.send("play-mode-change", statusStore.playSongMode);
    }
  }
  /**
   * 设置播放进度
   * @param time 播放进度（单位：毫秒）
   */
  setSeek(time: number) {
    const statusStore = useStatusStore();
    // 检查播放器状态
    if (!this.player || this.player.state() !== "loaded") {
      console.warn("⚠️ Player not ready for seek");
      return;
    }
    if (time < 0 || time > this.getDuration()) {
      console.warn("⚠️ Invalid seek time", time);
      time = Math.max(0, Math.min(time, this.getDuration()));
    }
    this.player.seek(time / 1000);
    statusStore.currentTime = time;
  }
  /**
   * 获取播放进度
   * @returns 播放进度（单位：毫秒）
   */
  getSeek(): number {
    // 检查播放器状态
    if (!this.player || this.player.state() !== "loaded") return 0;
    return Math.floor(this.player.seek() * 1000);
  }
  /**
   * 获取播放时长
   * @returns 播放时长（单位：毫秒）
   */
  getDuration(): number {
    return Math.floor(this.player.duration() * 1000);
  }
  /**
   * 设置播放速率
   * @param rate 播放速率
   */
  setRate(rate: number) {
    const statusStore = useStatusStore();
    this.player.rate(rate);
    statusStore.playRate = rate;
  }
  /**
   * 设置播放音量
   * @param actions 音量
   */
  setVolume(actions: number | "up" | "down" | WheelEvent) {
    const statusStore = useStatusStore();
    const increment = 0.05;
    // 直接设置
    if (typeof actions === "number") {
      actions = Math.max(0, Math.min(actions, 1));
    }
    // 分类调节
    else if (actions === "up" || actions === "down") {
      statusStore.playVolume = Math.max(
        0,
        Math.min(statusStore.playVolume + (actions === "up" ? increment : -increment), 1),
      );
    }
    // 鼠标滚轮
    else {
      const deltaY = actions.deltaY;
      const volumeChange = deltaY > 0 ? -increment : increment;
      statusStore.playVolume = Math.max(0, Math.min(statusStore.playVolume + volumeChange, 1));
    }
    // 调整音量
    this.player.volume(statusStore.playVolume);
  }
  /**
   * 切换静音
   */
  toggleMute() {
    const statusStore = useStatusStore();
    // 是否静音
    const isMuted = statusStore.playVolume === 0;
    // 恢复音量
    if (isMuted) {
      statusStore.playVolume = statusStore.playVolumeMute;
    }
    // 保存当前音量并静音
    else {
      statusStore.playVolumeMute = this.player.volume();
      statusStore.playVolume = 0;
    }
    this.player.volume(statusStore.playVolume);
  }
  /**
   * 更新播放列表
   * @param data 播放列表
   * @param song 当前播放歌曲
   * @param pid 播放列表id
   * @param options 配置
   * @param options.showTip 是否显示提示
   * @param options.scrobble 是否打卡
   * @param options.play 是否直接播放
   */
  async updatePlayList(
    data: SongType[],
    song?: SongType,
    pid?: number,
    options: {
      showTip?: boolean;
      scrobble?: boolean;
      play?: boolean;
    } = {
      showTip: true,
      scrobble: true,
      play: true,
    },
  ) {
    if (!data || !data.length) return;
    const dataStore = useDataStore();
    const musicStore = useMusicStore();
    const statusStore = useStatusStore();
    // 获取配置
    const { showTip, play } = options;

    // 处理随机播放模式
    let processedData = cloneDeep(data);
    if (statusStore.playSongMode === "shuffle") {
      // 保存原始播放列表
      await dataStore.setOriginalPlayList(cloneDeep(data));
      // 随机排序
      processedData = shuffleArray(processedData);
    }

    // 更新列表
    await dataStore.setPlayList(processedData);
    // 关闭特殊模式
    if (statusStore.playHeartbeatMode) this.toggleHeartMode(false);
    if (statusStore.personalFmMode) statusStore.personalFmMode = false;
    // 是否直接播放
    if (song && typeof song === "object" && "id" in song) {
      // 是否为当前播放歌曲
      if (musicStore.playSong.id === song.id) {
        if (play) await this.play();
      } else {
        // 查找索引（在处理后的列表中查找）
        statusStore.playIndex = processedData.findIndex((item) => item.id === song.id);
        // 播放
        await this.initPlayer();
      }
    } else {
      statusStore.playIndex =
        statusStore.playSongMode === "shuffle"
          ? Math.floor(Math.random() * processedData.length)
          : 0;
      // 播放
      await this.initPlayer();
    }
    // 更改播放歌单
    musicStore.playPlaylistId = pid ?? 0;
    if (showTip) window.$message.success("已开始播放");
  }
  /**
   * 添加下一首歌曲
   * @param song 歌曲
   * @param play 是否立即播放
   */
  async addNextSong(song: SongType, play: boolean = false) {
    const dataStore = useDataStore();
    const musicStore = useMusicStore();
    const statusStore = useStatusStore();
    // 关闭特殊模式
    if (statusStore.personalFmMode) statusStore.personalFmMode = false;
    // 是否为当前播放歌曲
    if (musicStore.playSong.id === song.id) {
      this.play();
      window.$message.success("已开始播放");
      return;
    }
    // 尝试添加
    const songIndex = await dataStore.setNextPlaySong(song, statusStore.playIndex);
    // 播放歌曲
    if (songIndex < 0) return;
    if (play) this.togglePlayIndex(songIndex, true);
    else window.$message.success("已添加至下一首播放");
  }
  /**
   * 切换播放索引
   * @param index 播放索引
   * @param play 是否立即播放
   */
  async togglePlayIndex(index: number, play: boolean = false) {
    const dataStore = useDataStore();
    const statusStore = useStatusStore();
    try {
      // 立即更新UI状态，防止用户重复点击
      statusStore.playLoading = true;
      statusStore.playStatus = false;
      // 获取数据
      const { playList } = dataStore;
      // 若超出播放列表
      if (index >= playList.length) return;
      // 相同
      if (!play && statusStore.playIndex === index) {
        this.play();
        return;
      }
      // 更改状态
      statusStore.playIndex = index;
      // 重置播放进度（切换歌曲时必须重置）
      statusStore.currentTime = 0;
      statusStore.progress = 0;
      statusStore.lyricIndex = -1;
      // 清理定时器，防止旧定时器继续运行
      this.cleanupAllTimers();
      // 清理并播放（不传入seek参数，确保从头开始播放）
      await this.initPlayer(true, 0);
    } catch (error) {
      console.error("Error in togglePlayIndex:", error);
      statusStore.playLoading = false;
      throw error;
    }
  }
  /**
   * 移除指定歌曲
   * @param index 歌曲索引
   */
  removeSongIndex(index: number) {
    const dataStore = useDataStore();
    const statusStore = useStatusStore();
    // 获取数据
    const { playList } = dataStore;
    // 若超出播放列表
    if (index >= playList.length) return;
    // 仅剩一首
    if (playList.length === 1) {
      this.cleanPlayList();
      return;
    }
    // 是否为当前播放歌曲
    const isCurrentPlay = statusStore.playIndex === index;
    // 深拷贝，防止影响原数据
    const newPlaylist = cloneDeep(playList);
    // 若将移除最后一首
    if (index === playList.length - 1) {
      statusStore.playIndex = 0;
    }
    // 若为当前播放之后
    else if (statusStore.playIndex > index) {
      statusStore.playIndex--;
    }
    // 移除指定歌曲
    newPlaylist.splice(index, 1);
    dataStore.setPlayList(newPlaylist);
    // 若为当前播放
    if (isCurrentPlay) {
      this.initPlayer(statusStore.playStatus);
    }
  }
  /**
   * 清空播放列表
   */
  async cleanPlayList() {
    const dataStore = useDataStore();
    const statusStore = useStatusStore();
    // 停止播放
    Howler.unload();
    // 清空数据
    this.resetStatus();
    statusStore.$patch({
      playListShow: false,
      showFullPlayer: false,
      playHeartbeatMode: false,
      personalFmMode: false,
      playIndex: -1,
    });
    // 清空播放列表及缓存
    await dataStore.setPlayList([]);
    await dataStore.clearOriginalPlayList();
  }
  /**
   * 切换输出设备
   * @param deviceId 输出设备
   */
  toggleOutputDevice(deviceId?: string) {
    try {
      const settingStore = useSettingStore();
      // 输出设备
      const devices = deviceId ?? settingStore.playDevice;
      if (!(this.player as any)?._sounds.length) return;
      // 获取音频元素
      const audioDom = this.getAudioDom();
      // 设置输出设备
      if (devices && audioDom?.setSinkId) {
        audioDom.setSinkId(devices);
      }
    } catch (error) {
      console.error("Failed to change audio output device:", error);
    }
  }
  /**
   * 初始化音频可视化
   */
  initSpectrumData() {
    try {
      if (this.audioContext || !isElectron) return;
      // 获取音频元素
      const audioDom = this.getAudioDom();
      if (!audioDom) return;
      // 通过统一管理器创建/获取基础图
      const nodes = audioContextManager.getOrCreateBasicGraph(audioDom);
      if (!nodes) return;
      // 记录节点
      this.audioContext = nodes.context;
      this.analyser = nodes.analyser;
      // 可视化保持与原有行为一致：连接到输出
      this.analyser.connect(this.audioContext.destination);
      // 配置数据缓冲
      const bufferLength = this.analyser.frequencyBinCount;
      this.dataArray = new Uint8Array(bufferLength);
      // 更新频谱数据
      this.generateSpectrumData();
      console.log("🎼 Initialize music spectrum successfully");
    } catch (error) {
      console.error("🎼 Initialize music spectrum failed:", error);
    }
  }

  /**
   * 启用均衡器
   * @param options 配置
   * @param options.bands 各频段 dB 值（与 frequencies 对齐），直接写入 filter.gain
   * @param options.preamp 前级增益 dB，转换为线性增益写入 preGain.gain
   * @param options.q peaking 类型的 Q 值统一更新（shelf 不适用 Q）
   * @param options.frequencies 自定义中心频率
   */
  enableEq(options?: { bands?: number[]; preamp?: number; q?: number; frequencies?: number[] }) {
    if (!isElectron) return;
    const audioDom = this.getAudioDom();
    if (!audioDom) return;
    const nodes = audioContextManager.enableEq(audioDom, options);
    if (!nodes) return;
    // 连接到输出，确保声音从 WebAudio 输出
    try {
      nodes.analyser.connect(nodes.context.destination);
    } catch {
      /* empty */
    }
  }

  /**
   * 更新均衡器参数
   * @param options 配置
   * @param options.bands 各频段 dB 值（与 frequencies 对齐），直接写入 filter.gain
   * @param options.preamp 前级增益 dB，转换为线性增益写入 preGain.gain
   * @param options.q peaking 类型的 Q 值统一更新（shelf 不适用 Q）
   */
  updateEq(options: { bands?: number[]; preamp?: number; q?: number }) {
    if (!isElectron) return;
    const audioDom = this.getAudioDom();
    if (!audioDom) return;
    audioContextManager.updateEq(audioDom, options);
  }

  /**
   * 禁用均衡器并恢复直出（保持频谱可用）
   */
  disableEq() {
    if (!isElectron) return;
    const audioDom = this.getAudioDom();
    if (!audioDom) return;
    audioContextManager.disableEq(audioDom);
    // 恢复 analyser 输出
    const nodes = audioContextManager.getOrCreateBasicGraph(audioDom);
    if (nodes) {
      try {
        nodes.analyser.connect(nodes.context.destination);
      } catch {
        /* empty */
      }
    }
  }
  /**
   * 切换桌面歌词
   */
  toggleDesktopLyric() {
    const statusStore = useStatusStore();
    const show = !statusStore.showDesktopLyric;
    statusStore.showDesktopLyric = show;
    window.electron.ipcRenderer.send("toggle-desktop-lyric", show);
    window.$message.success(`${show ? "已开启" : "已关闭"}桌面歌词`);
  }
  /**
   * 显式设置桌面歌词显示/隐藏
   */
  setDesktopLyricShow(show: boolean) {
    const statusStore = useStatusStore();
    if (statusStore.showDesktopLyric === show) return;
    statusStore.showDesktopLyric = show;
    window.electron.ipcRenderer.send("toggle-desktop-lyric", show);
    window.$message.success(`${show ? "已开启" : "已关闭"}桌面歌词`);
  }
  /**
   * 切换心动模式
   * @param open 是否开启
   */
  async toggleHeartMode(open: boolean = true) {
    try {
      const dataStore = useDataStore();
      const musicStore = useMusicStore();
      const statusStore = useStatusStore();
      if (!open && statusStore.playHeartbeatMode) {
        statusStore.playHeartbeatMode = false;
        window.$message.success("已退出心动模式");
        return;
      }
      if (isLogin() !== 1) {
        if (isLogin() === 0) {
          openUserLogin(true);
        } else {
          window.$message.warning("该登录模式暂不支持该操作");
        }
        return;
      }
      if (statusStore.playHeartbeatMode) {
        window.$message.warning("已处于心动模式");
        this.play();
        return;
      }
      this.message?.destroy();
      this.message = window.$message.loading("心动模式开启中", { duration: 0 });
      // 获取所需数据
      const playSongData = getPlaySongData();
      const likeSongsList = await dataStore.getUserLikePlaylist();
      // if (!playSongData || !likeSongsList) {
      //   throw new Error("获取播放数据或喜欢列表失败");
      // }
      const pid =
        musicStore.playPlaylistId && musicStore.playPlaylistId !== 0
          ? musicStore.playPlaylistId
          : (likeSongsList?.detail?.id ?? 0);
      // 开启心动模式
      const result = await heartRateList(playSongData?.id || 0, pid);
      if (result.code === 200) {
        this.message?.destroy();
        const heartRatelists = formatSongsList(result.data);
        // 更新播放列表
        await this.updatePlayList(heartRatelists, heartRatelists[0]);
        // 更改模式
        statusStore.playHeartbeatMode = true;
      } else {
        this.message?.destroy();
        window.$message.error(result.message || "心动模式开启出错，请重试");
      }
    } catch (error) {
      console.error("Failed to toggle heart mode:", error);
      this.message?.destroy();
      window.$message.error("心动模式开启出错，请重试");
    } finally {
      this.message?.destroy();
    }
  }
  /**
   * 初始化私人FM
   * @param playNext 是否播放下一首
   */
  async initPersonalFM(playNext: boolean = false) {
    const musicStore = useMusicStore();
    const statusStore = useStatusStore();
    try {
      // 获取并重置
      const getPersonalFmData = async () => {
        const result = await personalFm();
        const songData = formatSongsList(result.data);
        console.log(`🌐 personal FM:`, songData);
        musicStore.personalFM.list = songData;
        musicStore.personalFM.playIndex = 0;
      };
      // 若为空
      if (musicStore.personalFM.list.length === 0) await getPersonalFmData();
      // 若需播放下一首
      if (playNext) {
        statusStore.personalFmMode = true;
        // 更改索引
        if (musicStore.personalFM.playIndex < musicStore.personalFM.list.length - 1) {
          musicStore.personalFM.playIndex++;
        } else {
          await getPersonalFmData();
        }
        // 清理并播放
        this.resetStatus();
        await this.initPlayer();
      }
    } catch (error) {
      console.error("Failed to initialize personal FM:", error);
    }
  }
  /**
   * 私人FM - 垃圾桶
   * @param id 歌曲id
   */
  async personalFMTrash(id: number) {
    try {
      const statusStore = useStatusStore();
      if (!isLogin()) {
        openUserLogin(true);
        return;
      }
      // 更改模式
      statusStore.personalFmMode = true;
      statusStore.playHeartbeatMode = false;
      // 加入回收站
      const result = await personalFmToTrash(id);
      if (result.code === 200) {
        window.$message.success("已移至垃圾桶");
        this.nextOrPrev("next");
      }
    } catch (error) {
      console.error("Error adding to trash:", error);
      window.$message.error("移至垃圾桶失败，请重试");
    }
  }
  /**
   * 开始定时关闭
   * @param time 关闭时间（分钟）
   * @param remainTime 剩余时间（秒）
   */
  startAutoCloseTimer(time: number, remainTime: number) {
    const statusStore = useStatusStore();
    if (!time || !remainTime) return;
    // 如已有定时器在运行，先停止以防叠加
    if (this.autoCloseInterval) {
      clearInterval(this.autoCloseInterval);
      this.autoCloseInterval = undefined;
    }
    // 重置剩余时间
    Object.assign(statusStore.autoClose, {
      enable: true,
      time,
      remainTime,
    });
    // 开始减少剩余时间
    this.autoCloseInterval = setInterval(() => {
      if (statusStore.autoClose.remainTime <= 0) {
        clearInterval(this.autoCloseInterval);
        this.autoCloseInterval = undefined;
        if (!statusStore.autoClose.waitSongEnd) {
          this.executeAutoClose();
        }
        return;
      }
      statusStore.autoClose.remainTime--;
    }, 1000);
  }
  /**
   * 清理所有定时器和资源
   */
  private cleanupAllTimers() {
    // 清理播放状态定时器
    if (this.playerInterval.isActive.value) {
      this.playerInterval.pause();
    }
    // 清理自动关闭定时器
    if (this.autoCloseInterval) {
      clearInterval(this.autoCloseInterval);
      this.autoCloseInterval = undefined;
    }
  }

  /**
   * 执行自动关闭
   */
  private executeAutoClose() {
    console.log("🔄 执行自动关闭");
    // 暂停播放
    this.pause();
    // 重置状态
    const { autoClose } = useStatusStore();
    autoClose.enable = false;
    autoClose.remainTime = autoClose.time * 60;
  }
}

// export default new Player();

let _player: Player | null = null;

/**
 * 获取播放器实例
 * @returns Player
 */
export const usePlayer = (): Player => {
  if (!_player) _player = new Player();
  return _player;
};
