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

import find from 'lodash/find'
import isEmpty from 'lodash/isEmpty'
import first from 'lodash/first'
import size from 'lodash/size'

import { getSubscriptions, SubscriptionsByPeriods } from 'requests'

import { useLexicsStore } from 'features/LexicsStore'

import type {
  MatchSubscriptions,
  MatchSubscription,
  Match,
} from '../../types'
import { SubscriptionType } from '../../types'
import { transformSubsciptions } from '../helpers'
import { useSubscriptionsLexics } from './useSubscriptionsLexics'

const defaultSubscriptions: MatchSubscriptions = {
  [SubscriptionType.Month]: [],
  [SubscriptionType.Year]: [],
  [SubscriptionType.PayPerView]: [],
}

export const useSubscriptions = () => {
  const { suffix } = useLexicsStore()
  const { fetchLexics } = useSubscriptionsLexics()

  const [selectedPeriod, setSelectedPeriod] = useState(SubscriptionType.Month)
  const [matchSubscriptions, setMatchSubscriptionsList] = useState(defaultSubscriptions)
  const [selectedSubscription, setSelectedSubscription] = useState<MatchSubscription | null>(null)
  const [
    initialSubscription, setInitialSubscription,
  ] = useState<SubscriptionsByPeriods | null>(null)
  const [
    selectedSubscriptionPackage, setSelectedSubscriptionPackage,
  ] = useState<SubscriptionsByPeriods | null>(null)

  const fetchSubscriptions = useCallback(async (match: Match) => {
    const subscriptions = await getSubscriptions(match.sportType, match.id)
    const subscriptionData = subscriptions.data && size(subscriptions.data) === 1
      ? {
        ...subscriptions.data[0].packages,
        season: subscriptions.season,
      }
      : subscriptions
    if (!subscriptions.data || size(subscriptions.data) === 1) {
      const convertedSubscriptions = transformSubsciptions({
        match,
        subscriptions: subscriptionData,
        suffix,
      })
      setInitialSubscription(subscriptions)
      setMatchSubscriptionsList(convertedSubscriptions)
      const firstSubscription = find(
        convertedSubscriptions, (subscription) => !isEmpty(subscription),
      )
      setSelectedPeriod(first(firstSubscription)?.type || SubscriptionType.Month)
    } else {
      setInitialSubscription(subscriptions)
      fetchLexics(subscriptions.data)
    }
  }, [fetchLexics, suffix])

  const fetchSubscriptionsPackages = useCallback((match) => {
    if (selectedSubscriptionPackage) {
      const convertedSubscriptions = transformSubsciptions({
        match,
        subscriptions: selectedSubscriptionPackage,
        suffix,
      })
      setInitialSubscription(selectedSubscriptionPackage)
      setMatchSubscriptionsList(convertedSubscriptions)
      const firstSubscription = find(
        convertedSubscriptions, (subscription) => !isEmpty(subscription),
      )
      setSelectedPeriod(first(firstSubscription)?.type || SubscriptionType.Month)
    }
  }, [selectedSubscriptionPackage, suffix])

  const resetSubscriptions = useCallback(() => {
    setSelectedSubscription(null)
    setMatchSubscriptionsList(defaultSubscriptions)
  }, [])

  const onSubscriptionSelect = (subscription: MatchSubscription) => {
    setSelectedSubscription(subscription === selectedSubscription ? null : subscription)
  }

  const onSubscriptionPackagesSelect = (packages: SubscriptionsByPeriods) => {
    setSelectedSubscriptionPackage(packages === selectedSubscriptionPackage ? null : packages)
  }

  useEffect(() => {
    const isOnlySubscriptionVariant = matchSubscriptions[selectedPeriod].length === 1
    if (isOnlySubscriptionVariant) {
      setSelectedSubscription(matchSubscriptions[selectedPeriod][0])
    } else {
      setSelectedSubscription(null)
    }
  }, [matchSubscriptions, selectedPeriod])

  return {
    fetchSubscriptions,
    fetchSubscriptionsPackages,
    initialSubscription,
    matchSubscriptions,
    onPeriodSelect: setSelectedPeriod,
    onSubscriptionPackagesSelect,
    onSubscriptionSelect,
    resetSubscriptions,
    selectedPeriod,
    selectedSubscription,
    selectedSubscriptionPackage,
    setSelectedSubscriptionPackage,
    subscriptions: matchSubscriptions[selectedPeriod],
  }
}
