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

import { VideoDsp } from '../Consts'
import { ReactNavigationProps } from '../Navigation'
import { EntityScreenStyles } from '../Styles'
import { AutoLayout } from '../components/AutoLayout'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { DemographicsTile } from '../components/DemographicsTile'
import { EntityScreenHeader } from '../components/EntityScreenHeader'
import { EntityStreamSourcesTile } from '../components/EntityStreamSourcesTile'
import { ErrorBoundary } from '../components/ErrorBoundary'
import { HeaderNav } from '../components/HeaderNav'
import { MarketSelectorButton } from '../components/MarketSelectorButton'
import { PlayButton } from '../components/PlayButton'
import { VideoEngagementTile } from '../components/VideoEngagementTile'
import { VideoImage } from '../components/VideoImage'
import { VideoViewsTable } from '../components/VideoViewsTable'
import { VideoViewsTile } from '../components/VideoViewsTile'
import { ScreenNames } from '../constants/ScreenNames'
import { ArtistContext } from '../contexts/ArtistContext'
import { ScreenContext } from '../contexts/ScreenContext'
import { VideoFieldsFragment } from '../graphql/__generated__/sdk'
import { EventType, sendAnalyticsEvent } from '../hooks/useAnalytics'
import { useScreenRefreshControl } from '../hooks/useScreenRefreshControl'
import { useVideo } from '../hooks/useVideo'
import { useVideoViewsDemographics } from '../hooks/useVideoViewDemographics'
import { useVideoViewSources } from '../hooks/useVideoViewSources'
import { Strings } from '../i18n'
import { defaultTimeInterval, TimeInterval } from '../types/TimeInterval'
import { timeRangeInterval, useAnimateTitleOpacity } from '../util'

const screenName = 'Video Screen'

/**
 * A tile representing video view sources for a dsp
 */
export const VideoViewsSourcesTile: React.FC<{
  video: VideoFieldsFragment
  dsp: VideoDsp
  timeInterval: TimeInterval
  market: string
  onPress: () => void
  style?: StyleProp<ViewStyle>
}> = ({ video, dsp, timeInterval, market, onPress, style }) => {
  const { sources, error } = useVideoViewSources(
    video.id,
    timeRangeInterval(timeInterval),
    video.dsp,
    market
  )
  return (
    <EntityStreamSourcesTile
      dsp={dsp}
      timeInterval={timeInterval}
      onPress={onPress}
      sources={sources}
      error={error}
      title={Strings.Shared.Sources}
      style={style}
    />
  )
}

export const VideoViewsDemographicsTile: React.FC<{
  dsp: VideoDsp
  timeInterval: TimeInterval
  countryCode: string
  videoId: string
  style?: StyleProp<ViewStyle>
}> = ({ dsp, timeInterval, countryCode, videoId, style }) => {
  const { demographics, error } = useVideoViewsDemographics(
    videoId,
    timeRangeInterval(timeInterval),
    dsp,
    countryCode
  )

  return (
    <DemographicsTile
      key={dsp}
      dsp={dsp}
      demographics={demographics}
      error={error}
      timeInterval={timeInterval}
      style={style}
    />
  )
}

export const VideoScreen: React.FC<ReactNavigationProps<ScreenNames.Video>> = ({
  navigation,
  route,
}) => {
  const artist = useContext(ArtistContext)
  const timeInterval = defaultTimeInterval
  const videoId = route.params.video_id
  const countryCode = route.params.market ?? 'worldwide'

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

  const videoResponse = useVideo(videoId)

  const onPullToRefresh = () => {
    sendAnalyticsEvent(EventType.PULL_TO_REFRESH, {
      artist_selected: artist.name,
      timeframe_selected: timeInterval,
      page: 'Video Screen',
      subject: 'user',
      verb: 'refreshed',
      object: 'video',
    })
    videoResponse.retry()
  }

  const { refreshControl, screenContext } = useScreenRefreshControl(
    onPullToRefresh,
    videoResponse.refreshing
  )

  const video = videoResponse.data?.artist?.video

  return (
    <ScreenContext.Provider value={screenContext}>
      <CommonScreenContainer screenName={screenName}>
        <HeaderNav
          title={video?.title}
          titleOpacity={titleOpacity}
          showToast={videoResponse.showToast}
          navigation={navigation}
          style={{
            zIndex: 10,
          }}
          right={
            <MarketSelectorButton
              countryCode={countryCode}
              onPress={() => {
                navigation.navigate('MarketSelector', {
                  previousScreen: 'Video',
                })
              }}
            />
          }
        />
        <ErrorBoundary
          error={videoResponse.error}
          refreshControl={refreshControl}
        >
          <Animated.ScrollView
            refreshControl={refreshControl}
            showsVerticalScrollIndicator={false}
            contentContainerStyle={{ flexGrow: 1 }}
            onScroll={onScroll}
          >
            <View
              style={{
                flex: 1,
              }}
            >
              {video && (
                <AutoLayout gap={24} style={EntityScreenStyles.container}>
                  <EntityScreenHeader
                    title={video.title}
                    date={video.dateUploaded}
                    image={
                      <>
                        <VideoImage item={video} width={108} height={108} />
                        <PlayButton
                          url={`http://www.youtube.com/watch?v=${video.dspVideoId}`}
                          width={108}
                          height={108}
                        />
                      </>
                    }
                    style={EntityScreenStyles.entityScreenHeader}
                  />
                  <VideoViewsTable
                    videoId={video.id}
                    countryCode={countryCode}
                  />
                  <VideoViewsTile
                    dsp={video.dsp}
                    timeInterval={timeInterval}
                    onPress={() => {
                      navigation.navigate(ScreenNames.VideoViewsGraph, {
                        video_id: videoId,
                        market: countryCode,
                      })
                    }}
                    videoId={video.id}
                    market={countryCode}
                    title={Strings.Shared.Views}
                  />
                  <VideoViewsSourcesTile
                    video={video}
                    dsp={video.dsp}
                    timeInterval={timeInterval}
                    onPress={() => {
                      navigation.navigate(ScreenNames.VideoViewSources, {
                        video_id: videoId,
                        market: countryCode,
                        dsp: video.dsp,
                      })
                    }}
                    market={countryCode}
                  />
                  <VideoEngagementTile
                    video={video}
                    timeInterval={timeInterval}
                    countryCode={countryCode}
                    onPress={() => {
                      navigation.navigate(ScreenNames.VideoEngagementGraph, {
                        video_id: videoId,
                        market: countryCode,
                      })
                    }}
                  />
                  <VideoViewsDemographicsTile
                    dsp="youtube"
                    videoId={video.id}
                    timeInterval={timeInterval}
                    countryCode={countryCode}
                  />
                </AutoLayout>
              )}
            </View>
          </Animated.ScrollView>
        </ErrorBoundary>
      </CommonScreenContainer>
    </ScreenContext.Provider>
  )
}
