import {
  useEffect,
  useState,
  useMemo,
} from 'react'

import includes from 'lodash/includes'
import filter from 'lodash/filter'
import isEmpty from 'lodash/isEmpty'

import { useToggle } from 'hooks'

import type { MatchInfo } from 'requests/getMatchInfo'
import { getMatchInfo } from 'requests/getMatchInfo'

import { usePageParams } from 'hooks/usePageParams'

import { parseDate } from 'helpers/parseDate'

import { useTournamentData } from './useTournamentData'
import { useMatchData } from './useMatchData'
import { useFiltersPopup } from './useFitersPopup'
import { useTabEvents } from './useTabEvents'

import type { Playlists } from '../../types'

const addScoresFromPlaylists = (
  profile: MatchInfo,
  playlists: Playlists,
): MatchInfo => (
  profile
    ? {
      ...profile,
      team1: {
        ...profile?.team1,
        score: playlists.score1,
      },
      team2: {
        ...profile?.team2,
        score: playlists.score2,
      },
    }
    : null
)

export const useMatchPage = () => {
  const [matchProfile, setMatchProfile] = useState<MatchInfo>(null)
  const { profileId: matchId, sportType } = usePageParams()
  const {
    close: hideProfileCard,
    isOpen: profileCardShown,
    open: showProfileCard,
  } = useToggle(true)

  const {
    activeEvents,
    activeFirstTeamPlayers,
    activeSecondTeamPlayers,
    applyFilters,
    close: closePopup,
    countOfFilters,
    filters,
    isEmptyFilters,
    isOpen: isOpenPopup,
    resetEvents,
    resetPlayers,
    toggle: togglePopup,
    toggleActiveEvents,
    toggleActivePlayers,
  } = useFiltersPopup()

  useEffect(() => {
    getMatchInfo(sportType, matchId).then(setMatchProfile)
  }, [sportType, matchId])

  useEffect(() => {
    let getIntervalMatch: ReturnType<typeof setInterval>
    if (matchProfile?.live && !matchProfile.youtube_link) {
      getIntervalMatch = setInterval(
        () => getMatchInfo(sportType, matchId).then(setMatchProfile), 1000 * 60 * 3,
      )
    }
    return () => clearInterval(getIntervalMatch)
  }, [matchProfile, sportType, matchId])

  const {
    events,
    handlePlaylistClick,
    matchPlaylists,
    selectedPlaylist,
    setFullMatchPlaylistDuration,
  } = useMatchData(matchProfile)

  const profile = useMemo(
    () => addScoresFromPlaylists(matchProfile, matchPlaylists),
    [matchProfile, matchPlaylists],
  )
  const isStarted = useMemo(() => (
    profile?.date
      ? parseDate(profile.date) < new Date()
      : true
  ), [profile?.date])

  const { tournamentData } = useTournamentData(matchProfile?.tournament.id ?? null)

  const filteredEvents = useMemo(() => {
    switch (true) {
      case (!isEmpty(filters.events) && !isEmpty(filters.players)):
        return filter(events, (event) => includes(filters.players, event.p)
          && includes(filters.events, event.l))
      case (!isEmpty(filters.players)):
        return filter(events, (event) => includes(filters.players, event.p))
      case (!isEmpty(filters.events)):
        return filter(events, (event) => includes(filters.events, event.l))
      default: return events
    }
  }, [events, filters])

  const [plaingOrder, setPlaingOrder] = useState(0)
  const [isPlayFilterEpisodes, setIsPlayinFiltersEpisodes] = useState(false)

  const {
    activeStatus,
    episodesToPlay,
    isLiveMatch,
    likeImage,
    likeToggle,
    reversedGroupEvents,
    setReversed,
    setUnreversed,
  } = useTabEvents({ events: filteredEvents, profile })

  useEffect(() => {
    if (plaingOrder > episodesToPlay.length) setPlaingOrder(0)
  }, [plaingOrder, episodesToPlay])

  const playNextEpisode = (order?: number) => {
    const isLastEpisode = plaingOrder === episodesToPlay.length

    const currentOrder = order === 0 ? order : plaingOrder
    if (isLastEpisode) {
      setIsPlayinFiltersEpisodes(false)

      return
    }
    handlePlaylistClick(episodesToPlay[currentOrder])
    setPlaingOrder(currentOrder + 1)
  }
  const playEpisodes = () => {
    setIsPlayinFiltersEpisodes(true)

    if (matchProfile?.live) {
      handlePlaylistClick({
        episodes: episodesToPlay.map((el) => el.episodes[0]),
        id: 1,
        type: episodesToPlay[0].type,
      })
    } else {
      playNextEpisode(0)
    }
  }

  const disablePlayingEpisodes = () => {
    setIsPlayinFiltersEpisodes(false)
  }

  return {
    activeEvents,
    activeFirstTeamPlayers,
    activeSecondTeamPlayers,
    activeStatus,
    applyFilters,
    closePopup,
    countOfFilters,
    disablePlayingEpisodes,
    events,
    filteredEvents,
    handlePlaylistClick,
    hideProfileCard,
    isEmptyFilters,
    isLiveMatch,
    isOpenPopup,
    isPlayFilterEpisodes,
    isStarted,
    likeImage,
    likeToggle,
    matchPlaylists,
    playEpisodes,
    playNextEpisode,
    profile,
    profileCardShown,
    resetEvents,
    resetPlayers,
    reversedGroupEvents,
    selectedPlaylist,
    setFullMatchPlaylistDuration,
    setIsPlayinFiltersEpisodes,
    setPlaingOrder,
    setReversed,
    setUnreversed,
    showProfileCard,
    toggleActiveEvents,
    toggleActivePlayers,
    togglePopup,
    tournamentData,
  }
}
