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

import includes from 'lodash/includes'
import isEmpty from 'lodash/isEmpty'
import filter from 'lodash/filter'
import remove from 'lodash/remove'
import every from 'lodash/every'
import find from 'lodash/find'
import map from 'lodash/map'

import type { Tournament, Tournaments } from 'requests/getSportTournaments'
import type { UserPreferences } from 'requests/getUserPreferences'

export const useSelectedTournaments = (
  selectedSports: Array<number>,
  tournaments: Tournaments,
) => {
  const [selectedTournaments, setSelectedTournaments] = useState<UserPreferences>([])

  const isTournamentSelected = useCallback(({ id, sport }: Tournament) => (
    Boolean(find(
      selectedTournaments,
      { sport, tournament_id: id },
    ))
  ), [selectedTournaments])

  const onTournamentSelect = useCallback((tournament: Tournament) => {
    const preference = { sport: tournament.sport, tournament_id: tournament.id }
    if (isTournamentSelected(tournament)) {
      remove(selectedTournaments, preference)
      setSelectedTournaments([...selectedTournaments])
    } else {
      setSelectedTournaments([...selectedTournaments, preference])
    }
  }, [isTournamentSelected, selectedTournaments])

  const allTournamentsSelected = useMemo(
    () => {
      if (isEmpty(tournaments)) return false

      return every(tournaments, isTournamentSelected)
    },
    [isTournamentSelected, tournaments],
  )

  const onSelectAllTournaments = () => {
    const newSelectedTournaments = allTournamentsSelected
      ? []
      : map(
        tournaments,
        ({ id, sport }) => ({ sport, tournament_id: id }),
      )
    setSelectedTournaments(newSelectedTournaments)
  }

  useEffect(() => {
    setSelectedTournaments((oldTournaments) => (
      filter(oldTournaments, ({ sport }) => includes(selectedSports, sport))
    ))
  }, [selectedSports])

  return {
    allTournamentsSelected,
    isTournamentSelected,
    onSelectAllTournaments,
    onTournamentSelect,
    selectedTournaments,
    setInitialSelectedTournaments: setSelectedTournaments,
  }
}
