import _ from 'lodash'
import React from 'react'
import { StyleProp, Text, View, ViewStyle } from 'react-native'
import { colorsV2, sourceLeanColors } from '../Colors'
import { dspNames, SourceLean, sourceLeans, StreamingDsp } from '../Consts'
import { DateData } from '../DateData'
import { useTrackStreamSources } from '../hooks/useTrackStreamSources'
import { Strings } from '../i18n'
import { TextStylesV2 } from '../Styles'
import { TimeInterval } from '../types/TimeInterval'
import { DspSource } from '../types/types'
import { formatPercent, readableAxisLabels, timeRangeInterval } from '../util'
import { formatInterval } from '../util/date'
import { DataTile, DataTileText } from './DataTile'
import { Graph } from './Graph'
import { GraphYAxisScale } from './GraphYAxisScale'
import { GraphYAxisAxes } from './GraphYAxisAxes'

const LeanPercentage: React.FC<{
  percentage: number
  lean: SourceLean
}> = ({ percentage, lean }) => {
  return (
    <View
      style={{
        justifyContent: 'space-between',
        flexDirection: 'row',
        alignItems: 'center',
        height: 31,
      }}
    >
      <View style={{ flexDirection: 'row', alignItems: 'center' }}>
        <View
          style={{
            borderRadius: 5,
            width: 5,
            height: 5,
            marginRight: 8,
            backgroundColor: sourceLeanColors[lean],
          }}
        />
        <Text style={[TextStylesV2.body, { color: colorsV2.metals.metal0 }]}>
          {
            {
              leanForward: Strings.Shared.LeanForward,
              leanBack: Strings.Shared.LeanBack,
            }[lean]
          }
        </Text>
      </View>
      <Text style={[TextStylesV2.bodyBold, { color: sourceLeanColors[lean] }]}>
        {formatPercent(percentage, 0, false)}
      </Text>
    </View>
  )
}

/*
 * aggregate day by day data for all sources of a certain lean/dsp
 */
function leanDspStreams(
  sources: DateData<Record<StreamingDsp, DspSource | null> | null>[],
  lean: SourceLean,
  dsp: StreamingDsp
) {
  const byDate = sources.map((item) => {
    const leanSources = item.data?.[dsp]?.[lean]
    const data = leanSources != null ? _.sum(Object.values(leanSources)) : null

    return {
      date: item.date,
      data,
    }
  })

  const sum = _.sum(byDate.map(({ data }) => data))

  return { byDate, sum }
}

function dspSummary(
  sources: DateData<Record<StreamingDsp, DspSource>>[],
  dsp: StreamingDsp
) {
  const streams = sourceLeans.map((lean) => ({
    lean,
    summary: leanDspStreams(sources, lean, dsp),
  }))

  const total = _.sum(streams.map((lean) => lean.summary.sum))
  const leanPercentages =
    total > 0
      ? streams.map((l) => ({
          lean: l.lean,
          percentage: (l.summary.sum / total) * 100,
        }))
      : null

  const graphData = streams.map(({ lean, summary }) => ({
    yValues: summary.byDate.map(({ data }) => data),
    strokeColor: sourceLeanColors[lean],
  }))

  const maxYValue = graphData.reduce(
    (max, { yValues }) => Math.max(max, ...yValues),
    0
  )

  return { maxYValue, graphData, leanPercentages }
}

/**
 * A tile representing entity (track/video) stream sources for a dsp
 */
export const StreamSourcesTile: React.FC<{
  entityId: string
  dsp: StreamingDsp
  countryCode: string
  timeInterval: TimeInterval
  onPress: () => void
  style?: StyleProp<ViewStyle>
  title: string
}> = ({ entityId, dsp, countryCode, timeInterval, onPress, style, title }) => {
  const currentInterval = timeRangeInterval(timeInterval)
  const { data, error } = useTrackStreamSources(
    entityId,
    countryCode,
    currentInterval
  )
  const sources = data?.sources
  const summary = sources != null ? dspSummary(sources, dsp) : null
  const { dividers, maxLabelValue } = readableAxisLabels(
    summary ? summary.maxYValue : 0
  )

  return (
    <DataTile
      dsp={dsp}
      title={title}
      subTitle={formatInterval(currentInterval)}
      onPress={onPress}
      style={[{ minHeight: 364 }, style]}
      error={error}
    >
      {summary != null ? (
        summary.leanPercentages != null ? (
          <>
            <View style={{ flex: 1, flexDirection: 'row', marginBottom: 24 }}>
              <View style={{ flex: 1, flexDirection: 'row' }}>
                <Graph
                  data={summary.graphData}
                  strokeWidth={2.5}
                  minY={0}
                  maxY={maxLabelValue}
                />
                <GraphYAxisAxes
                  lineStyle={{ backgroundColor: colorsV2.metals.metal1 }}
                  dividers={dividers}
                />
              </View>
              <GraphYAxisScale
                data={[0, maxLabelValue]}
                dividers={dividers}
                style={{ marginLeft: 4 }}
                textStyle={{
                  ...TextStylesV2.tinyBold,
                  ...{ color: colorsV2.offWhite },
                }}
              />
            </View>
            {summary.leanPercentages.map(({ lean, percentage }) => (
              <LeanPercentage key={lean} percentage={percentage} lean={lean} />
            ))}
          </>
        ) : (
          <DataTileText
            text={Strings.Shared.TrackNoStreamSourcesForDsp.replace(
              '%s',
              dspNames[dsp]
            )}
          />
        )
      ) : null}
    </DataTile>
  )
}
