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

import { Dsp } from '../Consts'
import { NavigationProp } from '../Navigation'
import { CommonScreenContainer } from '../components/CommonScreenContainer'
import { ContextMenuItem } from '../components/ContextMenuModal'
import { ErrorBoundary } from '../components/ErrorBoundary'
import { GraphDetailScreenHeader } from '../components/GraphDetailScreenHeader'
import { HeaderNav } from '../components/HeaderNav'
import { MarketSelectorButton } from '../components/MarketSelectorButton'
import { TimeIntervalSelector } from '../components/TimeIntervalSelector'
import { ScreenNames } from '../constants/ScreenNames'
import { ScreenContext } from '../contexts/ScreenContext'
import { NetworkError } from '../hooks/useNetwork'
import { useScreenRefreshControl } from '../hooks/useScreenRefreshControl'
import { TimeInterval } from '../types/TimeInterval'
import { formatDate, timeRangeInterval } from '../util'
import { formatInterval } from '../util/date'

export const GraphScreenContent: React.FC<{
  screenName: string
  screenTitle?: string
  title: string
  headerImage: React.ReactNode
  dsp: Dsp | 'all'
  countryCode: string
  selectedTimeInterval: TimeInterval
  selectTimeInterval: (timeInterval: TimeInterval) => void
  onSelectTimeInterval: (timeInterval: TimeInterval) => void
  error: NetworkError | null
  showToast: boolean
  navigation: NavigationProp<ScreenNames>
  retry: () => void
  refreshing: boolean
  onPressMarketSelectorButton?: () => void
  renderSelectedDateSummary: (
    selectedInterval: Interval,
    selectedTimeInterval: TimeInterval,
    selectedBar: number | null
  ) => React.ReactNode
  renderSelectedIntervalSummary?: (
    selectedInterval: Interval
  ) => React.ReactNode
  renderGraph: (
    selectedBar: number | null,
    selectBar: (number: number | null) => void,
    selectedInterval: Interval,
    selectedTimeInterval: TimeInterval,
    selectTimeInterval: (timeInterval: TimeInterval) => void,
    setScrollEnabled: (enabled: boolean) => void
  ) => React.ReactNode
  contextMenuItems?: ContextMenuItem[]
}> = ({
  screenName,
  screenTitle,
  title,
  headerImage,
  dsp,
  countryCode,
  selectedTimeInterval,
  selectTimeInterval,
  onSelectTimeInterval,
  error,
  showToast,
  navigation,
  retry,
  refreshing,
  onPressMarketSelectorButton,
  renderSelectedDateSummary,
  renderSelectedIntervalSummary,
  renderGraph,
  contextMenuItems,
}) => {
  useEffect(() => {
    onSelectTimeInterval(selectedTimeInterval)
  }, [onSelectTimeInterval, selectedTimeInterval])

  const selectedInterval = timeRangeInterval(selectedTimeInterval)
  const [selectedBar, selectBar] = useState<number | null>(null)
  const [scrollEnabled, setScrollEnabled] = useState<boolean>(true)
  const { refreshControl, screenContext } = useScreenRefreshControl(
    retry,
    refreshing
  )

  const selectedDate =
    selectedBar != null
      ? df.eachDayOfInterval(selectedInterval)[selectedBar]
      : null

  const subTitle =
    selectedDate != null
      ? formatDate(selectedDate)
      : formatInterval(selectedInterval)

  return (
    <ScreenContext.Provider value={screenContext}>
      <CommonScreenContainer screenName={screenName}>
        <HeaderNav
          title={screenTitle}
          showToast={showToast}
          navigation={navigation}
          style={{ zIndex: 10 }}
          right={
            onPressMarketSelectorButton != null ? (
              <MarketSelectorButton
                countryCode={countryCode}
                onPress={onPressMarketSelectorButton}
              />
            ) : null
          }
          contextMenuItems={contextMenuItems}
        />
        <ErrorBoundary error={error} refreshControl={refreshControl}>
          <ScrollView
            refreshControl={refreshControl}
            showsVerticalScrollIndicator={false}
            contentContainerStyle={{
              flex: 1,
            }}
            scrollEnabled={scrollEnabled}
          >
            <View
              style={{
                flex: 1,
                paddingHorizontal: 8,
              }}
            >
              <View style={{ flex: 1 }}>
                <View>
                  <GraphDetailScreenHeader
                    image={headerImage}
                    title={title}
                    subTitle={subTitle}
                    dsp={dsp}
                  />

                  <View style={{ minHeight: 150 }}>
                    {renderSelectedDateSummary?.(
                      selectedInterval,
                      selectedTimeInterval,
                      selectedBar
                    )}
                    {selectedBar === null &&
                      renderSelectedIntervalSummary?.(selectedInterval)}
                  </View>
                </View>

                {renderGraph(
                  selectedBar,
                  selectBar,
                  selectedInterval,
                  selectedTimeInterval,
                  selectTimeInterval,
                  setScrollEnabled
                )}
                <TimeIntervalSelector
                  onSelectTimeInterval={selectTimeInterval}
                  selectedTimeInterval={selectedTimeInterval}
                />
              </View>
            </View>
          </ScrollView>
        </ErrorBoundary>
      </CommonScreenContainer>
    </ScreenContext.Provider>
  )
}
