import type { Dispatch, SetStateAction } from 'react'
import { useState } from 'react'

import map from 'lodash/map'
import isEqual from 'lodash/isEqual'

import { isIOS } from 'config'

import type {
  Episode,
  Episodes,
  Events,
} from 'requests'

import type { EventPlaylistOption, PlaylistOption } from 'features/MatchPage/types'
import type { TCircleAnimation } from 'features/CircleAnimationBar'
import { initialCircleAnimation } from 'features/CircleAnimationBar'
import { PlaylistTypes } from 'features/MatchPage/types'
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config'

type UseStatsTabArgs = {
  disablePlayingEpisodes: () => void,
  handlePlaylistClick: (playlist: PlaylistOption) => void,
  selectedPlaylist?: PlaylistOption,
  setSelectedPlaylist: Dispatch<SetStateAction<PlaylistOption | undefined>>,
}

type PlayNextEpisodeArgs = {
  episodesToPlay?: Array<EventPlaylistOption>,
  order?: number,
}

const EPISODE_TIMESTAMP_OFFSET = 0.001

const addOffset = ({
  e,
  h,
  s,
}: Episode) => ({
  e: e + EPISODE_TIMESTAMP_OFFSET,
  h,
  s: s + EPISODE_TIMESTAMP_OFFSET,
})

export const useStatsTab = ({
  disablePlayingEpisodes,
  handlePlaylistClick,
  selectedPlaylist,
  setSelectedPlaylist,
}: UseStatsTabArgs) => {
  const [statsType, setStatsType] = useState<StatsType>(StatsType.FINAL_STATS)
  const [isPlayersStatsFetching, setIsPlayersStatsFetching] = useState(false)
  const [isTeamsStatsFetching, setIsTeamsStatsFetching] = useState(false)
  const [stateEpisodesToPlay, setEpisodesToPlay] = useState<Array<EventPlaylistOption>>([])
  const [filteredEvents, setFilteredEvents] = useState<Events>([])
  const [plaingOrder, setPlaingOrder] = useState(0)
  const [isPlayFilterEpisodes, setIsPlayingFiltersEpisodes] = useState(false)
  const [watchAllEpisodesTimer, setWatchAllEpisodesTimer] = useState(false)
  const [circleAnimation, setCircleAnimation] = useState<TCircleAnimation>(initialCircleAnimation)

  const isFinalStatsType = statsType === StatsType.FINAL_STATS

  const toggleStatsType = () => {
    const newStatsType = isFinalStatsType ? StatsType.CURRENT_STATS : StatsType.FINAL_STATS

    setStatsType(newStatsType)
    setIsTeamsStatsFetching(true)
    setIsPlayersStatsFetching(true)
  }

  const getEpisodesToPlay = (episodes: Episodes) => map(episodes, (episode, i) => ({
    episodes: [
      /** При проигрывании нового эпизода с такими же e и s, как у текущего
       воспроизведение начинается не с начала, чтобы пофиксить это добавляем
       небольшой оффсет
      */
      isEqual(episode, selectedPlaylist?.episodes[0])
        ? addOffset(episode)
        : episode,
    ],
    id: i,
    type: PlaylistTypes.EVENT,
  })) as Array<EventPlaylistOption>

  const playNextEpisode = ({
    order,
    episodesToPlay = stateEpisodesToPlay,
  }: PlayNextEpisodeArgs = {}) => {
    const currentOrder = order === 0 ? order : plaingOrder
    const isLastEpisode = currentOrder === episodesToPlay.length

    if (isLastEpisode) {
      setPlaingOrder(0)
      setIsPlayingFiltersEpisodes(false)

      return
    }

    if (currentOrder !== 0) {
      handlePlaylistClick(episodesToPlay[currentOrder])
    }

    setPlaingOrder(currentOrder + 1)
  }

  const playEpisodes = (episodes: Episodes) => {
    disablePlayingEpisodes()

    const episodesToPlay = getEpisodesToPlay(episodes)

    /**
     * на ios видео иногда не останавлвается после завершения эпизода,
     * данный хак исправляет проблему
     */
    if (isIOS) {
      setSelectedPlaylist({
        ...episodesToPlay[0],
        episodes: [addOffset(episodesToPlay[0].episodes[0])],
      })
    }

    setEpisodesToPlay(episodesToPlay)
    setFilteredEvents(episodes as Events)

    setWatchAllEpisodesTimer(true)
    setIsPlayingFiltersEpisodes(true)

    handlePlaylistClick(episodesToPlay[0])
    playNextEpisode({ episodesToPlay, order: 0 })
  }

  return {
    circleAnimation,
    filteredEvents,
    isPlayFilterEpisodes,
    isPlayersStatsFetching,
    isTeamsStatsFetching,
    plaingOrder,
    playEpisodes,
    playNextEpisode,
    setCircleAnimation,
    setIsPlayersStatsFetching,
    setIsPlayingFiltersEpisodes,
    setIsTeamsStatsFetching,
    setPlaingOrder,
    setWatchAllEpisodesTimer,
    statsType,
    toggleStatsType,
    watchAllEpisodesTimer,
  }
}
