export function isEditableShortcutTarget(target) {
  const tag = target?.tagName;
  if (tag === 'TEXTAREA' || tag === 'SELECT') return true;
  if (tag === 'INPUT') {
    const type = target.type?.toLowerCase();
    return type !== 'range' && type !== 'checkbox' && type !== 'radio';
  }
  return !!target?.isContentEditable;
}

export function createAudioPlaybackController({
  audio,
  playButton,
  skipButton,
  loopButton,
  documentTarget,
  now = () => Date.now(),
  isSilentPlaying,
  setSilentTime,
  getLoop,
  togglePlayback,
  toggleLoop,
  updateButton,
  updatePlayhead,
  resumeAnimations,
  pauseAnimations,
  acquireWakeLock,
  releaseWakeLock,
  toggleFullscreen,
  isFullscreen,
  exitFullscreen,
  logger = console,
}) {
  const removers = [];
  let lastSpacePress = 0;
  const listen = (target, type, handler) => {
    target?.addEventListener(type, handler);
    if (target) removers.push(() => target.removeEventListener(type, handler));
  };

  listen(playButton, 'click', togglePlayback);
  listen(audio, 'play', async () => {
    updateButton();
    resumeAnimations();
    await acquireWakeLock();
  });
  const stop = async () => {
    updateButton();
    pauseAnimations();
    await releaseWakeLock();
  };
  listen(audio, 'pause', stop);
  listen(audio, 'ended', stop);
  listen(audio, 'seeked', () => updatePlayhead(true));
  listen(audio, 'timeupdate', () => {
    const loop = getLoop();
    if (loop.enabled && audio.currentTime >= loop.end) audio.currentTime = loop.start;
  });
  listen(skipButton, 'click', () => {
    const hasAudioTransport = Boolean(audio?.src);
    const wasPlaying = isSilentPlaying() || (hasAudioTransport && !audio.paused);
    setSilentTime(0);
    if (hasAudioTransport) audio.currentTime = 0;
    if (wasPlaying && hasAudioTransport) {
      audio.play()?.catch?.(error => {
        if (error.name !== 'AbortError') logger.error?.('Play from start failed:', error);
      });
    }
    updatePlayhead(true);
  });
  listen(loopButton, 'click', toggleLoop);
  listen(documentTarget, 'keydown', event => {
    if (isEditableShortcutTarget(event.target)) {
      if (event.code === 'Escape') event.target.blur?.();
      return;
    }
    if (event.code === 'Space') {
      event.preventDefault();
      const timestamp = now();
      if (lastSpacePress && timestamp - lastSpacePress < 300) {
        setSilentTime(0);
        if (audio?.src) audio.currentTime = 0;
        if (!(isSilentPlaying() || (audio?.src && !audio.paused))) togglePlayback();
        lastSpacePress = 0;
      } else {
        togglePlayback();
        lastSpacePress = timestamp;
      }
      return;
    }
    if (event.code === 'KeyF') {
      event.preventDefault();
      toggleFullscreen();
      return;
    }
    if (event.code === 'KeyL') {
      event.preventDefault();
      toggleLoop();
      return;
    }
    if (event.code === 'Escape' && isFullscreen()) {
      event.preventDefault();
      exitFullscreen();
    }
  });

  return {
    destroy() {
      for (const remove of removers.splice(0)) remove();
    },
  };
}
