import React, { useCallback, useContext, useEffect, useState } from 'react'
import { ActivityIndicator, Text, View } from 'react-native'

import { colors } from '../Colors'
import { ReactNavigationProps } from '../Navigation'
import { TextStyles } from '../Styles'
import { Button } from '../components/Button'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { ErrorBoundary } from '../components/ErrorBoundary'
import { GraphDetailScreenHeader } from '../components/GraphDetailScreenHeader'
import { HeaderNav } from '../components/HeaderNav'
import { ProductImage } from '../components/ProductImage'
import { TimeIntervalSelector } from '../components/TimeIntervalSelector'
import {
  sortByNumberOfStreams,
  TrackComparison,
} from '../components/TrackComparison'
import {
  TrackComparisonSelectionModalContainer,
  useTrackComparisonSelectionModal,
} from '../components/TrackComparisonSelectionModal'
import { ScreenNames } from '../constants/ScreenNames'
import { ArtistContext } from '../contexts/ArtistContext'
import { EventType, sendAnalyticsEvent } from '../hooks/useAnalytics'
import { useScreenRefreshControl } from '../hooks/useScreenRefreshControl'
import { useScreenTimeInterval } from '../hooks/useScreenTimeInterval'
import { useTracksStreams } from '../hooks/useTracksStreams'
import { Strings } from '../i18n'
import { getTracksWithAllDsp } from '../streams'
import { defaultTimeInterval } from '../types/TimeInterval'
import { productImageFieldsFromProduct } from '../types/graphqlCompatibilityHelpers'
import { TrackWithStreamsByDspAndDate } from '../types/types'
import { isTrackExplicit, timeRangeInterval } from '../util'
import { formatInterval } from '../util/date'

export const TracksComparisonScreen: React.FC<
  ReactNavigationProps<ScreenNames.TracksComparison>
> = ({ navigation, route }) => {
  const screenName = 'Tracks Comparison Screen'
  const artist = useContext(ArtistContext)

  const isrcs = route.params.isrcs
  const dsp = 'all'

  const [tracks, setTracks] = useState<TrackWithStreamsByDspAndDate[]>()
  const [selectedTrack, setSelectedTrack] =
    useState<TrackWithStreamsByDspAndDate | null>()

  const maxInterval = defaultTimeInterval //Longest interval represented in the graph

  const [timeInterval, setTimeInterval] = useScreenTimeInterval(maxInterval, {
    screenName,
    artistName: artist.name,
    entityId: artist.sonyArtistId,
  })

  const interval = timeRangeInterval(timeInterval)

  const { streams, error, retry, refreshing, showToast } = useTracksStreams(
    isrcs,
    interval
  )

  const onPullToRefresh = () => {
    sendAnalyticsEvent(EventType.PULL_TO_REFRESH, {
      artist_selected: artist.name,
      timeframe_selected: timeInterval,
      page: screenName,
      subject: 'user',
      verb: 'refreshed',
      object: 'tracks',
    })

    retry()
  }

  const { refreshControl } = useScreenRefreshControl(
    onPullToRefresh,
    refreshing
  )

  const {
    trackComparisonSelectionModalOpen,
    setTrackComparisonSelectionModalOpen,
  } = useTrackComparisonSelectionModal()

  useEffect(
    () => setTracks(streams ? getTracksWithAllDsp(streams) : undefined),
    [streams, isrcs]
  )

  const handleOnTrackSelect = useCallback(
    (track: TrackWithStreamsByDspAndDate | null) => {
      setSelectedTrack(track)

      if (track) {
        sendTrackComparisonTrackChangedAnalyticsEvent(track.item.isrc)
      }
    },
    []
  )

  const sendTrackComparisonTrackChangedAnalyticsEvent = (isrc: string) => {
    sendAnalyticsEvent(EventType.TRACK_COMPARISON_TRACK_CHANGED, {
      isrc,
      subject: 'user',
      verb: 'selected',
      object: 'track_comparison',
    })
  }

  return (
    <CommonScreenContainer screenName={screenName}>
      <ErrorBoundary error={error} refreshControl={refreshControl}>
        <HeaderNav
          title={artist.name ?? ' '}
          showToast={showToast}
          navigation={navigation}
          style={{
            zIndex: 10,
          }}
        />
        <View
          style={{
            paddingHorizontal: 10,
            flex: 1,
            justifyContent: 'space-between',
          }}
        >
          <GraphDetailScreenHeader
            image={
              tracks
                ? sortByNumberOfStreams(tracks).map(
                    ({ item }) =>
                      item.product && (
                        <View style={{ width: 56 }}>
                          <ProductImage
                            size={48}
                            product={productImageFieldsFromProduct(
                              item.product
                            )}
                            isExplicit={isTrackExplicit(item)}
                          />
                          <Text
                            style={[TextStyles.small, { color: colors.white }]}
                            ellipsizeMode="tail"
                            numberOfLines={1}
                          >
                            {item.name}
                          </Text>
                        </View>
                      )
                  )
                : null
            }
            imageWidth={60}
            imageHeight={80}
            dsp={dsp}
            title={Strings.Shared.TrackPerformance}
            subTitle={formatInterval(interval)}
          />
          {tracks != null ? (
            <TrackComparison
              tracks={tracks}
              onTrackSelect={handleOnTrackSelect}
            />
          ) : (
            <ActivityIndicator />
          )}
          <TimeIntervalSelector
            selectedTimeInterval={timeInterval}
            onSelectTimeInterval={(timeInterval) => {
              setTimeInterval(timeInterval)
              setSelectedTrack(null)
            }}
          />
        </View>
        <View
          style={{
            paddingVertical: 28,
            paddingHorizontal: 10,
            flexDirection: 'row',
            justifyContent: 'space-between',
          }}
        >
          <Button
            onPress={() => {
              setTrackComparisonSelectionModalOpen(true)
              setSelectedTrack(null)
            }}
          >
            {Strings.TrackComparison.Edit}
          </Button>
          {selectedTrack && (
            <Button
              onPress={() =>
                navigation.navigate(ScreenNames.Track, {
                  isrc: selectedTrack.item.isrc,
                })
              }
            >
              {Strings.TrackComparison.TrackScreen}
            </Button>
          )}
        </View>
        {trackComparisonSelectionModalOpen && (
          <TrackComparisonSelectionModalContainer
            initialSelectedTrackIsrcs={isrcs}
            open={trackComparisonSelectionModalOpen}
            onClose={() => setTrackComparisonSelectionModalOpen(false)}
          />
        )}
      </ErrorBoundary>
    </CommonScreenContainer>
  )
}
