import React, { useContext, useState } from 'react'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { ErrorBoundary } from '../components/ErrorBoundary'
import { HeaderNav } from '../components/HeaderNav'
import { ProductDetailHeading } from '../components/ProductDetailHeading'
import { TrackListSkeleton } from '../components/Skeleton'
import { StreamsListItem } from '../components/StreamsListItem'
import { TrackList } from '../components/TrackList'
import { NetworkRequest } from '../components/useNetwork'
import { ScreenNames } from '../constants/ScreenNames'
import { ArtistContext } from '../contexts/ArtistContext'
import { EventType, sendAnalyticsEvent } from '../hooks/useAnalytics'
import { ProductResponse, useProduct } from '../hooks/useProducts'
import { ReactNavigationProps } from '../Navigation'
import { getTracksWithAllDsp, periodToPeriodChangePercentage } from '../streams'
import { defaultTimeInterval, TimeInterval } from '../types/TimeInterval'
import { TrackWithStreamsByDspAndDate } from '../types/types'
import { isExplicit, timeRangeInterval, trackMatchesDsp } from '../util'

export const ProductDetailScreen: React.FC<
  ReactNavigationProps<ScreenNames.ProductDetail>
> = ({ navigation, route }) => {
  const artist = useContext(ArtistContext)
  const [timeInterval, setTimeInterval] = useState<TimeInterval>(
    route.params.timeInterval ?? defaultTimeInterval
  )
  const interval = timeRangeInterval(timeInterval)
  const productId = route.params.productId

  const response = useProduct(productId, interval, () =>
    sendAnalyticsEvent(EventType.PULL_TO_REFRESH, {
      artist_selected: artist.name,
      timeframe_selected: timeInterval,
      page: 'Product Details Screen',
      subject: 'user',
      verb: 'refreshed',
      object: 'product',
    })
  )

  return (
    <CommonScreenContainer>
      <ErrorBoundary
        error={response.error}
        refreshControl={response.refreshControl}
      >
        <Content
          productId={productId}
          {...response}
          navigation={navigation}
          timeInterval={timeInterval}
          setTimeInterval={setTimeInterval}
        />
      </ErrorBoundary>
    </CommonScreenContainer>
  )
}

function Content({
  productId,
  navigation,
  data,
  refreshControl,
  showToast,
  timeInterval,
  setTimeInterval,
}: {
  productId: string
  navigation: ReactNavigationProps<ScreenNames.ProductDetail>['navigation']
  timeInterval: TimeInterval
  setTimeInterval: (timeInterval: TimeInterval) => void
} & NetworkRequest<ProductResponse>) {
  return (
    <>
      <HeaderNav
        title={data?.product?.name ?? ' '}
        titleSecondary={data?.product?.digitalTitleSuppl ?? ' '}
        showToast={showToast}
        navigation={navigation}
        style={{
          zIndex: 10,
        }}
        timeInterval={timeInterval}
        setTimeInterval={setTimeInterval}
      />
      {data?.product != null && data?.streams != null ? (
        <ProductDetailHeading
          product={data?.product}
          isExplicit={isProductExplicit(data.streams)}
          onPressCompare={() => {
            navigation.navigate('ProductTracksComparison', { productId })
          }}
        />
      ) : null}
      {data != null ? (
        <TrackList
          refreshControl={refreshControl}
          renderTrack={(track, i) => (
            <StreamsListItem
              key={track.track.isrc}
              track={track.track}
              index={i}
              currentPeriodStreams={track.currentPeriodStreams}
              changePercentage={track.changePercentage}
              onPress={() =>
                navigation.navigate(ScreenNames.Track, {
                  isrc: track.track.isrc,
                })
              }
            />
          )}
          tracks={getTracksWithAllDsp(data.streams)
            .flatMap(trackMatchesDsp('all'))
            .map(({ item, data }) => ({
              track: item,
              currentPeriodStreams: data.currentPeriod,
              changePercentage: periodToPeriodChangePercentage(data),
            }))}
          style={{
            paddingHorizontal: 4,
          }}
        />
      ) : (
        <TrackListSkeleton numItems={4} dspFilter />
      )}
    </>
  )
}

//TODO: Remove this once Delphi has added product-level is_explicit
export function isProductExplicit(
  trackStreams: TrackWithStreamsByDspAndDate[]
) {
  return trackStreams.some((track) => isExplicit(track.item))
}
