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

import { format } from 'date-fns'
import map from 'lodash/map'
import sortBy from 'lodash/sortBy'

import { MatchCard } from 'features/MatchCard'
import { TournamentData } from 'features/MatchPage/types'

import { MatchInfo } from 'requests'

import { parseDate } from 'helpers/parseDate'

import { usePageParams } from 'hooks/usePageParams'

import { VideoDate } from './components/VideoDate'
import { MatchesWrapper } from './styled'

type Props = {
  additionalScrollHeight: number,
  profile: MatchInfo,
  tournamentData: TournamentData,
}

const formatDate = (date: Date) => format(date, 'yyyy-MM-dd')

export const Matches = ({
  additionalScrollHeight,
  profile,
  tournamentData,
}: Props) => {
  const { profileId } = usePageParams()

  const profileDate = useMemo(() => (
    format(parseDate(profile?.date!), 'yyyy-MM-dd')
  ), [profile?.date])

  const [selectedDate, setSelectedDate] = useState(profileDate)

  const matches = useMemo(() => (
    tournamentData.matches.filter((match) => (
      formatDate(match.date) === selectedDate && match.id !== profileId
    ))
  ), [profileId, selectedDate, tournamentData.matches])

  const isInitialDateHidden = useMemo(() => {
    const someProfileMatch = tournamentData.matches.find((match) => (
      formatDate(match.date) === profileDate && match.id !== profileId))

    if (!someProfileMatch) {
      const profileDateIndex = tournamentData.matchDates.findIndex((date) => date === profileDate)

      if (profileDateIndex !== 0) {
        setSelectedDate(tournamentData.matchDates[profileDateIndex - 1])
      } else {
        setSelectedDate(tournamentData.matchDates[profileDateIndex + 1])
      }
    }

    return !someProfileMatch
  }, [tournamentData, profileId, profileDate])

  const ref = useRef<HTMLDivElement | null>(null)
  const [overflow, setOverflow] = useState(false)

  useEffect(() => {
    const {
      clientHeight = 0,
      scrollHeight = 0,
    } = ref.current || {}
    const hasScroll = scrollHeight > clientHeight

    setOverflow(hasScroll)
  }, [ref.current?.clientHeight, selectedDate])

  if (tournamentData.matches.length <= 1) return null

  return (
    <Fragment>
      <VideoDate
        isInitialDateHidden={isInitialDateHidden}
        matchDates={tournamentData.matchDates}
        selectedDate={selectedDate}
        profileDate={profileDate}
        onDateClick={setSelectedDate}
      />
      <MatchesWrapper
        ref={ref}
        hasScroll={overflow}
        additionalScrollHeight={additionalScrollHeight}
      >
        {
          map(sortBy(matches, ({ live }) => !live), (match) => (
            <MatchCard
              key={match.id}
              match={match}
            />
          ))
        }
      </MatchesWrapper>
    </Fragment>
  )
}
