import React, { useContext } from 'react'
import { Animated, StyleProp, StyleSheet, View, ViewStyle } from 'react-native'

import { colors, DspColors } from '../Colors'
import { ChartDsp, chartDsps, StreamingDsp, streamingDsps } from '../Consts'
import { ReactNavigationProps } from '../Navigation'
import { spaces } from '../Spaces'
import { EntityScreenStyles } from '../Styles'
import { ArtistStreamsDemographicsCarousel } from '../components/ArtistStreamsDemographicsCarousel'
import { Carousel } from '../components/Carousel'
import { CenteredActivityIndicator } from '../components/CenteredActivityIndicator'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { CountryIcon } from '../components/CountryIconAndName'
import { EntityScreenHeader } from '../components/EntityScreenHeader'
import {
  ReleaseToDateTableRow,
  TimeIntervalTableRows,
} from '../components/EntityStreamsTable'
import { EntityStreamsTile } from '../components/EntityStreamsTile'
import { ErrorBoundary } from '../components/ErrorBoundary'
import { HeaderNav } from '../components/HeaderNav'
import { MarketChartTrackPositionsTile } from '../components/MarketChartTrackPositionsTile'
import { MarketTopTracksTile } from '../components/MarketTopTracksTile'
import { ScreenNames } from '../constants/ScreenNames'
import { ArtistContext } from '../contexts/ArtistContext'
import { ScreenContext } from '../contexts/ScreenContext'
import { EventType, sendAnalyticsEvent } from '../hooks/useAnalytics'
import { useArtistStreams } from '../hooks/useArtistStreams'
import { useRegions } from '../hooks/useRegions'
import { useScreenRefreshControl } from '../hooks/useScreenRefreshControl'
import { Strings } from '../i18n'
import { TimeInterval } from '../types/TimeInterval'
import { Track } from '../types/Track'
import { Dsp } from '../types/types'
import { useAnimateTitleOpacity, formatCountryName } from '../util'

const screenName = 'Market Screen'

const styles = StyleSheet.create({
  tile: { flex: 1, marginHorizontal: spaces.insets.medium },
  carousel: { marginHorizontal: -spaces.insets.medium },
  carouselIndicator: {
    paddingTop: 16,
    paddingBottom: 16,
  },
})

const MarketStreamsCarousel: React.FC<{
  timeInterval: TimeInterval
  countryCode: string
  onPressItem: (item: StreamingDsp | 'all') => void
  onSwipe: (item: StreamingDsp | 'all') => void
}> = ({ timeInterval, onPressItem, countryCode, onSwipe }) => (
  <Carousel<StreamingDsp | 'all'>
    items={['all', ...streamingDsps]}
    renderItem={({ item }) => {
      const useEntityStreams = (interval: Interval) =>
        useArtistStreams(interval, item, countryCode)

      return (
        <EntityStreamsTile
          key={item}
          dsp={item}
          timeInterval={timeInterval}
          onPress={() => onPressItem(item)}
          useEntityStreams={useEntityStreams}
          title={Strings.Shared.Streams}
          style={styles.tile}
          strokeColor={DspColors[item]}
        />
      )
    }}
    onSwipe={onSwipe}
    style={styles.carousel}
    indicatorStyle={styles.carouselIndicator}
  />
)

const MarketTopTracksCarousel: React.FC<{
  timeInterval: TimeInterval
  countryCode: string
  onPressTrack: (track: Track) => void
  onSwipe: (item: StreamingDsp | 'all') => void
}> = ({ timeInterval, onPressTrack, countryCode, onSwipe }) => (
  <Carousel<StreamingDsp | 'all'>
    items={['all', ...streamingDsps]}
    renderItem={({ item, style }) => (
      <MarketTopTracksTile
        key={item}
        dsp={item}
        countryCode={countryCode}
        timeInterval={timeInterval}
        style={[
          {
            backgroundColor: colors.black,
            marginHorizontal: styles.tile.marginHorizontal,
          },
          style,
        ]}
        onPressTrack={onPressTrack}
      />
    )}
    onSwipe={onSwipe}
    style={styles.carousel}
    indicatorStyle={styles.carouselIndicator}
    scale={0.8}
  />
)

const MarketChartTrackPositionsCarousel: React.FC<{
  timeInterval: TimeInterval
  countryCode: string
  onPressItem: (item: ChartDsp) => void
  onSwipe: (item: ChartDsp) => void
}> = ({ timeInterval, onPressItem, countryCode, onSwipe }) => (
  <Carousel<ChartDsp>
    items={[...chartDsps]}
    renderItem={({ item }) => (
      <MarketChartTrackPositionsTile
        key={item}
        dsp={item}
        countryCode={countryCode}
        timeInterval={timeInterval}
        onPress={() => onPressItem(item)}
        style={[styles.tile, { flexShrink: 1 }]}
      />
    )}
    onSwipe={onSwipe}
    style={styles.carousel}
    indicatorStyle={styles.carouselIndicator}
  />
)

export const MarketStreamsTable: React.FC<{
  entityId: string
  countryCode: string
  releaseDate?: string
  style?: StyleProp<ViewStyle>
}> = ({ releaseDate, style, countryCode }) => {
  const useEntityStreams = (interval: Interval) =>
    useArtistStreams(interval, 'all', countryCode)
  return (
    <View style={[style]}>
      <ReleaseToDateTableRow
        useEntityStreams={useEntityStreams}
        releaseDate={releaseDate}
      />
      <TimeIntervalTableRows
        useEntityStreams={useEntityStreams}
        key="intervals"
      />
    </View>
  )
}

export const MarketScreen: React.FC<
  ReactNavigationProps<ScreenNames.Market>
> = ({ navigation, route }) => {
  const artist = useContext(ArtistContext)
  const timeInterval = 'last28days'
  const countryCode = route.params.market
  const regionsResponse = useRegions()
  const region = regionsResponse.data?.regions?.find(
    (r) => r.countryCode === countryCode
  )

  const { refreshControl, screenContext } = useScreenRefreshControl(
    regionsResponse.retry,
    regionsResponse.refreshing
  )

  const sendAnalyticsForSwipe = (carousel: string) => (dsp: Dsp) => {
    sendAnalyticsEvent(EventType.MARKET_SCREEN_CAROUSEL_SWIPED, {
      carousel,
      screen: 'Market Screen',
      countryCode,
      dsp,
      artist: {
        name: artist.name,
        sonyArtistId: artist.sonyArtistId,
      },
      subject: 'user',
      verb: 'swiped',
      object: 'carousel',
    })
  }

  const { onScroll, titleOpacity } = useAnimateTitleOpacity(120, 100)

  return (
    <ScreenContext.Provider value={screenContext}>
      <CommonScreenContainer screenName={screenName}>
        <HeaderNav
          title={
            region?.countryName != null
              ? formatCountryName(region?.countryName)
              : ''
          }
          titleOpacity={titleOpacity}
          showToast={regionsResponse?.showToast}
          navigation={navigation}
          style={{ zIndex: 10 }}
        />
        <ErrorBoundary
          error={regionsResponse.error}
          refreshControl={refreshControl}
        >
          {region != null ? (
            <Animated.ScrollView
              refreshControl={refreshControl}
              showsVerticalScrollIndicator={false}
              contentContainerStyle={{ flexGrow: 1 }}
              onScroll={onScroll}
            >
              <View style={EntityScreenStyles.container}>
                <EntityScreenHeader
                  title={formatCountryName(region?.countryName)}
                  image={<CountryIcon countryCode={countryCode} size={48} />}
                  style={EntityScreenStyles.entityScreenHeader}
                />
                <MarketStreamsTable
                  entityId={countryCode}
                  countryCode={countryCode}
                  style={{ paddingBottom: 16 }}
                />
                <MarketStreamsCarousel
                  timeInterval={timeInterval}
                  countryCode={countryCode}
                  onPressItem={(item) => {
                    navigation.navigate(ScreenNames.ArtistStreamsGraph, {
                      dsp: item,
                      market: countryCode,
                    })
                  }}
                  onSwipe={sendAnalyticsForSwipe('Streams')}
                />
                <MarketTopTracksCarousel
                  timeInterval={timeInterval}
                  countryCode={countryCode}
                  onPressTrack={(track) =>
                    navigation.navigate(ScreenNames.Track, {
                      isrc: track.isrc,
                      market: countryCode,
                    })
                  }
                  onSwipe={sendAnalyticsForSwipe('Top Tracks')}
                />
                <MarketChartTrackPositionsCarousel
                  timeInterval={timeInterval}
                  countryCode={countryCode}
                  onPressItem={(item) => {
                    navigation.navigate('MarketCharts', {
                      market: countryCode,
                      dsp: item,
                    })
                  }}
                  onSwipe={sendAnalyticsForSwipe('Charts')}
                />
                <ArtistStreamsDemographicsCarousel
                  timeInterval={timeInterval}
                  countryCode={countryCode}
                  onSwipe={() => {}}
                />
              </View>
            </Animated.ScrollView>
          ) : (
            <CenteredActivityIndicator size="large" />
          )}
        </ErrorBoundary>
      </CommonScreenContainer>
    </ScreenContext.Provider>
  )
}
