import { useCallback } from 'react'

import isUndefined from 'lodash/isUndefined'

import type { SetPartialState } from 'hooks'

import type { PlayerState } from '.'
import type { Chapters } from '../types'

export const usePlayingHandlers = (
  setPlayerState: SetPartialState<PlayerState>,
  chapters: Chapters,
) => {
  const onReady = useCallback(() => {
    setPlayerState((state) => (
      state.ready
        ? state
        : {
          buffering: false,
          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 nextChapterIndex = state.activeChapterIndex + 1
      const nextChapter = chapters[nextChapterIndex]
      if (!nextChapter) {
        return {
          activeChapterIndex: 0,
          loadedProgress: 0,
          playedProgress: 0,
          playing: false,
          seek: chapters[0].startOffsetMs / 1000,
          seeking: false,
        }
      }
      if (isUndefined(fromMs) || isUndefined(startOffsetMs)) {
        return {
          activeChapterIndex: nextChapterIndex,
          loadedProgress: 0,
          playedProgress: 0,
          seek: nextChapter.startOffsetMs / 1000,
        }
      }

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

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

      const prevChapterIndex = state.activeChapterIndex - 1
      const prevChapter = chapters[prevChapterIndex]
      if (isUndefined(fromMs) || isUndefined(startOffsetMs)) {
        return {
          activeChapterIndex: prevChapterIndex,
          loadedProgress: 0,
          playedProgress: 0,
          seek: prevChapter.startOffsetMs / 1000,
        }
      }

      return {
        activeChapterIndex: prevChapterIndex,
        loadedProgress: 0,
        playedProgress: fromMs,
        seek: (startOffsetMs + fromMs) / 1000,
      }
    })
  }, [chapters, setPlayerState])

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