import { useEffect, useState } from 'react';

let audioContext: AudioContext;
if (typeof window === 'undefined') {
  // this may be a problem for deviceCompileWorker!
  audioContext = {
    sampleRate: 44100,
  } as AudioContext;
} else {
  const AudioContextConstructor =
    window.AudioContext || (window as any).webkitAudioContext;

  if (AudioContextConstructor) {
    audioContext = new AudioContextConstructor({
      latencyHint: 0,
    }) as AudioContext;

    // On some browsers, the audioContext starts immediately, i suspect this happens in cases where the site is deemed trustworthy? not sure.
    // adding a `suspend` here to get uniform behavior, but it is probably slightly worse UX on trusted sites.
    // should undo this when we understand what's going on.
    audioContext.suspend();
    window.addEventListener('mousedown', () => {
      if (audioContext.state === 'suspended') {
        audioContext.resume();
      }
    });
    window.addEventListener('keydown', () => {
      if (audioContext.state === 'suspended') {
        audioContext.resume();
      }
    });
  } else {
    // Fallback for test environments where AudioContext is not available (We should never be in this case other than for testing; jest does not support AudioContext)
    audioContext = {
      sampleRate: 44100,
      state: 'suspended',
      addEventListener: () => {},
      removeEventListener: () => {},
      suspend: () => Promise.resolve(),
      resume: () => Promise.resolve(),
    } as any as AudioContext;
  }
}

export const useAudioContextRunning = () => {
  const [running, setRunning] = useState(audioContext.state === 'running');
  useEffect(() => {
    const listener = () => {
      setRunning(audioContext.state === 'running');
    };
    audioContext.addEventListener('statechange', listener);
    return () => {
      audioContext.removeEventListener('statechange', listener);
    };
  }, []);
  return running;
};

export default audioContext;
