text: import * as React from 'react';
  import StatTitle from './StatTitle';
  import {ResponsiveLine, Serie, Datum} from '@nivo/line';
  import {SpacedRepStat, StatType} from "polar-firebase/src/firebase/om/SpacedRepStats";
  import {Statistics} from "polar-shared/src/util/Statistics";
  import {ISODateTimeString, ISODateTimeStrings} from "polar-shared/src/metadata/ISODateTimeStrings";
  import {RepetitionMode, StageCountsCalculator} from "polar-spaced-repetition-api/src/scheduler/S2Plus/S2Plus";
  import {ReviewerStatistics} from "../reviewer/ReviewerStatistics";
  import {Logger} from "polar-shared/src/logger/Logger";
  import {StatBox} from "./StatBox";
  import {LoadingProgress} from "../../../../web/js/ui/LoadingProgress";
  import { minDatapointsReducer, sumDatapointsReducer } from './StatisticsReducers';
  import {useNivoTheme} from "./NivoHooks";
  
  const HEIGHT = '300px';
  
  const log = Logger.create();
  
  interface ChartProps {
      readonly type: 'queue' | 'completed';
      readonly lineData: Serie[];
  }
  
  const Chart = React.memo((props: ChartProps) => {
  
      const nivoTheme = useNivoTheme();
  
      const createTitle = () => {
          switch (props.type) {
              case "queue":
                  return "Number of tasks pending (queue length)";
              case "completed":
                  return "Number of tasks completed";
          }
      };
  
      const title = createTitle();
  
      return (
  
          <StatBox>
              <>
                  <StatTitle>{title}</StatTitle>
  
                  <div style={{
                           height: HEIGHT,
                           width: '100%'
                       }}>
  
                      <ResponsiveLine
                          data={props.lineData}
                          // isInteractive={true}
                          margin={{
                              top: 10,
                              right: 10,
                              bottom: 50,
                              left: 40
                          }}
                          // padding={0.3}
                          colors={{ scheme: 'nivo' }}
                          // colorBy="id"
                          enableArea={true}
                          yScale={{
                              type: 'linear'
                          }}
                          xScale={{
                              type: 'time',
                              // format: '%Y-%m-%dT%h:%m:%s.%msZ',
                              // format: '%Y-%m-%d',
                              // precision: 'day',
                          }}
                          // xFormat="time:%Y-%m-%d"
                          axisBottom={{
                              format: '%b %d',
                              // tickValues: ['every 2 days', 'every 2 days', 'every 2 days'],
                              tickValues: 5,
                              // legend: 'time scale',
                              // legendOffset: -12,
                          }}
                          // useMesh={true}
                          // enablePointLabel={true}
                          animate={true}
                          theme={nivoTheme}
                      />
                  </div>
              </>
          </StatBox>
  
      );
  
  });
  
  const NeedChardData = () => {
      // return <div className="text-lg text-muted mt-2"
      //             style={{
      //                 display: 'flex',
      //                 height: '100%'
      //             }}>
      //
      //     <div className="m-auto">
      //         More data needed for reliable chart.
      //     </div>
      // </div>;
  
      return <div/>;
  
  };
  
  export class SpacedRepQueueChart extends React.Component<IProps, IState> {
  
      constructor(props: Readonly<IProps>) {
          super(props);
  
          this.state = {
              data: undefined
          };
      }
  
      public componentDidMount(): void {
  
          // TODO: this is actually a bug because the first time we do too many queries..
  
          // TODO: migrate to the new data loader component which also means we will get one copy
          // and use snapshots too.
  
          ReviewerStatistics.statistics(this.props.mode, this.props.type)
              .then(data => this.setState({data}))
              .catch(err => log.error("Could not fetch queue stats: ", err));
  
      }
  
      public render() {
  
          const {data} = this.state;
  
          if (! data) {
              return <LoadingProgress style={{height: HEIGHT}}/>;
          }
  
  
          // TODO: these need better stats sections for incremental reading and flashcards as we should have counts,
          // forecasting, and completed for all...
  
          const computeStats = () => {
  
              // TODO: limit on the most recent N points so that I don't crowd up the UI BUT the points need to be
              // extrapolated including gaps for time because I could have one datapoint 5 years ago and another today
              // and the interpolated points shown in the graph would be too many
  
              // TODO:
              //  - create synthetic 'zero' values for days we don't actually do any work..
              //
  
              const createDatapointsReducer = () => {
                  switch (this.props.type) {
                      case "queue":
                          return minDatapointsReducer;
                      case "completed":
                          return sumDatapointsReducer;
                  }
              };
  
              const emptyDatapointFactory = (created: ISODateTimeString): SpacedRepStat => {
  
                  return {
                      created,
                      type: this.props.type,
                      mode: this.props.mode,
                      nrNew: 0,
                      nrLapsed: 0,
                      nrLearning: 0,
                      nrReview: 0
                  };
  
              };
  
              return Statistics.compute(data, createDatapointsReducer(), emptyDatapointFactory);
  
          };
  
          const stats = computeStats();
  
          const computeLineData = () => {
  
              type StatID = 'nrLearning' | 'nrReview' | 'nrLapsed';
  
              // const computeLine = (id: StatID): LineSerieData => {
              //     return {
              //         id,
              //         data: [
              //             // {x: new Date('2019-11-01'), y: 100},
              //             // {x: '2019-11-01', y: 100},
              //             // {x: '2019-11-02', y: 150},
              //             // {x: '2019-11-03', y: 120},
              //         ]
              //     }
              // };
  
              const toDataPoint = (spacedRepStat: SpacedRepStat, id: StatID): Datum => {
  
                  const x = ISODateTimeStrings.parse(spacedRepStat.created);
                  // const y = spacedRepStat.nrLearning;
                  const y = (spacedRepStat as any)[id];
                  return {x, y};
  
              };
  
              const computeLine = (id: StatID): Serie => {
                  return {
                      id,
                      data: stats.map(current => toDataPoint(current, id))
                  };
              };
  
              return [
                  computeLine('nrLearning'),
                  computeLine('nrReview'),
                  computeLine('nrLapsed')
              ];
  
          };
  
          const lineData: Serie[] = computeLineData();
  
          const Main = () => {
  
              if (lineData[0].data.length < 3) {
                  return <NeedChardData/>;
              } else {
                  return <Chart type={this.props.type}
                                lineData={lineData}/>;
              }
  
          };
  
          return (
              <div>
                  <Main/>
              </div>
          );
  
      }
  
  }
  
  export interface IProps {
      readonly mode: RepetitionMode;
      readonly type: StatType;
  }
  
  export interface IState {
      readonly data: ReadonlyArray<SpacedRepStat> | undefined;
  }
  
  
  