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

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

import { useAuthStore } from 'features/AuthStore'
import { Tabs } from 'features/MatchSidePlaylists/config'
import { initialCircleAnimation } from 'features/CircleAnimationBar'
import type { TCircleAnimation } from 'features/CircleAnimationBar'
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config'

import { PAGES } from 'config/pages'

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

import { usePageParams, useToggle } from 'hooks'

import { redirectToUrl } from 'helpers/redirectToUrl'
import { parseDate } from 'helpers/parseDate'

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

type PlayingData = {
  player: {
    id: number | null,
    paramId: number | null,
  },
  team: {
    id: number | null,
    paramId: number | null,
  },
}

const initPlayingData: PlayingData = {
  player: {
    id: null,
    paramId: null,
  },
  team: {
    id: null,
    paramId: null,
  },
}

const ACCESS_TIME = 60

export const useMatchPage = () => {
  const [matchProfile, setMatchProfile] = useState<MatchInfo>(null)
  const [watchAllEpisodesTimer, setWatchAllEpisodesTimer] = useState(false)
  const [access, setAccess] = useState(true)
  const [playingProgress, setPlayingProgress] = useState(0)
  const [playingData, setPlayingData] = useState<PlayingData>(initPlayingData)
  const [plaingOrder, setPlaingOrder] = useState(0)
  const [isPlayFilterEpisodes, setIsPlayingFiltersEpisodes] = useState(false)
  const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.WATCH)
  const [circleAnimation, setCircleAnimation] = useState<TCircleAnimation>(initialCircleAnimation)

  const isStatsTab = selectedTab === Tabs.STATS

  const { profileId: matchId, sportType } = usePageParams()

  useEffect(() => {
    sessionStorage.removeItem('isFromLanding')
  }, [])

  const {
    isFromLanding,
    setIsFromLanding,
    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,
    isFirstTeamPlayersChecked,
    isOpen: isOpenFiltersPopup,
    isSecondTeamPlayersChecked,
    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(() => {
    if (user || isFromLanding) return
    getLandingStatus({ matchId, sportType })
      .then(({ landing_id }) => {
        setIsFromLanding(false)
        if (landing_id) redirectToUrl(`${PAGES.landing}/${landing_id}`)
      })
  }, [
    isFromLanding,
    matchId,
    setIsFromLanding,
    sportType,
    user,
  ])

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

  const disablePlayingEpisodes = () => {
    setIsPlayingFiltersEpisodes(false)
    setWatchAllEpisodesTimer(false)
    setCircleAnimation(initialCircleAnimation)
  }

  const {
    circleAnimation: statsCircleAnimation,
    filteredEvents: statsFilteredEvents,
    isExpanded,
    isPlayersStatsFetching,
    isPlayFilterEpisodes: isStatsPlayFilterEpisodes,
    isTeamsStatsFetching,
    plaingOrder: statsPlaingOrder,
    playEpisodes: playStatsEpisodes,
    playNextEpisode: playStatsNextEpisode,
    reduceTable,
    selectedStatsTable,
    setCircleAnimation: setStatsCircleAnimation,
    setIsPlayersStatsFetching,
    setIsPlayingFiltersEpisodes: setStatsIsPlayinFiltersEpisodes,
    setIsTeamsStatsFetching,
    setPlaingOrder: setStatsPlaingOrder,
    setSelectedStatsTable,
    setStatsType,
    setWatchAllEpisodesTimer: setStatsWatchAllEpisodesTimer,
    statsType,
    toggleIsExpanded,
    toggleStatsType,
    watchAllEpisodesTimer: statsWatchAllEpisodesTimer,
  } = useStatsTab({
    disablePlayingEpisodes,
    handlePlaylistClick,
    matchProfile,
    selectedPlaylist,
  })

  const {
    beforeCloseTourCallback: beforeCloseTourCallbackTeams,
    getFirstClickableParam,
    isClickable,
    teamsStats,
  } = useTeamsStats({
    matchProfile,
    playingProgress,
    selectedPlaylist,
    setIsTeamsStatsFetching,
    statsType,
  })

  const {
    beforeCloseTourCallback: beforeCloseTourCallbackPlayers,
    getParams,
    isEmptyPlayersStats,
    playersData,
    playersStats,
  } = usePlayersStats({
    matchProfile,
    playingProgress,
    selectedPlaylist,
    setIsPlayersStatsFetching,
    statsType,
  })

  const beforeCloseTourCallback = () => {
    beforeCloseTourCallbackPlayers()
    beforeCloseTourCallbackTeams()

    setStatsType(profile?.live ? StatsType.CURRENT_STATS : StatsType.FINAL_STATS)
    isExpanded && toggleIsExpanded()
  }

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

  const { tournamentData } = useTournamentData(matchProfile)

  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 {
    activeStatus,
    episodesToPlay,
    isLiveMatch,
    likeImage,
    likeToggle,
    reversedGroupEvents,
    setReversed,
    setUnreversed,
  } = useTabEvents({ events: filteredEvents, profile })

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

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

      return
    }
    handlePlaylistClick(episodesToPlay[currentOrder])
    setPlaingOrder(currentOrder + 1)
  }
  const playEpisodes = () => {
    setPlayingData(initPlayingData)
    setStatsWatchAllEpisodesTimer(true)
    setStatsIsPlayinFiltersEpisodes(false)
    setStatsCircleAnimation(initialCircleAnimation)

    if (!watchAllEpisodesTimer) {
      setWatchAllEpisodesTimer(true)
    }

    setIsPlayingFiltersEpisodes(true)

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

  return {
    access,
    activeEvents,
    activeFirstTeamPlayers,
    activeSecondTeamPlayers,
    activeStatus,
    allActionsToggle,
    allPlayersToggle,
    applyFilters,
    beforeCloseTourCallback,
    circleAnimation: isStatsTab ? statsCircleAnimation : circleAnimation,
    closePopup,
    countOfFilters,
    disablePlayingEpisodes,
    events,
    filteredEvents: isStatsTab ? statsFilteredEvents : filteredEvents,
    getFirstClickableParam,
    getParams,
    handlePlaylistClick,
    hideProfileCard,
    isAllActionsChecked,
    isClickable,
    isEmptyFilters,
    isEmptyPlayersStats,
    isExpanded,
    isFirstTeamPlayersChecked,
    isLiveMatch,
    isOpenFiltersPopup,
    isPlayFilterEpisodes: isStatsTab ? isStatsPlayFilterEpisodes : isPlayFilterEpisodes,
    isPlayersStatsFetching,
    isSecondTeamPlayersChecked,
    isStarted,
    isTeamsStatsFetching,
    likeImage,
    likeToggle,
    matchPlaylists,
    plaingOrder: isStatsTab ? statsPlaingOrder : plaingOrder,
    playEpisodes,
    playNextEpisode: isStatsTab ? playStatsNextEpisode : playNextEpisode,
    playStatsEpisodes,
    playersData,
    playersStats,
    playingData,
    playingProgress,
    profile,
    profileCardShown,
    reduceTable,
    reversedGroupEvents,
    selectedPlaylist,
    selectedStatsTable,
    selectedTab,
    setCircleAnimation: isStatsTab ? setStatsCircleAnimation : setCircleAnimation,
    setFullMatchPlaylistDuration,
    setIsPlayingFiltersEpisodes: isStatsTab
      ? setStatsIsPlayinFiltersEpisodes
      : setIsPlayersStatsFetching,
    setPlaingOrder: isStatsTab ? setStatsPlaingOrder : setPlaingOrder,
    setPlayingData,
    setPlayingProgress,
    setReversed,
    setSelectedStatsTable,
    setSelectedTab,
    setStatsType,
    setUnreversed,
    setWatchAllEpisodesTimer: isStatsTab ? setStatsWatchAllEpisodesTimer : setWatchAllEpisodesTimer,
    showProfileCard,
    statsType,
    teamsStats,
    toggleActiveEvents,
    toggleActivePlayers,
    toggleIsExpanded,
    togglePopup,
    toggleStatsType,
    tournamentData,
    uniqEvents,
    user,
    watchAllEpisodesTimer: isStatsTab ? statsWatchAllEpisodesTimer : watchAllEpisodesTimer,
  }
}
