import React from 'react';

import Paper from '@mui/material/Paper';
import {FormControlLabel, Checkbox, Stack, Tooltip, ListItem, List, Radio, RadioGroup, Typography} from "@mui/material";
import NumberTextField from "./NumberTextField";
import {azim_int_settings} from "../openapi";
import _ from "lodash";
import ButtonWithSnackbar from "./ButtonWithSnackbar";
import FormControl from "@mui/material/FormControl";

type MyProps = {
    s?: azim_int_settings
};

type MyState = {
    s: azim_int_settings
    last_downloaded_s: azim_int_settings
    download_counter: number
    low_q_error: boolean
    high_q_error: boolean
    q_spacing_error: boolean
};

const default_azim_int_settings : azim_int_settings = {
    solid_angle_corr: true,
    polarization_corr: true,
    high_q_recipA: 5,
    low_q_recipA: 0.1,
    q_spacing: 0.1,
    azimuthal_bins: 1,
    force_cpu: false
}

class AzIntSettings extends React.Component<MyProps, MyState> {
    state : MyState = {
        s: default_azim_int_settings,
        last_downloaded_s: default_azim_int_settings,
        download_counter: 0,
        low_q_error: false,
        high_q_error: false,
        q_spacing_error: false,
    }

    getValues = () => {
        if (this.props.s !== undefined) {
            let format_set: azim_int_settings = this.props.s;
            if (!_.isEqual(format_set, this.state.last_downloaded_s)) {
                this.setState(prevState => ({
                    s: format_set,
                    last_downloaded_s: format_set,
                    download_counter: prevState.download_counter + 1
                }));
            }
        }
    }

    componentDidMount() {
        this.getValues();
    }

    componentDidUpdate() {
        this.getValues();
    }

    render() {
        return <Paper style={{textAlign: 'center'}} sx={{ width: '100%'}}>
            <br/>
            <Stack spacing={3} sx={{
                justifyContent: "center",
                alignItems: "center",
                marginLeft: '8%',
                marginRight: '8%',
            }}>
                <div><strong>Azimuthal integration settings </strong></div>
                <Stack spacing={2} direction="row">
                    <NumberTextField
                        default={1.0}
                        start_val={this.state.s.q_spacing}
                        label={"Q spacing"}
                        min={1e-5}
                        units={"A-1"}
                        float={true}
                        counter={this.state.download_counter}
                        callback={(val: number, err: boolean) => {
                            this.setState(prevState => ({
                                s: {...prevState.s, q_spacing: val},
                                q_spacing_error: err
                            }));
                        }}
                        fullWidth/>

                    <NumberTextField
                        default={0.1}
                        start_val={this.state.s.low_q_recipA}
                        label={"Low Q"}
                        min={1e-5}
                        max={10.0}
                        units={"A-1"}
                        float={true}
                        counter={this.state.download_counter}
                        callback={(val: number, err: boolean) => {
                            this.setState(prevState => ({
                                s: {...prevState.s, low_q_recipA: val},
                                low_q_error: err
                            }));
                        }}
                        fullWidth/>

                    <NumberTextField
                        default={5}
                        start_val={this.state.s.high_q_recipA}
                        label={"High Q"}
                        min={1e-5}
                        max={10.0}
                        units={"A-1"}
                        float={true}
                        counter={this.state.download_counter}
                        callback={(val: number, err: boolean) => {
                            this.setState(prevState => ({
                                s: {...prevState.s, high_q_recipA: val},
                                high_q_error: err
                            }));
                        }}
                        fullWidth/>
                </Stack>
                <FormControl>
                <FormControlLabel control={
                    <Checkbox
                        checked={this.state.s.solid_angle_corr}
                        onChange={
                            (event: React.ChangeEvent<HTMLInputElement>) => {
                                this.state.s.solid_angle_corr = event.target.checked;
                            }}
                    />} label="Solid angle correction"/>
                <FormControlLabel control={
                    <Checkbox
                        checked={this.state.s.polarization_corr}
                        onChange={
                            (event: React.ChangeEvent<HTMLInputElement>) => {
                                this.state.s.polarization_corr = event.target.checked;
                            }}
                    />} label="Polarization correction"/>
                    <FormControlLabel control={
                        <Checkbox
                            checked={this.state.s.force_cpu ?? false}
                            onChange={
                                (event: React.ChangeEvent<HTMLInputElement>) => {
                                    this.state.s.force_cpu = event.target.checked;
                                }}
                        />} label="Force CPU calculation in FPGA workflow"/>
                </FormControl>
                <Typography>Azimuthal bins</Typography>
                <FormControl component="fieldset">
                    <RadioGroup
                        row
                        value={this.state.s.azimuthal_bins}
                        onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
                            this.setState(prevState => ({
                                s: {...prevState.s, azimuthal_bins: Number(event.target.value)}
                            }));
                        }}
                    >
                        {[1, 2, 4, 8, 16, 32, 64, 128].map((value) => (
                            <FormControlLabel
                                key={value}
                                value={value}
                                control={<Radio/>}
                                label={value.toString()}
                            />
                        ))}
                    </RadioGroup>
                </FormControl>

                <ButtonWithSnackbar
                    color={"primary"}
                    path={"/config/azim_int"}
                    input={JSON.stringify(this.state.s)}
                    method={"PUT"}
                    text={"Upload"}
                    disabled={
                        (this.state.s.high_q_recipA <= this.state.s.low_q_recipA)
                        || this.state.high_q_error
                        || this.state.low_q_error
                        || this.state.q_spacing_error
                    }
                />
            </Stack>
            <br/>
        </Paper>
    }
}

export default AzIntSettings;
