import React, { useState, useEffect, useContext } from 'react'
import { DateTime } from 'luxon'
import {
  IConsumptionDataManager,
  IDataload,
  IChartData,
  ChartData,
  TimeStep,
  ITimePeriod,
} from 'services/dataConsumptionContracts'
import { defineTimePeriod } from 'services/dateChartService'
import { FluidType } from 'enum/fluid.enum'

import BarChart from 'components/ContentComponents/Charts/BarChart'
import { AppContext } from 'components/Contexts/AppContextProvider'
import StyledSpinner from 'components/CommonKit/Spinner/StyledSpinner'

interface FluidChartSlideProps {
  index: number
  fluidTypes: FluidType[]
  timeStep: TimeStep
  multiFluid: boolean
  referenceDate: DateTime
  selectedDate: DateTime
  showCompare: boolean
  width: number
  height: number
  challengePeriod: ITimePeriod | null
  handleClickData: (
    dataload: IDataload,
    compareDataload: IDataload | null
  ) => void
  consumptionDataManager: IConsumptionDataManager
  isSwitching: boolean
}

const FluidChartSlide: React.FC<FluidChartSlideProps> = ({
  index,
  fluidTypes,
  timeStep,
  multiFluid,
  referenceDate,
  selectedDate,
  showCompare,
  width,
  height,
  challengePeriod,
  handleClickData,
  consumptionDataManager,
  isSwitching,
}: FluidChartSlideProps) => {
  const [chartData, setChartData] = useState<IChartData>(new ChartData([]))
  const [isLoaded, setIsLoaded] = useState<boolean>(false)

  const { setChartIsLoaded, maxLoads, chartIsLoaded } = useContext(AppContext)

  const isHome: boolean = !window.location.hash.split('/')[2] ? true : false

  useEffect(() => {
    let subscribed = true
    async function loadData() {
      const [timePeriod, compareTimePeriod] = await Promise.all([
        defineTimePeriod(referenceDate, timeStep, index),
        defineTimePeriod(referenceDate, timeStep, index + 1),
      ])

      const graphData = await consumptionDataManager.getGraphData(
        timePeriod,
        timeStep,
        fluidTypes,
        compareTimePeriod,
        isHome
      )

      if (subscribed && graphData && graphData.actualData.length > 0) {
        setChartData(graphData)
        setIsLoaded(true)
      }
    }
    setIsLoaded(false)

    loadData()
    return () => {
      subscribed = false
    }
  }, [timeStep, fluidTypes])

  useEffect(() => {
    let subscribed = true

    const actualMonth = selectedDate.startOf('week').month
    const actualYear = selectedDate.startOf('week').year

    const maxTimePeriod = {
      startDate:
        timeStep === TimeStep.HALF_AN_HOUR
          ? selectedDate.startOf('month')
          : selectedDate.startOf('week').startOf('month').weekdayLong ===
            'lundi'
          ? selectedDate.startOf('week').startOf('month')
          : selectedDate
              .startOf('week')
              .startOf('month')
              .plus({ days: +7 })
              .startOf('week'),
      endDate:
        timeStep === TimeStep.HALF_AN_HOUR
          ? selectedDate.endOf('month')
          : selectedDate.startOf('week').month !==
            selectedDate.endOf('week').month
          ? selectedDate.endOf('week')
          : selectedDate.endOf('month').endOf('week'),
    }

    const compareMaxTimePeriod = maxTimePeriod

    const key = `${actualMonth}/${actualYear}-${isHome}-${fluidTypes
      .sort()
      .join('-')}-${timeStep}`
    async function loadData() {
      setChartIsLoaded(false)
      const graphMaxLoad = await consumptionDataManager.getMaxLoad(
        maxTimePeriod,
        timeStep,
        fluidTypes,
        compareMaxTimePeriod,
        isHome
      )

      maxLoads[key] = graphMaxLoad

      if (subscribed && graphMaxLoad) {
        setIsLoaded(true)
        setChartIsLoaded(true)
      }
    }
    if (
      key in maxLoads === false &&
      (timeStep === TimeStep.DAY || timeStep === TimeStep.HALF_AN_HOUR)
    ) {
      loadData()
    }
    return () => {
      subscribed = false
    }
  }, [selectedDate, fluidTypes])

  return (
    <>
      <div className="fs-slide">
        {!chartIsLoaded || !isLoaded ? (
          <div className="chart-loading">
            <StyledSpinner size="5em" fluidTypes={fluidTypes} isHome={isHome} />
          </div>
        ) : (
          <BarChart
            chartData={chartData}
            fluidTypes={fluidTypes}
            timeStep={timeStep}
            multiFluid={multiFluid}
            selectedDate={selectedDate}
            showCompare={showCompare}
            handleClickData={handleClickData}
            height={height}
            width={width}
            challengePeriod={challengePeriod}
            isSwitching={isSwitching}
            isHome={isHome}
          />
        )}
      </div>
    </>
  )
}

export default FluidChartSlide