import React, {Component} from 'react';

import {DefaultService, plots} from "../openapi";
import MultiLinePlotWrapper from "./MultiLinePlotWrapper";

export enum PlotType {
    COLLECTION_EFFICIENCY,
    SPOT_COUNT,
    RAD_INT,
    INDEXING_RATE_PER_FILE,
    INDEXING_RATE,
    RAD_INT_PER_FILE,
    BKG_ESTIMATE,
    ERROR_PIXELS,
    RECEIVER_DELAY,
    STRONG_PIXELS,
    ROI_SUM,
    ROI_MAX_COUNT,
    RES_ESTIMATION,
    RECEIVER_FREE_SEND_BUFS
}

type MyProps = {
    type: PlotType;
    xlabel: string;
    ylabel: string;
    binning: number;
};

type MyState = {
    plots : plots,
    connection_error: boolean
}

type PlotlyPlot = {
    x: number[],
    y: number[],
    type: string,
    mode: string,
    name: string
}

type PlotlyData = PlotlyPlot[]

class DataProcessingPlot extends Component<MyProps, MyState> {
    interval: undefined | NodeJS.Timer;

    state: MyState = {
        plots: {
            plot : [
                {
                    x: [0, 100, 200, 300, 400, 500],
                    y: [0.1, 0.3, 0.5, 0.2, 0.0, 0.1],
                    title: "Example"
                }
            ]
        },
        connection_error: true
    }

    getValues() {
        switch(this.props.type) {
            case PlotType.ERROR_PIXELS:
                DefaultService.postPlotErrorPixel({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.STRONG_PIXELS:
                DefaultService.postPlotStrongPixel({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.COLLECTION_EFFICIENCY:
                DefaultService.postPlotImageCollectionEfficiency({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.SPOT_COUNT:
                DefaultService.postPlotSpotCount({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.BKG_ESTIMATE:
                DefaultService.postPlotBkgEstimate({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.RAD_INT:
                DefaultService.getPlotRadInt()
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.INDEXING_RATE_PER_FILE:
                DefaultService.getPlotIndexingRatePerFile()
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.INDEXING_RATE:
                DefaultService.postPlotIndexingRate({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.RECEIVER_DELAY:
                DefaultService.postPlotReceiverDelay({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.RECEIVER_FREE_SEND_BUFS:
                DefaultService.postPlotReceiverFreeSendBuffers({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.ROI_SUM:
                DefaultService.postPlotRoiSum({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.ROI_MAX_COUNT:
                DefaultService.postPlotRoiMaxCount({binning: this.props.binning})
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.RES_ESTIMATION:
                DefaultService.getPlotResolutionEstimateHistogram()
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
                break;
            case PlotType.RAD_INT_PER_FILE:
                DefaultService.getPlotRadIntPerFile()
                    .then(data => this.setState({plots: data, connection_error: false}))
                    .catch(error => {
                        this.setState({connection_error: true});
                    });
        }
    }
    componentDidMount() {
        this.getValues();
        this.interval = setInterval(() => this.getValues(), 500);
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }

    render() {
        if (this.state.connection_error
            || (this.state.plots === undefined)
            || (this.state.plots.plot === null)
            || (this.state.plots.plot.length === 0))
            return <div>No plots available</div>;

        let data: PlotlyData = [];
        this.state.plots.plot.map(d =>
            data.push({
                x: d.x,
                y: d.y,
                type: "scatter",
                mode: "line",
                name: d.title
            }));

        return <MultiLinePlotWrapper xaxis={this.props.xlabel} yaxis={this.props.ylabel} data={data}/>
    }
}

export default DataProcessingPlot;

