(() => {
  const INSTALL_VERSION = 2;
  const previousController = globalThis.__biliSummaryPlaybackRateMainController;
  if (previousController?.version === INSTALL_VERSION) return;

  try { previousController?.destroy?.(); } catch (_) {}

  // 1.1.2 之后曾有一个版本把 playbackRate setter 装到了整个
  // HTMLMediaElement.prototype 上。扩展热重载不会销毁现有页面的主世界，旧 setter
  // 会继续把所有档位拉回更新前的自定义速度。通过同源空 iframe 取得浏览器原生
  // descriptor，在安装新版实例级守卫前完成一次迁移；新页面不会走这条分支。
  if (globalThis.__biliSummaryPlaybackRateMainInstalled && !previousController) {
    let pristineFrame = null;
    try {
      const root = document.documentElement || document.head || document.body;
      if (root && globalThis.HTMLMediaElement?.prototype) {
        pristineFrame = document.createElement('iframe');
        pristineFrame.hidden = true;
        pristineFrame.setAttribute('aria-hidden', 'true');
        root.appendChild(pristineFrame);
        const pristinePrototype = pristineFrame.contentWindow?.HTMLMediaElement?.prototype;
        const pristinePlaybackRate = pristinePrototype
          ? Object.getOwnPropertyDescriptor(pristinePrototype, 'playbackRate')
          : null;
        if (pristinePlaybackRate?.get && pristinePlaybackRate?.set) {
          Object.defineProperty(globalThis.HTMLMediaElement.prototype, 'playbackRate', pristinePlaybackRate);
        }
        const legacyVideo = document.querySelector('#bilibili-player video, .bpx-player-container video, video');
        const legacyOwnPlaybackRate = legacyVideo
          ? Object.getOwnPropertyDescriptor(legacyVideo, 'playbackRate')
          : null;
        if (legacyOwnPlaybackRate?.configurable) delete legacyVideo.playbackRate;
      }
    } catch (_) {
      // 无法创建临时 realm 时仍继续安装新版桥；完整刷新页面会自然恢复原生原型。
    } finally {
      pristineFrame?.remove?.();
    }
  }

  globalThis.__biliSummaryPlaybackRateMainInstalled = true;

  const REQUEST_EVENT = '__biliSummarySetPlaybackRate';
  const NATIVE_PLAYER_RATES = new Set([0.5, 0.75, 1, 1.25, 1.5, 2]);
  const rateState = { desired: 1, custom: false };
  const mediaPrototype = globalThis.HTMLMediaElement?.prototype;
  const nativePlaybackRate = mediaPrototype
    ? Object.getOwnPropertyDescriptor(mediaPrototype, 'playbackRate')
    : null;
  let guardedVideo = null;
  let guardedVideoOwnDescriptor = null;
  let guardedVideoSetter = null;

  const sameRate = (left, right) => Math.abs(Number(left) - Number(right)) < 1e-4;

  function mainVideo() {
    const playerContainer = document.querySelector('#bilibili-player, .bpx-player-container, .bilibili-player-video-wrap');
    return playerContainer?.querySelector?.('video') || document.querySelector('video');
  }

  function setNativePlaybackRate(media, rate) {
    if (!media) return;
    if (typeof nativePlaybackRate?.set === 'function') nativePlaybackRate.set.call(media, rate);
    else media.playbackRate = rate;
  }

  function removeCustomRateGuard() {
    if (!guardedVideo) return;
    try {
      const current = Object.getOwnPropertyDescriptor(guardedVideo, 'playbackRate');
      if (current?.set === guardedVideoSetter) {
        if (guardedVideoOwnDescriptor) Object.defineProperty(guardedVideo, 'playbackRate', guardedVideoOwnDescriptor);
        else delete guardedVideo.playbackRate;
      }
    } catch (_) {
      // 即使页面锁定了实例，也不能影响原生档位的播放器 API 路径。
    }
    guardedVideo = null;
    guardedVideoOwnDescriptor = null;
    guardedVideoSetter = null;
  }

  // B 站播放器只认识固定档位。自定义速度仅在当前主视频实例上加一层临时守卫，
  // 阻止播放器把 0.9/1.1 改回旧档位；绝不改写 HTMLMediaElement.prototype，
  // 否则页面内所有音视频（包括原生倍速菜单）都会经过扩展 setter 并产生新抖动。
  function installCustomRateGuard(video) {
    if (!video || typeof nativePlaybackRate?.set !== 'function') {
      setNativePlaybackRate(video, rateState.desired);
      return;
    }
    if (guardedVideo !== video) {
      removeCustomRateGuard();
      guardedVideo = video;
      guardedVideoOwnDescriptor = Object.getOwnPropertyDescriptor(video, 'playbackRate') || null;
      guardedVideoSetter = function (value) {
        const requested = Number(value);
        nativePlaybackRate.set.call(this,
          rateState.custom && !sameRate(requested, rateState.desired) ? rateState.desired : value);
      };
      try {
        Object.defineProperty(video, 'playbackRate', {
          configurable: true,
          enumerable: guardedVideoOwnDescriptor?.enumerable ?? nativePlaybackRate.enumerable,
          get() { return nativePlaybackRate.get.call(this); },
          set: guardedVideoSetter,
        });
      } catch (_) {
        guardedVideo = null;
        guardedVideoOwnDescriptor = null;
        guardedVideoSetter = null;
      }
    }
    setNativePlaybackRate(video, rateState.desired);
  }

  function handlePlaybackRateRequest(event) {
    const rate = Number(event.detail?.rate);
    if (!(rate > 0)) return;

    rateState.desired = rate;
    rateState.custom = !NATIVE_PLAYER_RATES.has(rate);

    const video = mainVideo();
    if (rateState.custom) {
      installCustomRateGuard(video);
      return;
    }
    removeCustomRateGuard();

    try {
      const player = window.player;
      if (player && typeof player.setPlaybackRate === 'function') {
        player.setPlaybackRate(rate);
      }
    } catch (_) {
      // 隔离世界会在事件返回后对当前 video 做兜底设置。
    }

    if (video && !sameRate(video.playbackRate, rate)) setNativePlaybackRate(video, rate);
  }

  document.addEventListener(REQUEST_EVENT, handlePlaybackRateRequest);
  globalThis.__biliSummaryPlaybackRateMainController = {
    version: INSTALL_VERSION,
    destroy() {
      document.removeEventListener(REQUEST_EVENT, handlePlaybackRateRequest);
      removeCustomRateGuard();
    },
  };
})();
