import * as df from 'date-fns'
import React from 'react'
import { View } from 'react-native'
import { colorsV2 } from '../Colors'
import { BarChartTouchWrapper } from './BarChartTouchWrapper'
import { TimeIntervalSelector } from './TimeIntervalSelector'
import { DateData } from '../DateData'
import { TimeInterval } from '../types/TimeInterval'
import { parseDateString } from '../util/date'
import { DateIndicator } from './DateIndicator'
import { BarAndLineFigure } from './figures/BarAndLineFigure'
import { AxisConfig } from './figures/Axis'

function sortDateDataByEarliestDate<T extends unknown | null>(
  a: DateData<T>,
  b: DateData<T>
): number {
  return new Date(a.date).getTime() - new Date(b.date).getTime()
}

/**
 *
 * Bar graph displaying bars for a given time interval, used for video views and track streams
 *
 */
export function TrackDateDataFigure<T extends number | null>({
  maxIntervalBar,
  maxIntervalLine,
  lineAxisConfig,
  selectedInterval,
  selectDate,
  selectedDate,
  selectTimeInterval,
  selectedTimeInterval,
  onHoverBar,
  onHoverBarEnd,
  lineReverse,
  barReverse,
}: {
  maxIntervalBar: DateData<T>[]
  maxIntervalLine: DateData<T>[]
  lineAxisConfig?: AxisConfig
  selectedInterval: Interval
  selectDate: (date: string | null) => void
  selectedDate: string | null
  selectTimeInterval: (timeInterval: TimeInterval) => void
  selectedTimeInterval: TimeInterval
  onHoverBar: () => void
  onHoverBarEnd: () => void
  lineReverse?: boolean
  barReverse?: boolean
}): React.ReactElement {
  const numBars = maxIntervalBar.length
  const selectedBarIndex = maxIntervalBar.findIndex(
    ({ date }) => date === selectedDate
  )
  const barData = maxIntervalBar.sort(sortDateDataByEarliestDate)
  const lineData = maxIntervalLine.sort(sortDateDataByEarliestDate)
  const selectedIntervalStartIndex = barData.findIndex(({ date }) =>
    df.isEqual(parseDateString(date), selectedInterval.start)
  )

  return (
    <View style={{ flex: 1 }}>
      <DateIndicator
        selectedDate={selectedDate}
        desiredCenterPosition={selectedBarIndex / numBars}
        style={{ height: 32, marginLeft: 26 }}
      />
      <View style={{ flex: 1, flexDirection: 'row' }}>
        <BarChartTouchWrapper
          numBars={maxIntervalBar.length}
          onHoverBar={(barIndex) => {
            selectDate(maxIntervalBar[barIndex].date)
            onHoverBar()
          }}
          onHoverBarEnd={() => {
            selectDate(null)
            onHoverBarEnd()
          }}
        >
          <BarAndLineFigure
            barData={barData}
            lineData={lineData}
            lineAxisConfig={lineAxisConfig}
            lineReverse={lineReverse ?? false}
            barReverse={barReverse ?? false}
            style={{
              flex: 1,
            }}
            barStyle={(i, item) => ({
              fill:
                item.date === selectedDate ? colorsV2.white : colorsV2.offWhite,
            })}
            barWidth={5}
            valueExtractor={(item) => item.data ?? 0}
            statusExtractor={(item) =>
              item.data !== null ? 'full' : 'missing'
            }
            disablePointerEvents
            selectedBarIndex={selectedBarIndex}
            shroud={{ start: 0, end: selectedIntervalStartIndex }}
          />
        </BarChartTouchWrapper>
      </View>
      <TimeIntervalSelector
        onSelectTimeInterval={selectTimeInterval}
        selectedTimeInterval={selectedTimeInterval}
      />
    </View>
  )
}
