import React, { useState } from 'react'
import { sum } from 'lodash'
import {
  View,
  Text,
  TouchableOpacity,
  ScrollView,
  ActivityIndicator,
} from 'react-native'

import { colors, DspColors } from '../Colors'
import { TextStyles } from '../Styles'
import { HeaderNav } from '../components/HeaderNav'
import {
  useSocial,
  UseSocialResponse,
  isSocialMedia,
} from '../components/useSocial'
import { SocialIcon } from '../components/SocialIcon'
import { ErrorBoundary } from '../components/ErrorBoundary'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { Graph } from '../components/Graph'
import { Number } from '../components/Number'
import { ScreenNames } from '../constants/ScreenNames'
import { ReactNavigationProps } from '../Navigation'
import { LinearGradient } from 'expo-linear-gradient'
import { ChangePlusMinusAndNumber } from '../components/ChangePlusMinusAndNumber'
import { Strings } from '../i18n'
import { SocialMedia, socialMedias } from '../Consts'
import { defaultTimeInterval, TimeInterval } from '../types/TimeInterval'
import { notEmpty } from '../util'

export const SocialScreen: React.FC<
  ReactNavigationProps<ScreenNames.Social>
> = ({ navigation }) => {
  const [timeInterval, setTimeInterval] =
    useState<TimeInterval>(defaultTimeInterval)
  const request = useSocial('Social Screen', timeInterval)

  return (
    <CommonScreenContainer>
      <View
        style={{
          flexGrow: 1,
          backgroundColor: colors.darkGray,
        }}
      >
        <HeaderNav
          title={Strings.Shared.Social}
          showToast={request.showToast}
          navigation={navigation}
          style={{
            zIndex: 10,
          }}
          timeInterval={timeInterval}
          setTimeInterval={setTimeInterval}
        />
        <ErrorBoundary
          error={request.error}
          refreshControl={request.refreshControl}
        >
          <Content
            {...request}
            navigation={navigation}
            timeInterval={timeInterval}
          />
        </ErrorBoundary>
      </View>
    </CommonScreenContainer>
  )
}

const SocialMediaRow: React.FC<{
  dspSlug: SocialMedia
  title: string
  current: number | null
  previous: number | null
  data: number[]
  sumOfLatest: number
  onPress: () => void
}> = ({ dspSlug, title, current, previous, data, sumOfLatest, onPress }) => {
  const barLocation = current ? current / sumOfLatest : 0

  const changeNumber =
    current === null || previous === null ? null : current - previous

  const latestFollowers = current ?? previous
  const disabled = current === null

  return (
    <TouchableOpacity onPress={onPress} style={{ flex: 1 }} disabled={disabled}>
      <LinearGradient
        colors={[colors.midGray, colors.darkGray]}
        start={[0, 0]}
        end={[1, 0]}
        locations={[barLocation, barLocation]}
        style={{ flex: 1, marginVertical: 1 }}
      >
        <View
          style={{
            flexGrow: 1,
            padding: 16,
            marginVertical: 1.5,
          }}
        >
          <View>
            <SocialIcon {...{ dspSlug }} disabled={disabled} />
            <View
              style={{
                flexDirection: 'row',
                justifyContent: 'space-between',
              }}
            >
              <Text
                style={{
                  ...TextStyles.body,
                  textTransform: 'capitalize',
                }}
              >
                {title}
              </Text>
              {changeNumber && (
                <ChangePlusMinusAndNumber changeNumber={changeNumber} />
              )}
            </View>
            <View>
              {latestFollowers && (
                <Number number={latestFollowers} style={{ paddingStart: 0 }} />
              )}
              {disabled && (
                <Text
                  style={{ ...TextStyles.body, textTransform: 'capitalize' }}
                >
                  {Strings.SocialScreen.MissingData}
                </Text>
              )}
            </View>
          </View>
          <View style={{ flexGrow: 1 }}>
            <Graph
              data={[
                {
                  yValues: data,
                  strokeColor: DspColors[dspSlug],
                },
              ]}
              strokeWidth={4}
            />
          </View>
        </View>
      </LinearGradient>
    </TouchableOpacity>
  )
}

const Content: React.FC<
  {
    navigation: ReactNavigationProps<ScreenNames.Social>['navigation']
    timeInterval: TimeInterval
  } & UseSocialResponse
> = ({ navigation, data: rows, refreshControl, timeInterval }) => {
  if (!rows) return <ActivityIndicator style={{ flex: 1 }} size="large" />
  const sumOfLatest = sum(rows.map(({ current }) => current))

  const filteredRows = rows.filter(isSocialMedia)

  return (
    <ScrollView
      contentContainerStyle={{ flexGrow: 1 }}
      refreshControl={refreshControl}
    >
      <View style={{ flexGrow: 1 }}>
        {Object.values(socialMedias)
          .map((dsp) => filteredRows.find(({ dspSlug }) => dspSlug === dsp))
          .filter(notEmpty)
          .map((row, i) => (
            <SocialMediaRow
              key={i}
              sumOfLatest={sumOfLatest}
              {...row}
              onPress={() =>
                navigation.navigate(ScreenNames.Followers, {
                  dspSlug: row?.dspSlug,
                  data: rows,
                  timeInterval,
                })
              }
            />
          ))}
      </View>
    </ScrollView>
  )
}
