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

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

import { FULL_GAME_KEY } from 'features/MatchPage/helpers/buildPlaylists'
import { useAuthStore } from 'features/AuthStore'

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

import { usePageParams } from 'hooks/usePageParams'
import { useToggle } from 'hooks/useToggle'

import { parseDate } from 'helpers/parseDate'

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

const ACCESS_TIME = 60

export const useMatchPage = () => {
  const [matchProfile, setMatchProfile] = useState<MatchInfo>(null)
  const [watchAllEpisodesTimer, setWatchAllEpisodesTimer] = useState(false)
  const [access, setAccess] = useState(true)
  const { profileId: matchId, sportType } = usePageParams()

  const { user, userInfo } = useAuthStore()

  const {
    close: hideProfileCard,
    isOpen: profileCardShown,
    open: showProfileCard,
  } = useToggle(true)

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

  const profile = matchProfile

  const {
    activeEvents,
    activeFirstTeamPlayers,
    activeSecondTeamPlayers,
    allActionsToggle,
    allPlayersToggle,
    applyFilters,
    close: closePopup,
    countOfFilters,
    filters,
    isAllActionsChecked,
    isEmptyFilters,
    isOpen: isOpenFiltersPopup,
    resetEvents,
    resetPlayers,
    toggle: togglePopup,
    toggleActiveEvents,
    toggleActivePlayers,
    uniqEvents,
  } = useFiltersPopup({
    events,
    matchPlaylists,
  })

  const getMatchViewDuration = (id: number) => (getViewMatchDuration({
    matchId,
    sportType,
    userId: id,
  }).then(({
    duration,
    error,
  }) => {
    if (error || (duration && Number(duration) > ACCESS_TIME)) {
      setAccess(false)
    }
  }))

  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])

  useEffect(() => {
    if (user || !userInfo?.email) return

    const counter = setInterval(
      () => getMatchViewDuration(Number(userInfo?.email)), 1000 * 30,
    )
    // eslint-disable-next-line
    return () => clearInterval(counter)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    sportType,
    matchId,
    userInfo,
  ])

  useEffect(() => {
    let getIntervalMatch: ReturnType<typeof setInterval>
    if (matchProfile?.live && selectedPlaylist?.id === FULL_GAME_KEY
    ) {
      getIntervalMatch = setInterval(
        () => getMatchInfo(sportType, matchId).then(setMatchProfile), 5000,
      )
    }
    return () => clearInterval(getIntervalMatch)
  })

  const {
    events,
    handlePlaylistClick,
    isEmptyPlayersStats,
    matchPlaylists,
    playersData,
    playersStats,
    selectedPlaylist,
    setFullMatchPlaylistDuration,
    setPlayingProgress,
    setStatsType,
    statsType,
    teamsStats,
  } = useMatchData(matchProfile)

  const profile = matchProfile

  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 = () => {
    if (!watchAllEpisodesTimer) {
      setWatchAllEpisodesTimer(true)
    }

    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 {
    access,
    activeEvents,
    activeFirstTeamPlayers,
    activeSecondTeamPlayers,
    activeStatus,
    allActionsToggle,
    allPlayersToggle,
    applyFilters,
    closePopup,
    countOfFilters,
    disablePlayingEpisodes,
    events,
    filteredEvents,
    handlePlaylistClick,
    hideProfileCard,
    isAllActionsChecked,
    isEmptyFilters,
    isEmptyPlayersStats,
    isLiveMatch,
    isOpenFiltersPopup,
    isPlayFilterEpisodes,
    isSecondTeamPlayersChecked,
    isStarted,
    likeImage,
    likeToggle,
    matchPlaylists,
    plaingOrder,
    playEpisodes,
    playNextEpisode,
    playersData,
    playersStats,
    profile,
    profileCardShown,
    reversedGroupEvents,
    selectedPlaylist,
    setFullMatchPlaylistDuration,
    setIsPlayinFiltersEpisodes,
    setPlaingOrder,
    setPlayingProgress,
    setReversed,
    setStatsType,
    setUnreversed,
    setWatchAllEpisodesTimer,
    showProfileCard,
    statsType,
    teamsStats,
    toggleActiveEvents,
    toggleActivePlayers,
    togglePopup,
    tournamentData,
    uniqEvents,
    user,
    watchAllEpisodesTimer,
  }
}
