import React, { useContext, useState } from 'react'
import { View } from 'react-native'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { DateListItem } from '../components/DateListItem'
import { HeaderNav } from '../components/HeaderNav'
import { Item, StreamsListItem } from '../components/StreamsListItem'
import {
  sortByChangePercentage,
  sortByName,
  sortByReleaseDate,
  sortByStreams,
} from '../components/TrackList'
import { ScreenNames } from '../constants/ScreenNames'
import { ArtistContext } from '../contexts/ArtistContext'
import {
  EventType,
  sendAnalyticsEvent,
  useAnalytics,
} from '../hooks/useAnalytics'
import { useTracksScreenData } from '../hooks/useTracksScreenData'
import { Strings } from '../i18n'
import { ReactNavigationProps } from '../Navigation'
import { getTracksWithAllDsp } from '../streams'
import { Mode } from '../types/helpers'
import { defaultTimeInterval, TimeInterval } from '../types/TimeInterval'
import { DspSlug } from '../types/types'
import {
  FilterFn,
  SortFn,
  TrackListStreamsTab,
} from './tabs/TrackListStreamsTab'

const TracksScreenModes = [
  'streams',
  'release',
  'all',
  'favorites',
  'trending',
] as const
export type TracksScreenModes = typeof TracksScreenModes[number]

const screen = 'Tracks Screen'

export const TracksScreen: React.FC<
  ReactNavigationProps<ScreenNames.Tracks>
> = ({ navigation, route }) => {
  const artist = useContext(ArtistContext)
  const [timeInterval, setTimeInterval] =
    useState<TimeInterval>(defaultTimeInterval)

  const modeOptions: Record<
    TracksScreenModes,
    {
      title: string
      sortFn: SortFn
      filterFn?: FilterFn
      showDspSelector: boolean
      analyticsTabName: string
      ListItem: React.FC<Item>
      displayRank: boolean
    }
  > = {
    [Mode.STREAMS]: {
      title: Strings.Shared.MostStreamed,
      sortFn: sortByStreams,
      showDspSelector: true,
      analyticsTabName: 'Streams',
      ListItem: StreamsListItem,
      displayRank: true,
    },
    [Mode.RELEASE]: {
      title: Strings.Shared.NewestReleases,
      sortFn: sortByReleaseDate,
      showDspSelector: false,
      analyticsTabName: 'Release Date',
      ListItem: DateListItem,
      displayRank: false,
    },
    [Mode.ALL]: {
      title: Strings.Shared.AllTracks,
      sortFn: sortByName,
      showDspSelector: true,
      analyticsTabName: 'All',
      ListItem: StreamsListItem,
      displayRank: false,
    },
    [Mode.FAVORITES]: {
      title: Strings.Shared.Favorites,
      sortFn: sortByName,
      filterFn: (track) => track.track.isFavorite,
      showDspSelector: false,
      analyticsTabName: 'Favorites',
      ListItem: StreamsListItem,
      displayRank: false,
    },
    [Mode.TRENDING]: {
      title: Strings.Shared.TopTrending,
      sortFn: sortByChangePercentage,
      filterFn: (track) =>
        track.changePercentage ? track.changePercentage >= 1 : false,
      showDspSelector: true,
      analyticsTabName: 'Trending',
      ListItem: StreamsListItem,
      displayRank: false,
    },
  }

  const options = modeOptions[route.params.mode as TracksScreenModes]
  const { data, showToast, refreshControl } = useTracksScreenData(
    timeInterval,
    () =>
      sendAnalyticsEvent(EventType.PULL_TO_REFRESH, {
        artist_selected: artist.name,
        timeframe_selected: timeInterval,
        page: 'Tracks Screen',
        subject: 'user',
        verb: 'refreshed',
        object: 'tracks',
      })
  )

  const tracksWithAll = data?.tracks
    ? getTracksWithAllDsp(data.tracks)
    : undefined

  return (
    <CommonScreenContainer>
      <HeaderNav
        title={options.title}
        showToast={showToast}
        navigation={navigation}
        style={{
          zIndex: 10,
        }}
        timeInterval={timeInterval}
        setTimeInterval={setTimeInterval}
      />
      <View
        style={{
          flex: 1,
          paddingHorizontal: 8,
        }}
      >
        <TrackListStreamsTab
          tracks={tracksWithAll}
          onPressTrack={(isrc: string) =>
            navigation.navigate(ScreenNames.Track, {
              isrc,
            })
          }
          refreshControl={refreshControl}
          onLoad={(dsp: DspSlug) =>
            useAnalytics(
              EventType.TAB_VIEWED,
              {
                screen,
                dsp,
                tab: options.analyticsTabName,
                subject: 'user',
                verb: 'viewed',
                object: 'dsp',
              },
              true,
              timeInterval
            )
          }
          {...options}
        />
      </View>
    </CommonScreenContainer>
  )
}
