import { useMemo } from 'react';
import { usePlaybackStore } from '../store/usePlaybackStore';
import { useOptionalPlaybackSync } from '../components/PlaybackSyncProvider';

/**
 * The transport every control set should call.
 *
 * While another device holds the audio, a press has to travel to that device
 * instead of starting a second stream here. Controls that reach into the
 * playback store directly work on the desktop and silently do nothing useful
 * from a phone, so there is one place that makes the choice.
 */
export interface Transport {
  play: () => void;
  pause: () => void;
  toggle: () => void;
  next: () => void;
  prev: () => void;
  seek: (seconds: number) => void;
  /** True when the presses are being forwarded rather than played here. */
  remote: boolean;
}

export function useTransport(): Transport {
  const sync = useOptionalPlaybackSync();
  const hasRemoteOwner = sync?.hasRemoteOwner ?? false;
  const sendCommand = sync?.sendCommand;

  return useMemo(() => {
    const local = () => usePlaybackStore.getState();
    const away = hasRemoteOwner && sendCommand !== undefined;
    return {
      play: () => (away ? void sendCommand!({ type: 'play' }) : local().play()),
      pause: () => (away ? void sendCommand!({ type: 'pause' }) : local().pause()),
      toggle: () => {
        const playing = local().isPlaying;
        if (away) void sendCommand!({ type: playing ? 'pause' : 'play' });
        else if (playing) local().pause();
        else local().play();
      },
      next: () => (away ? void sendCommand!({ type: 'next' }) : local().next()),
      prev: () => (away ? void sendCommand!({ type: 'prev' }) : local().prev()),
      seek: (seconds: number) =>
        away ? void sendCommand!({ type: 'seek', position: seconds }) : local().setPosition(seconds),
      remote: away,
    };
  }, [hasRemoteOwner, sendCommand]);
}
