import axios from 'axios';
import React, { Suspense, lazy } from 'react';
import { Col, Grid, Row } from 'react-bootstrap';
import createPlotlyComponent from 'react-plotly.js/factory';
import { getInstrumentStatistics } from '../../../api/icat/icatPlus';
import ParameterTableWidget from '../../Instrument/ParameterTableWidget';
import Loader from '../../Loader';
import ErrorUserMessage from '../../UserMessages/ErrorUserMessage';
import { stringifyBytesSize } from '../../../helpers';

// https://reactjs.org/docs/code-splitting.html
// https://github.com/plotly/react-plotly.js#customizing-the-plotlyjs-bundle
const Plot = lazy(() =>
  import('plotly.js-basic-dist').then((Plotly) => ({
    default: createPlotlyComponent(Plotly),
  }))
);

class GeneralStatsPanel extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fetching: false,
      fetched: false,
      data: [],
      message: {
        isError: false,
        text: null,
      },
    };
  }

  componentDidMount() {
    this.setState({
      fetching: true,
      fetched: false,
    });

    axios
      .post(getInstrumentStatistics(this.props.user.sessionId), {
        ranges: [
          {
            name: this.props.name,
            start: this.props.start,
            end: this.props.end,
          },
        ],
      })
      .then((response) => {
        const statistics = Object.keys(response.data.startDate.buckets).map(
          (key) => ({
            date: key,
            data: response.data.startDate.buckets[key],
          })
        );
        this.setState({
          fetching: false,
          fetched: true,
          data: statistics,
        });
      })
      .catch(() => {
        this.setState({
          statistics: {
            fetching: false,
            fetched: false,
            data: [],
          },
        });
      });
  }

  getParameters(record) {
    return [
      { name: 'Datasets', value: record.data.doc_count },
      { name: 'Beamlines', value: record.data.instrument.buckets.length },
      {
        name: 'Total Volume',
        value: stringifyBytesSize(record.data.volume_stats.sum),
      },
      { name: 'Total Number of files', value: record.data.fileCount_stats.sum },
    ];
  }

  getStatsParameters(record) {
    if (record.data.doc_count === 0) {
      return;
    }
    return [
      {
        name: 'Average file count',
        value: record.data.fileCount_stats.avg.toFixed(0),
      },
      { name: 'Max files', value: record.data.fileCount_stats.max },
      {
        name: 'Average volume',
        value: stringifyBytesSize(record.data.volume_stats.avg),
      },
      {
        name: 'Max volume',
        value: stringifyBytesSize(record.data.volume_stats.max),
      },
      {
        name: 'Average metadata',
        value: record.data.parametersCount_stats.avg.toFixed(1),
      },
    ];
  }

  render() {
    const _this = this;
    if (this.state.message.isError) {
      return <ErrorUserMessage text={this.state.message.text} />;
    }

    if (this.state.fetching) {
      return <Loader message="Loading statistics..." spacedOut />;
    }

    if (this.state.data.doc_count === 0) {
      if (this.state.data[0].doc_count === 0) {
        return <ErrorUserMessage text="No data found" />;
      }
    }

    return (
      <Suspense fallback={<Loader message="Loading plots..." spacedOut />}>
        {this.state.data.map((record) => (
          <Grid fluid style={{ margin: 20 }}>
            <Row>
              <Col xs={12} md={4}>
                <h4>Summary</h4>
                <ParameterTableWidget
                  striped
                  parameters={_this.getParameters(record)}
                />
              </Col>
              <Col xs={12} md={4}>
                <h4>Dataset</h4>
                <ParameterTableWidget
                  striped
                  parameters={_this.getStatsParameters(record)}
                />
              </Col>
            </Row>
            <Row>
              <Col xs={12}>
                <Plot
                  data={[
                    {
                      type: 'pie',
                      hole: 0.4,
                      textposition: 'inside',

                      labels: record.data.instrument.buckets.map((i) => i.key),
                      values: record.data.instrument.buckets.map(
                        (i) => i.volume_stats.sum
                      ),
                    },
                  ]}
                  layout={{ showLegend: true, title: 'Volume per instrument' }}
                />
              </Col>
              <Col xs={12}>
                <Plot
                  data={[
                    {
                      name: 'Datasets',
                      type: 'bar',
                      x: record.data.instrument.buckets.map((i) => i.key),
                      y: record.data.instrument.buckets.map((i) => i.doc_count),
                    },
                    {
                      x: record.data.instrument.buckets.map((i) => i.key),
                      y: record.data.instrument.buckets.map(
                        (i) => i.fileCount_stats.sum
                      ),
                      type: 'scatter',
                      mode: 'lines+markers',
                      marker: { color: 'red' },
                      yaxis: 'y2',
                      name: 'File count',
                    },
                  ]}
                  layout={{
                    title: 'Datasets',
                    xaxis: { title: 'Instruments' },
                    yaxis: { title: 'Datasets' },
                    showlegend: true,
                    legend: {
                      y: 100,
                      orientation: 'h',
                    },
                    yaxis2: {
                      title: 'Number of files',
                      overlaying: 'y',
                      side: 'right',
                      showgrid: false,
                    },
                  }}
                />
              </Col>
            </Row>
          </Grid>
        ))}
      </Suspense>
    );
  }
}

export default GeneralStatsPanel;
