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

import find from 'lodash/find'
import forEach from 'lodash/forEach'
import { reduce } from 'lodash'

import type { ObjectWithName } from 'features/Name'

import {
  FavoritesActions,
  UserFavorites,
  modifyUserFavorites,
  getUserFavorites,
} from 'requests'

import { useToggle } from 'hooks/useToggle'

import { ProfileTypes, SportTypes } from 'config'

import { useAuthStore } from '../../AuthStore'

type ProfileType = {
  profile: ObjectWithName & {
    additionalInfo: ObjectWithName & {
      id: number,
      tournamentId?: number,
    },
    id: number,
  },
  sportType: number,
}

export type SuperTournament = ObjectWithName & {
  sport: SportTypes,
  type: ProfileTypes,
}

type Args = Parameters<typeof modifyUserFavorites>[0]

export const useUserFavorites = () => {
  const { user, userInfo } = useAuthStore()
  const [userFavorites, setUserFavorites] = useState<UserFavorites>([])
  const [playerHighlight, setPlayerHighlight] = useState<ProfileType>({} as ProfileType)

  const {
    close,
    isOpen,
    open,
  } = useToggle()

  const superTournaments = useMemo(() => {
    const uniqueTournamnetIds: Record<number, number> = {}

    return reduce(
      userFavorites,
      (acc, item) => {
        if (
          item?.info?.super_tournament
          && !uniqueTournamnetIds[item.info.super_tournament.id]
        ) {
          uniqueTournamnetIds[item.info.super_tournament.id] = item.info.super_tournament.id
          acc.push({
            ...item.info.super_tournament,
            sport: item.sport,
            type: ProfileTypes.SUPERTOURNAMENTS,
          })
        }
        return acc
      },
      [] as Array<SuperTournament>,
    )
  }, [userFavorites])

  const fetchFavorites = useCallback(() => {
    getUserFavorites().then((value) => {
      if (Array.isArray(value)) {
        setUserFavorites(value)
      }
    })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [userInfo?.email])

  const removeSuperTournament = (id: number) => {
    forEach(userFavorites, (item) => {
      if (item.info.super_tournament?.id === id) {
        addRemoveFavorite({
          action: FavoritesActions.REMOVE,
          id: item.id,
          sport: item.sport,
          type: item.type,
        })
      }
    })
  }

  useEffect(() => {
    if (!user) return

    fetchFavorites()

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [fetchFavorites])

  const addRemoveFavorite = (args: Args) => {
    modifyUserFavorites(args).then(setUserFavorites, open)
  }

  const isInFavorites = (profileType: ProfileTypes, profileId: number) => (
    Boolean(find(userFavorites, { id: profileId, type: profileType }))
  )

  return {
    addRemoveFavorite,
    close,
    fetchFavorites,
    isInFavorites,
    isOpen,
    open,
    playerHighlight,
    removeSuperTournament,
    setPlayerHighlight,
    superTournaments,
    userFavorites,
  }
}
