import React, { useContext, useState } from 'react'
import { View } from 'react-native'

import { UserContext } from '../contexts/UserContext'
import { Countries } from '../components/Countries'
import { SearchBar } from '../components/SearchBar'
import { timeRangeDates } from '../util'
import { CountryWithStreams } from '../types/Country'
import { Styles } from '../Styles'
import { useNetwork, NetworkRequest } from '../components/useNetwork'
import { HeaderNav } from '../components/HeaderNav'
import { Colors, colorsV2 } from '../Colors'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { ErrorBoundary } from '../components/ErrorBoundary'
import { DemographicCountrySkeleton } from '../components/Skeleton'
import { ScreenNames } from '../constants/ScreenNames'
import { ReactNavigationProps } from '../Navigation'
import { EventType, sendAnalyticsEvent } from '../hooks/useAnalytics'
import { ArtistContext } from '../contexts/ArtistContext'
import { Strings } from '../i18n'
import { defaultTimeInterval, TimeInterval } from '../types/TimeInterval'

interface CountriesData {
  countries: CountryWithStreams[]
}

export const CountriesScreen: React.FC<
  ReactNavigationProps<ScreenNames.Countries>
> = ({ navigation, route }) => {
  const user = useContext(UserContext)
  const artist = useContext(ArtistContext)

  const [timeInterval, setTimeInterval] = useState<TimeInterval>(
    route.params.timeInterval ?? defaultTimeInterval
  )
  const [filter, setFilter] = useState('')
  const { startDate, endDate } = timeRangeDates(timeInterval)

  const response = useNetwork<CountriesData>(
    `screens/artist/${artist.sonyArtistId}/countries?startDate=${startDate}&endDate=${endDate}`,
    user,
    () =>
      sendAnalyticsEvent(EventType.PULL_TO_REFRESH, {
        artist_selected: artist.name,
        timeframe_selected: timeInterval,
        page: 'Countries Screen',
        subject: 'user',
        verb: 'refreshed',
        object: 'countries',
      })
  )

  return (
    <CommonScreenContainer>
      <HeaderNav
        title={Strings.Shared.Countries}
        navigation={navigation}
        showToast={response.showToast}
        style={{
          zIndex: 10,
          backgroundColor: colorsV2.black,
        }}
        timeInterval={timeInterval}
        setTimeInterval={setTimeInterval}
      />
      <View
        style={{
          flex: 1,
          backgroundColor: Colors.background,
          ...Styles.screenHorizontalPadding,
        }}
      >
        <SearchBar
          filter={filter}
          setFilter={setFilter}
          placeholder={Strings.Shared.SearchHintMarket}
        />
        <ErrorBoundary
          error={response.error}
          refreshControl={response.refreshControl}
        >
          <Content
            {...response}
            navigation={navigation}
            filter={filter}
            artistId={artist.sonyArtistId}
          />
        </ErrorBoundary>
      </View>
    </CommonScreenContainer>
  )
}

type Filter = {
  filter: string
}
function Content({
  navigation,
  data,
  refreshControl,
  filter,
  artistId,
}: {
  navigation: ReactNavigationProps<ScreenNames.Globe>['navigation']
  artistId: string
} & NetworkRequest<CountriesData> &
  Filter) {
  const countries = data?.countries
    .sort(byStreams)
    .map((country, index) => ({ ...country, position: index + 1 }))
    .filter(countryMatchesFilter(filter))

  return countries ? (
    <Countries
      countries={countries}
      onPressCountry={(country) => {
        navigation.navigate(ScreenNames.Market, {
          countryCode: country.countryCode,
          artistId,
        })
      }}
      refreshControl={refreshControl}
    />
  ) : (
    <DemographicCountrySkeleton numItems={5} />
  )
}

function countryMatchesFilter(filter: string) {
  const normalizedFilter = filter.toLowerCase().trim()
  return ({ item: country }: CountryWithStreams) =>
    country.name.toLowerCase().includes(normalizedFilter)
}

function byStreams(a: CountryWithStreams, b: CountryWithStreams) {
  return b.data.current - a.data.current
}
