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

import type { MatchesBySection } from 'requests'

import { useRequest } from 'hooks'

import { usePreferencesStore } from 'features/PreferencesPopup'
import { isMobileDevice } from 'config/userAgent'

import { prepareMatches } from './helpers/prepareMatches'

import { useAuthStore } from '../AuthStore'

export type Match = ReturnType<typeof prepareMatches>[number]

export type Props = {
  fetch: (limit: number, offset: number) => Promise<MatchesBySection>,
}

const MATCHES_LIMIT = 1000

const initialState = {
  broadcast: [],
  features: [],
  hasNextPage: true,
  highlights: [],
  isVideoSections: false,
}

export const useMatches = ({ fetch }: Props) => {
  const { userPreferences } = usePreferencesStore()
  const { user } = useAuthStore()
  const {
    isFetching,
    request: requestMatches,
  } = useRequest(fetch)

  const pageRef = useRef(0)
  const [matches, setMatches] = useState<MatchesBySection>(initialState)

  const { hasNextPage } = matches

  const fetchMatches = useCallback((page: number) => (
    requestMatches(MATCHES_LIMIT, page * MATCHES_LIMIT)
  ), [requestMatches])

  const fetchMoreMatches = useCallback(async () => {
    if (!hasNextPage || isFetching) return

    const newMatches = await fetchMatches(pageRef.current)
    setMatches((oldMatches) => {
      const broadcast = [...oldMatches.broadcast, ...newMatches.broadcast]
      return {
        ...oldMatches,
        broadcast,
        hasNextPage: newMatches.hasNextPage,
      }
    })
    pageRef.current += 1
  }, [
    fetchMatches,
    hasNextPage,
    isFetching,
  ])

  useEffect(() => {
    const isDefaultUrl = window.location.href.slice(0, -1) === window.location.origin

    if (!isDefaultUrl) {
      fetchMatches(0).then(setMatches)
      pageRef.current = 1
    }

    return () => {
      setMatches(initialState)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [fetchMatches, userPreferences])

  const preparedMatches = useMemo(() => ({
    broadcast: prepareMatches(matches.broadcast, user),
    features: prepareMatches(matches.features, user),
    highlights: prepareMatches(matches.highlights, user),
    isVideoSections: matches.isVideoSections,
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }), [matches])

  return {
    fetchMoreMatches: isMobileDevice ? fetchMoreMatches : () => {},
    isFetching,
    matches: preparedMatches,
  }
}
