import * as df from 'date-fns'
import React from 'react'
import { Text, View } from 'react-native'

import { TextStyles } from '../Styles'
import { formatDateString } from '../util/date'
import { BarChartTouchWrapper } from './BarChartTouchWrapper'
import { DateIndicator } from './DateIndicator'
import {
  BarAndLineFigure,
  FigureAxisConfig,
  PlotConfig,
} from './figures/BarAndLineFigure'

function AxisLabels<T>({
  axisConfig,
  plots,
}: {
  axisConfig: FigureAxisConfig
  plots: PlotConfig<T>[]
}) {
  const axisLabels = (['left', 'right'] as (keyof FigureAxisConfig)[]).flatMap(
    (side) => {
      if (axisConfig?.[side]) {
        return {
          text: axisConfig?.[side]?.legendLabel ?? null,
          color: plots.find((p) => p.axisSide === side)?.color,
        }
      } else {
        return []
      }
    }
  )

  return axisLabels.length > 0 ? (
    <View
      style={[
        {
          justifyContent: 'space-between',
          flexDirection: 'row',
          marginBottom: 16,
        },
      ]}
    >
      {axisLabels.map(({ text, color }, i) => (
        <Text
          key={i}
          style={[TextStyles.tinyCaps, { color, textTransform: 'uppercase' }]}
        >
          {text}
        </Text>
      ))}
    </View>
  ) : null
}

/**
 *
 * Bar graph displaying bars for a given time interval, used for video views and track streams
 *
 */
export function TrackDateDataFigure<T extends number | null>({
  plots,
  axisConfig,
  selectedInterval,
  selectBar,
  selectedBar,
  onHoverBar,
  onHoverBarEnd,
}: {
  plots: PlotConfig<T>[]
  axisConfig?: FigureAxisConfig
  selectedInterval: Interval
  selectBar: (index: number | null) => void
  selectedBar: number | null
  onHoverBar: () => void
  onHoverBarEnd: () => void
}): React.ReactElement {
  const numBars = plots[0].data.length
  const selectedDate =
    selectedBar != null
      ? formatDateString(df.eachDayOfInterval(selectedInterval)[selectedBar])
      : null

  return (
    <View style={{ flex: 1 }}>
      <DateIndicator
        selectedDate={selectedDate}
        desiredCenterPosition={(selectedBar ?? 0) / numBars}
        style={{ height: 32, marginHorizontal: 26 }}
      />
      {axisConfig && <AxisLabels axisConfig={axisConfig} plots={plots} />}
      <View style={{ flex: 1, flexDirection: 'row' }}>
        <BarChartTouchWrapper
          numBars={numBars}
          onHoverBar={(barIndex) => {
            selectBar(barIndex)
            onHoverBar()
          }}
          onHoverBarEnd={() => {
            selectBar(null)
            onHoverBarEnd()
          }}
        >
          <BarAndLineFigure
            plots={plots}
            valueExtractor={(item) => item}
            statusExtractor={(item) => (item !== null ? 'full' : 'missing')}
            selectedBarIndex={selectedBar ?? undefined}
            axisConfig={axisConfig}
            grid
          />
        </BarChartTouchWrapper>
      </View>
    </View>
  )
}
