import { useCallback } from 'react'

import isUndefined from 'lodash/isUndefined'

import type { SetPartialState } from 'hooks'

import type { PlayerState } from '.'
import { getNextPlayer } from '../helpers'

export const usePlayingHandlers = (
  setPlayerState: SetPartialState<PlayerState>,
  numberOfChapters: number,
) => {
  const onReady = useCallback(() => {
    setPlayerState((state) => (
      state.ready
        ? state
        : { playing: true, ready: true }
    ))
  }, [setPlayerState])

  const togglePlaying = useCallback(() => {
    setPlayerState((state) => (
      state.ready
        ? { playing: !state.playing }
        : state
    ))
  }, [setPlayerState])

  const stopPlaying = useCallback(() => {
    setPlayerState({ playing: false })
  }, [setPlayerState])

  const startPlaying = useCallback(() => {
    setPlayerState((state) => (
      state.ready
        ? { playing: true }
        : state
    ))
  }, [setPlayerState])

  const playNextChapter = useCallback((fromMs?: number, startOffsetMs?: number) => {
    setPlayerState((state) => {
      if (!state.ready) return state

      const isLastChapter = state.activeChapterIndex + 1 === numberOfChapters
      if (isLastChapter || isUndefined(fromMs) || isUndefined(startOffsetMs)) {
        return {
          activeChapterIndex: isLastChapter ? 0 : state.activeChapterIndex + 1,
          activePlayer: getNextPlayer(state.activePlayer),
          loadedProgress: 0,
          playedProgress: 0,
          playing: isLastChapter ? false : state.playing,
        }
      }

      return {
        activeChapterIndex: state.activeChapterIndex + 1,
        loadedProgress: 0,
        playedProgress: fromMs,
        playing: state.playing,
        seek: {
          ...state.seek,
          [state.activePlayer]: (startOffsetMs + fromMs) / 1000,
        },
      }
    })
  }, [numberOfChapters, setPlayerState])

  const playPrevChapter = useCallback((fromMs?: number, startOffsetMs?: number) => {
    setPlayerState((state) => {
      if (!state.ready || state.activeChapterIndex === 0) return state

      if (isUndefined(fromMs) || isUndefined(startOffsetMs)) {
        return {
          activeChapterIndex: state.activeChapterIndex - 1,
          loadedProgress: 0,
          playedProgress: 0,
        }
      }

      return {
        activeChapterIndex: state.activeChapterIndex - 1,
        loadedProgress: 0,
        playedProgress: fromMs,
        seek: {
          ...state.seek,
          [state.activePlayer]: (startOffsetMs + fromMs) / 1000,
        },
      }
    })
  }, [setPlayerState])

  return {
    onReady,
    playNextChapter,
    playPrevChapter,
    startPlaying,
    stopPlaying,
    togglePlaying,
  }
}
