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

import { colorsV2 } from '../Colors'
import { timeIntervalOptions } from '../contexts/TimeIntervalContext'
import { DateData, sumDateData } from '../DateData'
import {
  StreamsByDateResult,
  useEntityStreamsSummary,
} from '../hooks/useEntityStreams'
import { TextStylesV2 } from '../Styles'
import { formatCountShort, notEmpty, timeRangeInterval } from '../util'
import { parseDateString } from '../util/date'
import { BarChart } from './BarChart'
import { PercentPill } from './PercentPill'
import { Bone } from './Bone'

interface RowData {
  label: string
  interval: Interval
  maxIntervalStreams: DateData<number | null>[]
  currentIntervalStreams: DateData<number | null>[]
  changePercentage: number
}

const styles = StyleSheet.create({
  text: { ...TextStylesV2.tiny, ...{ color: colorsV2.metals.metal0 } },
})

/**
 * Row representing streams/views for a particular interval
 */
export const EntityStreamsIntervalTableRow: React.FC<RowData> = ({
  label,
  interval,
  maxIntervalStreams,
  currentIntervalStreams,
  changePercentage,
}) => (
  <View
    style={[
      {
        flexDirection: 'row',
        flex: 1,
        alignItems: 'center',
      },
    ]}
  >
    <View style={{ flexDirection: 'row', width: '50%', alignItems: 'center' }}>
      <View style={{ flex: 1, flexBasis: 0 }}>
        <Text style={styles.text}>{label}</Text>
      </View>
      <View
        style={{
          flex: 1,
          flexBasis: 0,
          alignItems: 'flex-end',
        }}
      >
        <BarChart
          data={maxIntervalStreams}
          style={{ height: 14, width: 100 }}
          barStyle={(i, item) => ({
            minHeight: 1,
            fill: df.isWithinInterval(parseDateString(item.date), interval)
              ? colorsV2.offWhite
              : colorsV2.metals.metal2,
          })}
          barWidth={1}
          valueExtractor={(item) => item.data ?? 0}
          statusExtractor={(item) => 'full'} // Don't display "x" in this tiny graph
        />
      </View>
    </View>
    <View style={{ flexDirection: 'row', width: '50%', alignItems: 'center' }}>
      <View style={{ flex: 1, flexBasis: 0, alignItems: 'flex-end' }}>
        <Text style={styles.text}>
          {formatCountShort(sumDateData(currentIntervalStreams))}
        </Text>
      </View>
      <View
        style={{
          flex: 1,
          flexBasis: 0,
          alignItems: 'flex-end',
          justifyContent: 'flex-end',
        }}
      >
        <PercentPill percentage={changePercentage} size={'small'} />
      </View>
    </View>
  </View>
)

export const EntityStreamsIntervalTableRowSkeleton: React.FC<{}> = () => {
  return (
    <View
      style={{
        flexDirection: 'row',
        flex: 1,
      }}
    >
      <View
        style={{
          flex: 1,
          flexDirection: 'row',
          justifyContent: 'space-between',
        }}
      >
        <Bone style={{ width: 22, height: 14 }} />
        <Bone style={{ width: 100, height: 14 }} />
        <Bone style={{ width: 45, height: 14 }} />
        <Bone style={{ width: 45, height: 14 }} />
      </View>
    </View>
  )
}

/**
 *
 * View count information for an entity (video or track) for a set of intervals
 */
export const EntityStreamsIntervalTableRows = ({
  useEntityStreams,
}: {
  entityId: string
  countryCode: string
  useEntityStreams: (interval: Interval) => StreamsByDateResult
}): JSX.Element[] => {
  function getRows() {
    const rows = [...timeIntervalOptions]
      .sort((a, b) => a.days - b.days)
      .map((timeInterval) => {
        const currentInterval = timeRangeInterval(timeInterval.value)
        const summary = useEntityStreamsSummary(
          currentInterval,
          useEntityStreams
        )?.data
        return summary !== null
          ? {
              label: timeInterval.labelShort,
              interval: currentInterval,
              ...summary,
            }
          : null
      })
    return rows.every(notEmpty) ? rows : null
  }

  const rows = getRows()
  const maxIntervalStreams =
    rows != null ? rows[rows.length - 1]?.currentIntervalStreams ?? null : null

  return rows && maxIntervalStreams
    ? rows.flatMap((rowData, i) => {
        const { currentIntervalStreams, changePercentage } = rowData
        return currentIntervalStreams != null && changePercentage != null ? (
          <EntityStreamsIntervalTableRow
            key={i}
            {...rowData}
            currentIntervalStreams={currentIntervalStreams}
            changePercentage={changePercentage}
            maxIntervalStreams={maxIntervalStreams}
          />
        ) : (
          []
        )
      })
    : Object.keys(timeIntervalOptions).map((key) => (
        <EntityStreamsIntervalTableRowSkeleton key={key} />
      ))
}
