export const audioFils = {
  激光已校准:
    "https://static.shelingxingqiu.com/attachment/2025-10-29/ddupaur1vdkyhzaqdc.mp3",
  胜利: "https://static.shelingxingqiu.com/attachment/2025-09-17/dcuo9yjp0kt5msvmvd.mp3",
  失败: "https://static.shelingxingqiu.com/attachment/2025-09-17/dcuo9yht2sdwhuqygy.mp3",
  请射箭测试距离:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcuvj8avzqyw4hpq7t.mp3",
  距离合格:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutwrda0amn5kqr4j.mp3",
  距离不足:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6hr2faw28t0ianh0.mp3",
  轮到你了:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutzdrn4lxcpv8aqr.mp3",
  第一轮:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutyyr9a7m1vz2w13.mp3",
  第二轮:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutyyr9ldnfexjxtw.mp3",
  第三轮:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutyyr97m4ipxaze4.mp3",
  第四轮:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutyyr9x5addohlzf.mp3",
  第五轮:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutyyr9d7lw2gebpv.mp3",
  决金箭轮:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutwrd9zs4oi2kujv.mp3",
  请蓝方射箭:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutzdrxcbe5ll46as.mp3",
  请红方射箭:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutzdrl3re3dhlfjd.mp3",
  中场休息:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutwrd9zdk1xyolst.mp3",
  比赛结束:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutya59b6pu0ur4um.mp3",
  比赛开始:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcuu5z3a3lumkutske.mp3",
  请开始射击:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutzdrl5u0iromqhf.mp3",
  射击无效:
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutya55ufiiw8oo55.mp3",
  未上靶:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6n45o3tsm1v4unam.mp3",
  "1环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxin1aq7gxjih5l.mp3",
  "2环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxin64tdgx2s4at.mp3",
  "3环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxinlmf87vt8z65.mp3",
  "4环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxinniv97sx0q9u.mp3",
  "5环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxin7j01kknpb7k.mp3",
  "6环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxin4syy1015rtq.mp3",
  "7环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxin3iz3dvmjdai.mp3",
  "8环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxinnjd42lhpfiw.mp3",
  "9环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxin69nj1xh7yfz.mp3",
  "10环":
    "https://static.shelingxingqiu.com/attachment/2025-09-17/dcutxinnvsx0tt7ksa.mp3",
  向上调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6ellf5pfvu3l8dhr.mp3",
  向右上调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6ellf45v88pirarr.mp3",
  向右调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6elleqnhrenggxsb.mp3",
  向右下调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6elleo6q16qctf6a.mp3",
  向下调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6ellek2mu2cri2n9.mp3",
  向左下调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6ellf25yu1pt2k5r.mp3",
  向左调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6ellen3zoalxcb06.mp3",
  向左上调整:
    "https://static.shelingxingqiu.com/attachment/2025-11-12/de6ellf37a2iw6w4pu.mp3",
  最后30秒:
    "https://static.shelingxingqiu.com/attachment/2025-11-13/de7kzzllq0futwynso.mp3",
  练习开始:
    "https://static.shelingxingqiu.com/attachment/2025-11-14/de88w0lmmt43nnfmoi.mp3",
};

// 版本控制日志函数
function debugLog(...args) {
  // 获取当前环境信息
  const accountInfo = uni.getAccountInfoSync();
  const envVersion = accountInfo.miniProgram.envVersion;

  // 只在体验版打印日志，正式版(release)和开发版(develop)不打印
  if (envVersion === "trial") {
    console.log(...args);
  }
}

class AudioManager {
  constructor() {
    this.audioMap = new Map();
    this.currentPlayingKey = null;
    this.retryCount = new Map();
    this.maxRetries = 3;
    // 显式授权播放标记，防止 iOS 在设置 src 后误播
    this.allowPlayMap = new Map();

    // 串行加载相关属性
    this.audioKeys = [];
    this.currentLoadingIndex = 0;
    this.isLoading = false;
    this.loadingPromise = null;

    // 连续播放队列相关属性
    this.sequenceQueue = [];
    this.sequenceIndex = 0;
    this.isSequenceRunning = false;

    // 防重复播放保护
    this.lastPlayKey = null;
    this.lastPlayAt = 0;

    // 静音开关
    this.isMuted = false;

    // 网络状态相关
    this.networkOnline = true;
    this.pendingPlayKey = null;
    // 新增：就绪状态映射
    this.readyMap = new Map();
    try {
      uni.onNetworkStatusChange(({ isConnected }) => {
        this.networkOnline = !!isConnected;
        if (this.networkOnline) {
          this.onNetworkRestored();
        } else {
          this.onNetworkLost();
        }
      });
    } catch (_) {}

    this.initAudios();
  }

  // 初始化音频
  initAudios() {
    if (this.isLoading) {
      debugLog("音频正在加载中，跳过重复初始化");
      return this.loadingPromise;
    }

    debugLog("开始串行加载音频...");
    this.isLoading = true;
    this.audioKeys = Object.keys(audioFils);
    this.currentLoadingIndex = 0;

    this.loadingPromise = new Promise((resolve) => {
      this.loadNextAudio(resolve);
    });

    return this.loadingPromise;
  }

  // 串行加载下一个音频
  loadNextAudio(onComplete) {
    if (this.currentLoadingIndex >= this.audioKeys.length) {
      debugLog("所有音频加载完成");
      this.isLoading = false;
      if (onComplete) onComplete();
      return;
    }

    const key = this.audioKeys[this.currentLoadingIndex];
    debugLog(
      `开始加载音频 ${this.currentLoadingIndex + 1}/${
        this.audioKeys.length
      }: ${key}`
    );

    this.createAudio(key, () => {
      this.currentLoadingIndex++;
      setTimeout(() => {
        this.loadNextAudio(onComplete);
      }, 100);
    });
  }

  // 创建单个音频实例
  createAudio(key, callback) {
    const src = audioFils[key];
    const audio = uni.createInnerAudioContext();
    audio.autoplay = false;
    audio.src = src;

    // 初始化音量（支持的平台用 volume，H5 也可用 muted 作为兜底）
    try {
      if (typeof audio.volume === "number") {
        audio.volume = this.isMuted ? 0 : 1;
      } else if (typeof audio.muted !== "undefined") {
        audio.muted = this.isMuted;
      }
    } catch (_) {}

    // 初始化为不允许播放，只有显式 play() 才允许
    this.allowPlayMap.set(key, false);

    // 防止 iOS 误播：非授权播放立刻停止
    audio.onPlay(() => {
      if (!this.allowPlayMap.get(key)) {
        try {
          audio.stop();
        } catch (_) {}
      }
    });

    // 设置加载超时
    const loadTimeout = setTimeout(() => {
      debugLog(`音频 ${key} 加载超时`);
      audio.destroy();
      if (callback) callback();
    }, 10000);

    // 监听加载状态
    audio.onCanplay(() => {
      // 预加载阶段：仅在未授权情况下暂停，避免用户刚点击播放被打断
      if (!this.allowPlayMap.get(key)) {
        try {
          audio.pause();
        } catch (_) {}
      }
      clearTimeout(loadTimeout);
      // 标记为已就绪
      this.readyMap.set(key, true);
      debugLog(`音频 ${key} 已加载完成`);
      uni.$emit("audioLoaded", key);
      const loadedAudioKeys = uni.getStorageSync("loadedAudioKeys") || {};
      loadedAudioKeys[key] = true;
      uni.setStorageSync("loadedAudioKeys", loadedAudioKeys);
      this.retryCount.set(key, 0);
      if (callback) callback();
    });

    audio.onError((res) => {
      clearTimeout(loadTimeout);
      debugLog(`音频 ${key} 加载失败：`, res.errMsg);
      this.allowPlayMap.set(key, false);
      // 标记为未就绪
      this.readyMap.set(key, false);
      this.handleAudioError(key);
      if (callback) callback();
    });

    // 监听播放结束事件
    audio.onEnded(() => {
      if (this.currentPlayingKey === key) {
        this.currentPlayingKey = null;
      }
      this.allowPlayMap.set(key, false);
      // 触发连续播放队列的衔接
      this.onAudioEnded(key);
    });

    // 监听播放停止事件
    audio.onStop(() => {
      if (this.currentPlayingKey === key) {
        this.currentPlayingKey = null;
      }
      this.allowPlayMap.set(key, false);
    });

    this.audioMap.set(key, audio);
    if (!this.retryCount.has(key)) {
      this.retryCount.set(key, 0);
    }
  }

  // 处理音频加载错误
  handleAudioError(key) {
    // 网络不可用时不重试，等重连后统一重建
    if (!this.networkOnline) {
      debugLog(`网络不可用，暂不重试音频: ${key}`);
      return;
    }
    const currentRetries = this.retryCount.get(key) || 0;

    if (currentRetries < this.maxRetries) {
      this.retryCount.set(key, currentRetries + 1);
      debugLog(`音频 ${key} 开始第 ${currentRetries + 1} 次重试...`);

      setTimeout(() => {
        this.retryLoadAudio(key);
      }, 1000);
    } else {
      console.error(
        `音频 ${key} 重试 ${this.maxRetries} 次后仍然失败，停止重试`
      );
      const failedAudio = this.audioMap.get(key);
      if (failedAudio) {
        failedAudio.destroy();
        this.audioMap.delete(key);
      }
    }
  }

  // 重新加载音频
  retryLoadAudio(key) {
    if (!this.networkOnline) {
      debugLog(`网络不可用，稍后再重载音频: ${key}`);
      return;
    }
    const oldAudio = this.audioMap.get(key);
    if (oldAudio) {
      oldAudio.destroy();
    }
    this.createAudio(key);
  }

  // 播放指定音频或音频数组（数组则按顺序连续播放）
  play(input, interrupt = true) {
    // 统一规范化为队列
    let queue = [];
    if (Array.isArray(input)) {
      queue = input.filter((k) => !!audioFils[k]);
    } else if (typeof input === "string") {
      queue = !!audioFils[input] ? [input] : [];
    } else {
      debugLog("play 参数类型无效，仅支持字符串或字符串数组");
      return;
    }

    if (queue.length === 0) {
      debugLog("连续播放队列为空或无效");
      return;
    }

    if (interrupt) {
      // 立即打断并启动新的播放序列
      this.stopAll();
      this.isSequenceRunning = false;
      this.sequenceQueue = [];
      this.sequenceIndex = 0;

      this.sequenceQueue = queue;
      this.sequenceIndex = 0;
      this.isSequenceRunning = true;
      this._playSingle(queue[0], false);
      return;
    }

    // 不打断当前播放：把新的队列加入到序列中，等待当前播放结束后衔接
    if (this.currentPlayingKey) {
      if (this.isSequenceRunning) {
        // 已有序列在跑：直接追加
        this.sequenceQueue = this.sequenceQueue.concat(queue);
      } else {
        // 没有序列但当前有正在播放的：以当前为序列的起点
        this.isSequenceRunning = true;
        this.sequenceQueue = [this.currentPlayingKey].concat(queue);
        this.sequenceIndex = 0;
        // 不触发 _playSingle，等待当前音频自然结束后由 onAudioEnded 接管
      }
    } else {
      // 当前没有播放：直接启动新的序列
      this.sequenceQueue = queue;
      this.sequenceIndex = 0;
      this.isSequenceRunning = true;
      this._playSingle(queue[0], false);
    }
  }

  // 内部方法：播放单个 key
  _playSingle(key, forceStopAll = false) {
    // 200ms 内的同 key 重复播放直接忽略，避免“比比赛开始”这类重复首音
    const now = Date.now();
    if (this.lastPlayKey === key && now - this.lastPlayAt < 250) {
      debugLog(`忽略快速重复播放: ${key}`);
      return;
    }

    if (!this.networkOnline) {
      const audio = this.audioMap.get(key);
      const isReady = this.readyMap && this.readyMap.get(key);
      // 离线但已就绪：允许直接播放；未就绪则记录等待重连
      if (!audio || !isReady) {
        this.pendingPlayKey = key;
        debugLog(`网络不可用，记录播放: ${key}`);
        return;
      }
    }

    if (forceStopAll) {
      this.stopAll();
    } else if (this.currentPlayingKey && this.currentPlayingKey !== key) {
      this.stop(this.currentPlayingKey);
    } else if (this.currentPlayingKey === key) {
      // 同一音频正在播放：不重启，避免听到重复开头
      return;
    }

    const audio = this.audioMap.get(key);
    if (audio) {
      // 播放前确保遵循当前静音状态
      try {
        if (typeof audio.volume === "number") {
          audio.volume = this.isMuted ? 0 : 1;
        } else if (typeof audio.muted !== "undefined") {
          audio.muted = this.isMuted;
        }
      } catch (_) {}
      // 同一音频：避免 stop() 触发 onStop 清除授权，使用 pause()+seek(0)
      try {
        audio.pause();
      } catch (_) {}
      try {
        if (typeof audio.seek === "function") {
          audio.seek(0);
        } else {
          audio.startTime = 0;
        }
      } catch (_) {
        audio.startTime = 0;
      }

      // 显式授权播放并立即播放
      this.allowPlayMap.set(key, true);

      audio.play();
      this.currentPlayingKey = key;
      this.lastPlayKey = key;
      this.lastPlayAt = Date.now();
    } else {
      debugLog(`音频 ${key} 不存在，尝试重新加载...`);
      this.reloadAudio(key);
    }
  }

  // 连续播放：在某个音频结束后，若处于队列播放状态则继续下一个
  onAudioEnded(key) {
    if (!this.isSequenceRunning) return;
    const currentKey = this.sequenceQueue[this.sequenceIndex];
    if (currentKey !== key) return;

    const nextIndex = this.sequenceIndex + 1;
    if (nextIndex < this.sequenceQueue.length) {
      this.sequenceIndex = nextIndex;
      const nextKey = this.sequenceQueue[nextIndex];
      this._playSingle(nextKey, false);
    } else {
      // 队列播放完成
      this.isSequenceRunning = false;
      this.sequenceQueue = [];
      this.sequenceIndex = 0;
    }
  }

  // 停止指定音频
  stop(key) {
    const audio = this.audioMap.get(key);
    if (audio) {
      audio.stop();
      this.allowPlayMap.set(key, false);
      if (this.currentPlayingKey === key) {
        this.currentPlayingKey = null;
      }
    }
  }

  // 停止所有音频
  stopAll() {
    for (const [k, audio] of this.audioMap.entries()) {
      try {
        audio.stop();
      } catch (_) {}
      this.allowPlayMap.set(k, false);
    }
    this.currentPlayingKey = null;
  }

  // 销毁所有音频实例并清理状态
  destroyAll() {
    for (const [k, audio] of this.audioMap.entries()) {
      try {
        audio.destroy();
      } catch (_) {}
      this.allowPlayMap.delete(k);
      this.retryCount.delete(k);
      this.audioMap.delete(k);
      this.readyMap.delete(k);
    }
    this.audioKeys = [];
    this.currentLoadingIndex = 0;
    this.isLoading = false;
    this.loadingPromise = null;
    this.currentPlayingKey = null;
  }

  // 断网回调：停止当前播放，避免误状态
  onNetworkLost() {
    try {
      this.stopAll();
    } catch (_) {}
  }

  // 重连回调：重建全部音频后，重放上一次的播放
  onNetworkRestored() {
    // 网络恢复后，仅继续加载未就绪或缺失的音频，已就绪的不动，保证离线可播的缓存不被重置
    const keys = Object.keys(audioFils);
    const needLoad = keys.filter(
      (k) => !this.readyMap.get(k) || !this.audioMap.has(k)
    );

    if (needLoad.length > 0) {
      this.loadKeysSequentially(needLoad, () => {
        if (this.pendingPlayKey) {
          const pending = this.pendingPlayKey;
          this.pendingPlayKey = null;
          setTimeout(() => {
            this.play(pending);
          }, 20);
        }
      });
    } else {
      // 没有需要加载的音频，直接处理待播放
      if (this.pendingPlayKey) {
        const pending = this.pendingPlayKey;
        this.pendingPlayKey = null;
        setTimeout(() => {
          this.play(pending);
        }, 20);
      }
    }
  }

  // 重连后统一重建音频实例
  reinitializeOnReconnect() {
    this.destroyAll();
    this.initAudios();
  }

  // 按自定义列表串行加载音频（避免并发过多）
  loadKeysSequentially(keys, onComplete) {
    let idx = 0;
    const next = () => {
      if (idx >= keys.length) {
        if (onComplete) onComplete();
        return;
      }
      const k = keys[idx++];
      // 已存在但未就绪：重载；不存在：创建
      if (this.audioMap.has(k)) {
        this.retryLoadAudio(k);
      } else {
        this.createAudio(k, () => {
          setTimeout(next, 100);
        });
        return; // createAudio 内部会触发 next
      }
      setTimeout(next, 100);
    };
    next();
  }

  // 手动重新加载指定音频
  reloadAudio(key) {
    if (audioFils[key]) {
      debugLog(`手动重新加载音频: ${key}`);
      this.retryCount.set(key, 0);
      this.retryLoadAudio(key);
    }
  }

  // 设置静音开关：true 静音，false 取消静音
  setMuted(muted) {
    this.isMuted = !!muted;
    for (const audio of this.audioMap.values()) {
      try {
        if (typeof audio.volume === "number") {
          audio.volume = this.isMuted ? 0 : 1;
        } else if (typeof audio.muted !== "undefined") {
          audio.muted = this.isMuted;
        }
      } catch (_) {}
    }
    debugLog(`静音状态已设置为: ${this.isMuted}`);
  }

  // 新增：返回音频加载进度（0~1）
  getLoadProgress() {
    // 总数优先使用已初始化的 audioKeys，未初始化则回退到 audioFils
    const keys =
      this.audioKeys && this.audioKeys.length > 0
        ? this.audioKeys
        : Object.keys(audioFils);
    const total = keys.length;
    if (total === 0) return 0;
    let loaded = 0;
    for (const k of keys) {
      if (this.readyMap.get(k)) loaded++;
    }
    return loaded / total;
  }
}

// 导出单例
export default new AudioManager();