import { groupBy, map, mapValues, sum } from 'lodash'
import React, { useMemo } from 'react'
import { Text, View } from 'react-native'

import { colors } from '../Colors'
import { Gender } from '../Consts'
import { TextStyles } from '../Styles'
import { DemographicsAgeBand, AgeRange } from '../graphql/__generated__/sdk'
import { Strings } from '../i18n'
import { sortGenders } from '../util'
import { roundNumbersSummingTo100 } from '../util/rounding'

const GenderPercentage: React.FC<{
  gender: Gender
  percentage: number
  small?: boolean
}> = ({ gender, percentage, small = false }) => (
  <View style={{ flexDirection: 'column', flex: 1 }}>
    <View style={{ flexDirection: 'row', alignItems: 'center' }}>
      <Text style={[TextStyles.tiny, { color: colors.offWhite }]}>
        {Strings.Genders[gender]}
      </Text>
    </View>
    <Text
      style={[small ? TextStyles.body : TextStyles.h4, { color: colors.white }]}
    >
      {Math.round(percentage)}%
    </Text>
  </View>
)

interface GenderPercentageType {
  gender: Gender
  percentage: number
}

function roundGenderPercentages(genderPercentages: GenderPercentageType[]) {
  const roundedValues = roundNumbersSummingTo100(
    genderPercentages.map(({ percentage }) => percentage)
  )

  return genderPercentages.map((genderPercentage, i) => ({
    ...genderPercentage,
    percentage: roundedValues[i],
  }))
}

export const GenderDemographics: React.FC<{
  dspDemographics: DemographicsAgeBand[]
  selectedAgeRange?: AgeRange | null
}> = ({ dspDemographics, selectedAgeRange }) => {
  const genderDemographics = useMemo(() => {
    if (selectedAgeRange === undefined) {
      return dspDemographics
    }

    return dspDemographics?.filter(({ ageRange }) => {
      return selectedAgeRange
        ? selectedAgeRange.start === ageRange?.start
        : ageRange === null
    })
  }, [dspDemographics, selectedAgeRange])

  const genderPercentages = useMemo(() => {
    const genderPercentageSums = mapValues(
      groupBy(genderDemographics, 'gender'),
      (genderAgeBands) =>
        sum(genderAgeBands.map(({ percentage }) => percentage))
    )
    const genderPercentages = map(
      genderPercentageSums,
      (percentage, gender) => ({
        gender: gender as Gender,
        percentage,
      })
    )

    return roundGenderPercentages(genderPercentages)
  }, [genderDemographics])

  return (
    <View
      style={[
        {
          flexDirection: 'row',
          justifyContent: 'space-between',
          marginBottom: 18,
        },
      ]}
    >
      {genderPercentages
        .sort((a, b) => sortGenders(a.gender, b.gender))
        .map(({ gender, percentage }) => (
          <GenderPercentage
            key={gender}
            gender={gender}
            percentage={percentage}
          />
        ))}
    </View>
  )
}
