text: import TimeseriesLoader from './loaders/Timeseries';
  
  import {
    STATE_NAMES,
    STATISTIC_CONFIGS,
    TIMESERIES_CHART_TYPES,
    TIMESERIES_LOOKBACK_DAYS,
    TIMESERIES_STATISTICS,
  } from '../constants';
  import useIsVisible from '../hooks/useIsVisible';
  import {
    getIndiaDateYesterdayISO,
    parseIndiaDate,
    retry,
  } from '../utils/commonFunctions';
  
  import {PinIcon, ReplyIcon} from '@primer/octicons-react';
  import classnames from 'classnames';
  import {min} from 'd3-array';
  import {formatISO, subDays} from 'date-fns';
  import equal from 'fast-deep-equal';
  import {
    memo,
    useCallback,
    useEffect,
    useMemo,
    useRef,
    useState,
    lazy,
    Suspense,
  } from 'react';
  import {useTranslation} from 'react-i18next';
  import {useLocalStorage, useWindowSize} from 'react-use';
  
  const Timeseries = lazy(() => retry(() => import('./Timeseries')));
  const TimeseriesBrush = lazy(() => retry(() => import('./TimeseriesBrush')));
  
  function TimeseriesExplorer({
    stateCode,
    timeseries,
    date: timelineDate,
    regionHighlighted,
    setRegionHighlighted,
    anchor,
    setAnchor,
    expandTable = false,
    hideVaccinated = false,
    noRegionHighlightedDistrictData,
  }) {
    const {t} = useTranslation();
    const [lookback, setLookback] = useLocalStorage('timeseriesLookbackDays', 90);
    const [chartType, setChartType] = useLocalStorage('chartType', 'delta');
    const [isUniform, setIsUniform] = useLocalStorage('isUniform', false);
    const [isLog, setIsLog] = useLocalStorage('isLog', false);
    const [isMovingAverage, setIsMovingAverage] = useLocalStorage(
      'isMovingAverage',
      false
    );
  
    const stateCodeDateRange = Object.keys(timeseries?.[stateCode]?.dates || {});
    const beginningDate =
      stateCodeDateRange[0] || timelineDate || getIndiaDateYesterdayISO();
    const endDate = min([
      stateCodeDateRange[stateCodeDateRange.length - 1],
      timelineDate || getIndiaDateYesterdayISO(),
    ]);
  
    const [brushSelectionEnd, setBrushSelectionEnd] = useState(endDate);
    useEffect(() => {
      setBrushSelectionEnd(endDate);
    }, [endDate]);
  
    const brushSelectionStart =
      lookback !== null
        ? formatISO(subDays(parseIndiaDate(brushSelectionEnd), lookback), {
            representation: 'date',
          })
        : beginningDate;
  
    const explorerElement = useRef();
    const isVisible = useIsVisible(explorerElement, {once: true});
    const {width} = useWindowSize();
  
    const selectedRegion = useMemo(() => {
      if (timeseries?.[regionHighlighted.stateCode]?.districts) {
        return {
          stateCode: regionHighlighted.stateCode,
          districtName: regionHighlighted.districtName,
        };
      } else {
        return {
          stateCode: regionHighlighted.stateCode,
          districtName: null,
        };
      }
    }, [timeseries, regionHighlighted.stateCode, regionHighlighted.districtName]);
  
    const selectedTimeseries = useMemo(() => {
      if (selectedRegion.districtName) {
        return timeseries?.[selectedRegion.stateCode]?.districts?.[
          selectedRegion.districtName
        ]?.dates;
      } else {
        return timeseries?.[selectedRegion.stateCode]?.dates;
      }
    }, [timeseries, selectedRegion.stateCode, selectedRegion.districtName]);
  
    const regions = useMemo(() => {
      const states = Object.keys(timeseries || {})
        .filter((code) => code !== stateCode)
        .sort((code1, code2) =>
          STATE_NAMES[code1].localeCompare(STATE_NAMES[code2])
        )
        .map((code) => {
          return {
            stateCode: code,
            districtName: null,
          };
        });
      const districts = Object.keys(timeseries || {}).reduce((acc1, code) => {
        return [
          ...acc1,
          ...Object.keys(timeseries?.[code]?.districts || {}).reduce(
            (acc2, districtName) => {
              return [
                ...acc2,
                {
                  stateCode: code,
                  districtName: districtName,
                },
              ];
            },
            []
          ),
        ];
      }, []);
  
      return [
        {
          stateCode: stateCode,
          districtName: null,
        },
        ...states,
        ...districts,
      ];
    }, [timeseries, stateCode]);
  
    const dropdownRegions = useMemo(() => {
      if (
        regions.find(
          (region) =>
            region.stateCode === regionHighlighted.stateCode &&
            region.districtName === regionHighlighted.districtName
        )
      )
        return regions;
      return [
        ...regions,
        {
          stateCode: regionHighlighted.stateCode,
          districtName: regionHighlighted.districtName,
        },
      ];
    }, [regionHighlighted.stateCode, regionHighlighted.districtName, regions]);
  
    const dates = useMemo(
      () =>
        Object.keys(selectedTimeseries || {}).filter((date) => date <= endDate),
      [selectedTimeseries, endDate]
    );
  
    const brushSelectionDates = useMemo(
      () =>
        dates.filter(
          (date) => brushSelectionStart <= date && date <= brushSelectionEnd
        ),
      [dates, brushSelectionStart, brushSelectionEnd]
    );
  
    const handleChange = useCallback(
      ({target}) => {
        setRegionHighlighted(JSON.parse(target.value));
      },
      [setRegionHighlighted]
    );
  
    const resetDropdown = useCallback(() => {
      setRegionHighlighted({
        stateCode: stateCode,
        districtName: null,
      });
    }, [stateCode, setRegionHighlighted]);
  
    const statistics = useMemo(
      () =>
        TIMESERIES_STATISTICS.filter(
          (statistic) =>
            (!(STATISTIC_CONFIGS[statistic]?.category === 'vaccinated') ||
              !hideVaccinated) &&
            // (chartType === 'total' || statistic !== 'active') &&
            (chartType === 'delta' || statistic !== 'tpr')
        ),
      [chartType, hideVaccinated]
    );
  
    return (
      <div
        className={classnames(
          'TimeseriesExplorer fadeInUp',
          {
            stickied: anchor === 'timeseries',
          },
          {expanded: expandTable}
        )}
        style={{
          marginTop: '8.5rem',
          display:
            anchor && anchor !== 'timeseries' && (!expandTable || width < 769)
              ? 'none'
              : '',
        }}
        ref={explorerElement}
      >
        <div className="timeseries-header">
          {/*<div*/}
          {/*  className={classnames('anchor', 'fadeInUp', {*/}
          {/*    stickied: anchor === 'timeseries',*/}
          {/*  })}*/}
          {/*  style={{*/}
          {/*    display: expandTable && width >= 769 ? 'none' : '',*/}
          {/*  }}*/}
          {/*  onClick={*/}
          {/*    setAnchor &&*/}
          {/*    setAnchor.bind(this, anchor === 'timeseries' ? null : 'timeseries')*/}
          {/*  }*/}
          {/*>*/}
          {/*  <PinIcon />*/}
          {/*</div>*/}
  
          <h1>{t('Symbol & Sector Trends')}</h1>
          <div className="tabs">
            {Object.entries(TIMESERIES_CHART_TYPES).map(
              ([ctype, value], index) => (
                <div
                  className={`tab ${chartType === ctype ? 'focused' : ''}`}
                  key={ctype}
                  onClick={setChartType.bind(this, ctype)}
                >
                  <h4>{t(value)}</h4>
                </div>
              )
            )}
          </div>
  
          <div className="timeseries-options">
            {/*<div className="scale-modes">*/}
            {/*  <label className="main">{`${t('Scale Modes')}:`}</label>*/}
            {/*  <div className="timeseries-mode">*/}
            {/*    <label htmlFor="timeseries-mode">{t('Uniform')}</label>*/}
            {/*    <input*/}
            {/*      id="timeseries-mode"*/}
            {/*      type="checkbox"*/}
            {/*      className="switch"*/}
            {/*      checked={isUniform}*/}
            {/*      aria-label={t('Checked by default to scale uniformly.')}*/}
            {/*      onChange={setIsUniform.bind(this, !isUniform)}*/}
            {/*    />*/}
            {/*  </div>*/}
            {/*  <div*/}
            {/*    className={`timeseries-mode ${*/}
            {/*      chartType !== 'total' ? 'disabled' : ''*/}
            {/*    }`}*/}
            {/*  >*/}
            {/*    <label htmlFor="timeseries-logmode">{t('Logarithmic')}</label>*/}
            {/*    <input*/}
            {/*      id="timeseries-logmode"*/}
            {/*      type="checkbox"*/}
            {/*      checked={chartType === 'total' && isLog}*/}
            {/*      className="switch"*/}
            {/*      disabled={chartType !== 'total'}*/}
            {/*      onChange={setIsLog.bind(this, !isLog)}*/}
            {/*    />*/}
            {/*  </div>*/}
            {/*</div>*/}
  
            {/*<div*/}
            {/*  className={`timeseries-mode ${*/}
            {/*    chartType === 'total' ? 'disabled' : ''*/}
            {/*  } moving-average`}*/}
            {/*>*/}
            {/*  <label htmlFor="timeseries-moving-average">*/}
            {/*    {t('7 day Moving Average')}*/}
            {/*  </label>*/}
            {/*  <input*/}
            {/*    id="timeseries-moving-average"*/}
            {/*    type="checkbox"*/}
            {/*    checked={chartType === 'delta' && isMovingAverage}*/}
            {/*    className="switch"*/}
            {/*    disabled={chartType !== 'delta'}*/}
            {/*    onChange={setIsMovingAverage.bind(this, !isMovingAverage)}*/}
            {/*  />*/}
            {/*</div>*/}
          </div>
        </div>
        {dropdownRegions && (
          <div className="state-selection">
            <div className="dropdown">
              <select
                value={JSON.stringify(selectedRegion)}
                onChange={handleChange}
              >
                {dropdownRegions
                  .filter(
                    (region) =>
                      STATE_NAMES[region.stateCode] !== region.districtName
                  )
                  .map((region) => {
                    return (
                      <option
                        value={JSON.stringify(region)}
                        key={`${region.stateCode}-${region.districtName}`}
                      >
                        {region.districtName
                          ? t(region.districtName)
                          : t(STATE_NAMES[region.stateCode])}
                      </option>
                    );
                  })}
              </select>
            </div>
            <div className="reset-icon" onClick={resetDropdown}>
              <ReplyIcon />
            </div>
          </div>
        )}
        {isVisible && (
          <Suspense fallback={<TimeseriesLoader />}>
            <Timeseries
              timeseries={selectedTimeseries}
              regionHighlighted={selectedRegion}
              dates={brushSelectionDates}
              {...{
                statistics,
                endDate,
                chartType,
                isUniform,
                isLog,
                isMovingAverage,
                noRegionHighlightedDistrictData,
              }}
            />
            <TimeseriesBrush
              timeseries={selectedTimeseries}
              regionHighlighted={selectedRegion}
              currentBrushSelection={[brushSelectionStart, brushSelectionEnd]}
              animationIndex={statistics.length}
              {...{dates, endDate, lookback, setBrushSelectionEnd, setLookback}}
            />
          </Suspense>
        )}
        {!isVisible && <div style={{height: '50rem'}} />}
        <div
          className="pills fadeInUp"
          style={{animationDelay: `${(1 + statistics.length) * 250}ms`}}
        >
          {TIMESERIES_LOOKBACK_DAYS.map((numDays) => (
            <button
              key={numDays}
              type="button"
              className={classnames({
                selected: numDays === lookback,
              })}
              onClick={setLookback.bind(this, numDays)}
            >
              {numDays !== null ? `${numDays} ${t('days')}` : t('Beginning')}
            </button>
          ))}
        </div>
      </div>
    );
  }
  
  const isEqual = (prevProps, currProps) => {
    if (currProps.forceRender) {
      return false;
    } else if (!currProps.timeseries && prevProps.timeseries) {
      return true;
    } else if (currProps.timeseries && !prevProps.timeseries) {
      return false;
    } else if (
      !equal(
        currProps.regionHighlighted.stateCode,
        prevProps.regionHighlighted.stateCode
      )
    ) {
      return false;
    } else if (
      !equal(
        currProps.regionHighlighted.districtName,
        prevProps.regionHighlighted.districtName
      )
    ) {
      return false;
    } else if (!equal(currProps.date, prevProps.date)) {
      return false;
    } else if (!equal(currProps.anchor, prevProps.anchor)) {
      return false;
    } else if (!equal(currProps.expandTable, prevProps.expandTable)) {
      return false;
    } else if (!equal(currProps.hideVaccinated, prevProps.hideVaccinated)) {
      return false;
    } else if (
      !equal(
        currProps.noRegionHighlightedDistrictData,
        prevProps.noRegionHighlightedDistrictData
      )
    ) {
      return false;
    }
    return true;
  };
  
  export default memo(TimeseriesExplorer, isEqual);
  