import { useEffect, useState, useMemo, } from 'react' import { useHistory } from 'react-router' import includes from 'lodash/includes' import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' import { PAGES } from 'config' 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 { PlaylistTypes } from 'features/MatchPage/types' import { FULL_GAME_KEY } from 'features/MatchPage/helpers/buildPlaylists' 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 { useAds } from 'components/Ads/hooks' 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' import { useLexicsStore } from '../../../LexicsStore' type PlayingData = { player: { id: number | null, paramId: number | null, }, team: { id: number | null, paramId: number | null, }, } type EpisodeInfo = { episodesCount?: number, paramName?: string, playerOrTeamName?: string, } const initPlayingData: PlayingData = { player: { id: null, paramId: null, }, team: { id: null, paramId: null, }, } const ACCESS_TIME = 60 export const useMatchPage = () => { const [matchProfile, setMatchProfile] = useState(null) const [watchAllEpisodesTimer, setWatchAllEpisodesTimer] = useState(false) const [isFullscreen, setIsFullScreen] = useState(false) const [access, setAccess] = useState(true) const [playingProgress, setPlayingProgress] = useState(0) const [playingData, setPlayingData] = useState(initPlayingData) const [playingOrder, setPlaingOrder] = useState(0) const [isPlayFilterEpisodes, setIsPlayingFiltersEpisodes] = useState(false) const [selectedTab, setSelectedTab] = useState(Tabs.WATCH) const [circleAnimation, setCircleAnimation] = useState(initialCircleAnimation) const [episodeInfo, setEpisodeInfo] = useState({ episodesCount: 0, paramName: '', playerOrTeamName: '', }) const { suffix } = useLexicsStore() const { profileId: matchId, sportType } = usePageParams() const { ads } = useAds({ matchId, sportType, tournamentId: matchProfile?.tournament?.id, }) useEffect(() => { sessionStorage.removeItem('isFromLanding') }, []) const { isFromLanding, landingUrlFrom, setIsFromLanding, setLandingUrlFrom, user, userInfo, } = useAuthStore() const history = useHistory() const { close: hideProfileCard, isOpen: profileCardShown, open: showProfileCard, } = useToggle(true) const { events, handlePlaylistClick, matchPlaylists, selectedPlaylist, setFullMatchPlaylistDuration, } = useMatchData({ matchProfile, selectedTab }) const profile = matchProfile const isPlayingEpisode = selectedPlaylist.id !== FULL_GAME_KEY const isStatsPlaylist = selectedPlaylist.tab === Tabs.STATS 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 || history.length > 1) return setLandingUrlFrom(window.location.pathname) getLandingStatus({ matchId, sportType }) .then((data) => { sessionStorage.setItem( 'landingData', JSON.stringify({ ...data, defaultLanding: false }), ) setIsFromLanding(false) if (data.landing_id) redirectToUrl(`${PAGES.landing}/${data.landing_id}`) }) .catch(() => { getMatchInfo(sportType, matchId).then((data) => { sessionStorage.setItem('landingData', JSON.stringify({ defaultLanding: true, sportType, tournamentId: data?.tournament.id, })) redirectToUrl(` ${PAGES.landing}/default ?season=${data?.season.name} &tournament=${data?.tournament[`name_${suffix}`]}`) }) }) // eslint-disable-next-line react-hooks/exhaustive-deps }, [ setLandingUrlFrom, isFromLanding, landingUrlFrom, matchId, setIsFromLanding, sportType, user, ]) useEffect(() => { getMatchInfo(sportType, matchId).then( (info) => (info?.sport // проверяем именно какой-то ключ в объекте, // потому что, когда матча не существует, приходит - [] ? setMatchProfile(info) : window.location.replace(PAGES.home)), ) }, [sportType, matchId]) useEffect(() => { let getIntervalMatch: ReturnType 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 disablePlayingStatsEpisodes = () => { setStatsIsPlayinFiltersEpisodes(false) setStatsWatchAllEpisodesTimer(false) setStatsCircleAnimation(initialCircleAnimation) setStatsPlaingOrder(0) } const disablePlayingPlaysEpisodes = () => { setIsPlayingFiltersEpisodes(false) setWatchAllEpisodesTimer(false) setCircleAnimation(initialCircleAnimation) setPlaingOrder(0) } const disablePlayingEpisodes = () => { isStatsPlaylist ? disablePlayingStatsEpisodes() : disablePlayingPlaysEpisodes() } useEffect(() => { if (selectedPlaylist.type !== PlaylistTypes.EVENT) { disablePlayingStatsEpisodes() disablePlayingPlaysEpisodes() } else { !isStatsPlaylist ? disablePlayingStatsEpisodes() : disablePlayingPlaysEpisodes() } // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedPlaylist]) const { circleAnimation: statsCircleAnimation, filteredEvents: statsFilteredEvents, isExpanded, isPlayersStatsFetching, isPlayFilterEpisodes: isStatsPlayFilterEpisodes, isTeamsStatsFetching, playEpisodes: playStatsEpisodes, playingOrder: statsPlaingOrder, 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, selectedStatsTable, selectedTab, setIsTeamsStatsFetching, statsType, }) const { beforeCloseTourCallback: beforeCloseTourCallbackPlayers, getParams, playersData, playersStats, } = usePlayersStats({ matchProfile, playingProgress, selectedStatsTable, selectedTab, 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 = playingOrder === episodesToPlay.length const currentOrder = order === 0 ? order : playingOrder if (isLastEpisode || !episodesToPlay[currentOrder]) { setIsPlayingFiltersEpisodes(false) setPlaingOrder(0) return } handlePlaylistClick({ playlist: episodesToPlay[currentOrder], tab: Tabs.EVENTS, }) setPlaingOrder(currentOrder + 1) } const playEpisodes = () => { setPlayingData(initPlayingData) setStatsWatchAllEpisodesTimer(true) setStatsIsPlayinFiltersEpisodes(false) setStatsCircleAnimation(initialCircleAnimation) if (!watchAllEpisodesTimer) { setWatchAllEpisodesTimer(true) } setIsPlayingFiltersEpisodes(true) playNextEpisode(0) } return { access, activeEvents, activeFirstTeamPlayers, activeSecondTeamPlayers, activeStatus, ads, allActionsToggle, allPlayersToggle, applyFilters, beforeCloseTourCallback, circleAnimation: isStatsPlaylist ? statsCircleAnimation : circleAnimation, closePopup, countOfFilters, disablePlayingEpisodes, episodeInfo, events, filteredEvents: isStatsPlaylist ? statsFilteredEvents : filteredEvents, getFirstClickableParam, getParams, handlePlaylistClick, hideProfileCard, isAllActionsChecked, isClickable, isEmptyFilters, isExpanded, isFirstTeamPlayersChecked, isFullscreen, isLiveMatch, isOpenFiltersPopup, isPlayFilterEpisodes: isStatsPlaylist ? isStatsPlayFilterEpisodes : isPlayFilterEpisodes, isPlayersStatsFetching, isPlayingEpisode, isSecondTeamPlayersChecked, isStarted, isTeamsStatsFetching, likeImage, likeToggle, matchPlaylists, playEpisodes, playNextEpisode: isStatsPlaylist ? playStatsNextEpisode : playNextEpisode, playStatsEpisodes, playersData, playersStats, playingData, playingOrder: isStatsPlaylist ? statsPlaingOrder : playingOrder, playingProgress, profile, profileCardShown, reduceTable, reversedGroupEvents, selectedPlaylist, selectedStatsTable, selectedTab, setCircleAnimation: isStatsPlaylist ? setStatsCircleAnimation : setCircleAnimation, setEpisodeInfo, setFullMatchPlaylistDuration, setIsFullScreen, setIsPlayingFiltersEpisodes: isStatsPlaylist ? setStatsIsPlayinFiltersEpisodes : setIsPlayersStatsFetching, setMatchProfile, setPlaingOrder: isStatsPlaylist ? setStatsPlaingOrder : setPlaingOrder, setPlayingData, setPlayingProgress, setReversed, setSelectedStatsTable, setSelectedTab, setStatsType, setUnreversed, setWatchAllEpisodesTimer: isStatsPlaylist ? setStatsWatchAllEpisodesTimer : setWatchAllEpisodesTimer, showProfileCard, statsType, teamsStats, toggleActiveEvents, toggleActivePlayers, toggleIsExpanded, togglePopup, toggleStatsType, tournamentData, uniqEvents, user, watchAllEpisodesTimer: isStatsPlaylist ? statsWatchAllEpisodesTimer : watchAllEpisodesTimer, } }