import {
  useEffect,
  useRef,
  useState,
} from 'react'
import { createPortal } from 'react-dom'
import { useRecoilValue } from 'recoil'

import { useTour } from '@reactour/tour'

import type { PlaylistOption } from 'features/MatchPage/types'
import { totalLikesState, useMatchPageStore } from 'features/MatchPage/store'
import {
  Spotlight,
  Steps,
  TOUR_COMPLETED_STORAGE_KEY,
} from 'features/MatchTour'

import { Overlay } from 'components/Overlay'

import { useEventListener, useModalRoot } from 'hooks'

import { isIOS, isMobileDevice } from 'config/userAgent'

import { getLocalStorageItem } from 'helpers/getLocalStorage'

import { MATCH_ADS } from 'components/Ads/types'

import { Tabs } from './config'
import { TabEvents } from './components/TabEvents'
import { TabWatch } from './components/TabWatch'
import { TabPlayers } from './components/TabPlayers'
import { TabStats } from './components/TabStats'
import { TabLikes } from './components/TabLikes'
import { useMatchSidePlaylists } from './hooks'

import {
  Wrapper,
  TabsWrapper,
  TabsGroup,
  Tab,
  TabIcon,
  TabTitle,
  Container,
  EventsAdsWrapper,
} from './styled'
import { HeaderAds } from '../../components/Ads'

const tabPanes = {
  [Tabs.WATCH]: TabWatch,
  [Tabs.EVENTS]: TabEvents,
  [Tabs.STATS]: TabStats,
  [Tabs.PLAYERS]: TabPlayers,
  [Tabs.LIKES]: TabLikes,
}

type Props = {
  onSelect: (option: PlaylistOption) => void,
  selectedPlaylist?: PlaylistOption,
}

export const MatchSidePlaylists = ({
  onSelect,
  selectedPlaylist,
}: Props) => {
  const likeEvents = useRecoilValue(totalLikesState)

  const {
    ads,
    hideProfileCard,
    matchPlaylists: playlists,
    profile,
    profileCardShown,
    selectedTab,
    showProfileCard,
    tournamentData,
  } = useMatchPageStore()

  const {
    isMatchParsed,
    onTabClick,
  } = useMatchSidePlaylists()

  const {
    currentStep,
    isOpen,
    setIsOpen,
  } = useTour()

  const modalRoot = useModalRoot()

  const TabPane = tabPanes[selectedTab]

  const containerRef = useRef<HTMLDivElement | null>(null)
  const tabPaneContainerRef = useRef<HTMLDivElement | null>(null)
  const tabsGroupRef = useRef<HTMLDivElement | null>(null)

  const [hasTabPaneScroll, setTabPaneScroll] = useState(false)

  const { PLAYS_TOP, PLAYS_TOP_MOBILE } = MATCH_ADS
  const adsPositionId = isMobileDevice ? PLAYS_TOP_MOBILE : PLAYS_TOP

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

    setTabPaneScroll(hasScroll)
  }, [
    playlists,
    selectedTab,
    tabPaneContainerRef.current?.clientHeight,
  ])

  useEffect(() => {
    if (
      getLocalStorageItem(TOUR_COMPLETED_STORAGE_KEY) === 'true'
        || isOpen
        || !isMatchParsed
        || Number(profile?.c_match_calc_status) < 2
    ) return undefined

    const timer = setTimeout(() => setIsOpen(true), 1500)

    return () => clearTimeout(timer)
  }, [isMatchParsed, setIsOpen, profile?.c_match_calc_status, isOpen])

  useEventListener({
    callback: () => {
      const screenLandscape = isIOS ? window.orientation : window.screen.orientation.type
      const yOffset = containerRef.current?.scrollTop
      const isScreenLandscape = isIOS
        ? (screenLandscape === 90 || screenLandscape === -90)
        : (screenLandscape === 'landscape-primary' || screenLandscape === 'landscape-secondary')

      if (Number(yOffset) < 10) showProfileCard()
      if (Number(yOffset) > 10 && !isScreenLandscape) hideProfileCard()
    },
    event: 'scroll',
    target: containerRef,
  })

  const getTabsSpace = () => {
    const tabsGroup = tabsGroupRef.current

    const tabsWidth = isMobileDevice && containerRef.current
      ? containerRef.current.clientWidth - 20
      : 306

    return tabsGroup?.children.length && tabsGroup.children.length > 1
      ? (tabsWidth - (Array.from(tabsGroup.children) as Array<HTMLButtonElement>)
        .reduce((acc, elem) => acc + elem.clientWidth, 0)) / tabsGroup.children.length - 1
      : 0
  }

  return (
    <Wrapper
      ref={containerRef}
      data-step={Steps.Welcome}
      highlighted={Boolean(isOpen) && currentStep === Steps.Welcome}
      isTourOpen={Boolean(isOpen)}
      isHidden={!profileCardShown}
    >
      <TabsWrapper>
        {selectedTab === Tabs.EVENTS
              && ads
              && (
                <EventsAdsWrapper hasScroll={hasTabPaneScroll}>
                  <HeaderAds ads={ads.filter(({ position }) => position.id === adsPositionId)} />
                </EventsAdsWrapper>
              )}
        <TabsGroup
          ref={tabsGroupRef}
          space={getTabsSpace()}
        >
          {(isMatchParsed || likeEvents.length > 0) && (
            <Tab
              aria-pressed={selectedTab === Tabs.WATCH}
              onClick={() => onTabClick(Tabs.WATCH)}
              id='match_watch'
            >
              <TabIcon icon='watch' />
              <TabTitle t='watch' />
            </Tab>
          )}
          {isMatchParsed && (
            <Tab
              aria-pressed={selectedTab === Tabs.EVENTS}
              onClick={() => onTabClick(Tabs.EVENTS)}
              id='match_plays'
            >
              <TabIcon icon='plays' />
              <TabTitle t='actions' />
            </Tab>
          )}
          {likeEvents.length > 0 && (
            <Tab
              aria-pressed={selectedTab === Tabs.LIKES}
              onClick={() => onTabClick(Tabs.LIKES)}
              id='match_likes'
            >
              <TabIcon icon='likes' />
              <TabTitle t='likes' />
            </Tab>
          )}
          {isMatchParsed && (
            <Tab
              aria-pressed={selectedTab === Tabs.PLAYERS}
              onClick={() => onTabClick(Tabs.PLAYERS)}
              id='match_players'
            >
              <TabIcon icon='players' />
              <TabTitle t='players' />
            </Tab>
          )}
          {isMatchParsed && (
            <Tab
              aria-pressed={selectedTab === Tabs.STATS}
              onClick={() => onTabClick(Tabs.STATS)}
              data-step={Steps.Start}
              id='match_stats'
            >
              {Boolean(currentStep === Steps.Start && isOpen) && (
                <Spotlight />
              )}
              <TabIcon icon='stats' />
              <TabTitle t='stats' />
            </Tab>
          )}
        </TabsGroup>
      </TabsWrapper>
      <Container
        hasScroll={hasTabPaneScroll}
        ref={tabPaneContainerRef}
        forWatchTab={selectedTab === Tabs.WATCH}
        highlighted={Boolean(isOpen)}
      >
        <TabPane
          tournamentData={tournamentData}
          onSelect={onSelect}
          playlists={playlists}
          profile={profile}
          selectedPlaylist={selectedPlaylist}
        />
      </Container>
      {modalRoot.current && isOpen && createPortal(
        <Overlay />,
        modalRoot.current,
      )}
    </Wrapper>
  )
}
