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

import throttle from 'lodash/throttle'
import isEmpty from 'lodash/isEmpty'
import every from 'lodash/every'
import find from 'lodash/find'

import type {
  MatchInfo,
  PlayersStats,
  Player,
} from 'requests'
import { getPlayersStats, getMatchParticipants } from 'requests'

import { useObjectState, usePageParams } from 'hooks'

import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config'

const REQUEST_DELAY = 3000
const STATS_POLL_INTERVAL = 30000

type UsePlayersStatsArgs = {
  matchProfile: MatchInfo,
  playingProgress: number,
  statsType: StatsType,
}

type PlayersData = {
  team1: Array<Player>,
  team2: Array<Player>,
}

export const usePlayersStats = ({
  matchProfile,
  playingProgress,
  statsType,
}: UsePlayersStatsArgs) => {
  const [playersStats, setPlayersStats] = useObjectState<Record<string, PlayersStats>>({})
  const [playersData, setPlayersData] = useState<PlayersData>({ team1: [], team2: [] })

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

  const isCurrentStats = statsType === StatsType.CURRENT_STATS

  const progressSec = Math.floor(playingProgress / 1000)

  const isEmptyPlayersStats = (teamId: number) => (
    isEmpty(playersStats[teamId])
      || every(playersStats[teamId], isEmpty)
      || isEmpty(playersData[matchProfile?.team1.id === teamId ? 'team1' : 'team2'])
  )

  const fetchPlayers = useMemo(() => throttle((second?: number) => {
    if (!matchProfile?.team1.id || !matchProfile?.team1.id) return

    try {
      getMatchParticipants({
        matchId,
        second,
        sportType,
      }).then((data) => {
        const team1Players = find(data, { team_id: matchProfile.team1.id })?.players || []
        const team2Players = find(data, { team_id: matchProfile.team2.id })?.players || []

        setPlayersData({
          team1: team1Players,
          team2: team2Players,
        })
      })

    // eslint-disable-next-line no-empty
    } catch (e) {}
  }, REQUEST_DELAY), [
    matchId,
    matchProfile?.team1.id,
    matchProfile?.team2.id,
    sportType,
  ])

  const fetchPlayersStats = useMemo(() => throttle((second?: number) => {
    if (!sportName || !matchProfile?.team1.id || !matchProfile?.team2.id) return

    try {
      getPlayersStats({
        matchId,
        second,
        sportName,
        teamId: matchProfile.team1.id,
      }).then((data) => setPlayersStats({ [matchProfile.team1.id]: data }))

      getPlayersStats({
        matchId,
        second,
        sportName,
        teamId: matchProfile.team2.id,
      }).then((data) => setPlayersStats({ [matchProfile?.team2.id]: data }))
    // eslint-disable-next-line no-empty
    } catch (e) {}
  }, REQUEST_DELAY), [
    matchId,
    matchProfile?.team1.id,
    matchProfile?.team2.id,
    setPlayersStats,
    sportName,
  ])

  useEffect(() => {
    let interval: NodeJS.Timeout

    fetchPlayers()

    if (!isCurrentStats) {
      fetchPlayersStats()
    }

    if (matchProfile?.live) {
      interval = setInterval(() => {
        if (isCurrentStats) return

        fetchPlayersStats()
        fetchPlayers()
      }, STATS_POLL_INTERVAL)
    }

    return () => clearInterval(interval)
  }, [
    fetchPlayersStats,
    fetchPlayers,
    isCurrentStats,
    matchProfile?.live,
  ])

  useEffect(() => {
    if (isCurrentStats) {
      fetchPlayersStats(progressSec)
      fetchPlayers(progressSec)
    }
  }, [
    fetchPlayersStats,
    fetchPlayers,
    progressSec,
    isCurrentStats,
    matchProfile?.live,
  ])

  return {
    isEmptyPlayersStats,
    playersData,
    playersStats,
  }
}
