import { TextField, InputAdornment } from '@mui/material';
import { Doc } from '../../../../fields/Doc';
import React = require('react');
import TaskAltIcon from '@mui/icons-material/TaskAlt';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
import { isNumber } from 'lodash';
export interface IInputProps {
    label?: JSX.Element;
    lowerBound: number;
    dataDoc: Doc;
    prop: string;
    step: number;
    unit: string;
    upperBound: number;
    value: number | string | Array<number | string>;
    correctValue?: number;
    showIcon?: boolean;
    effect?: (val: number) => any;
    radianEquivalent?: boolean;
    small?: boolean;
    mode?: string;
    update?: boolean;
    labelWidth?: string;
}

interface IState {
    tempValue: string | number | (string | number)[];
    tempRadianValue: number;
    width: string;
    margin: string;
}

export default class InputField extends React.Component<IInputProps, IState> {
    constructor(props: any) {
        super(props);
        this.state = {
            tempValue: this.props.mode != 'Freeform' && !this.props.showIcon ? 0 : this.props.value,
            tempRadianValue: this.props.mode != 'Freeform' && !this.props.showIcon ? 0 : (Number(this.props.value) * Math.PI) / 180,
            width: this.props.small ? '6em' : '7em',
            margin: this.props.small ? '0px' : '10px',
        };
    }

    epsilon: number = 0.01;

    componentDidMount(): void {
        this.setState({ tempValue: Number(this.props.value) });
    }

    componentDidUpdate(prevProps: Readonly<IInputProps>, prevState: Readonly<IState>, snapshot?: any): void {
        if (prevProps.value != this.props.value && isNumber(this.props.value) && !isNaN(this.props.value)) {
            if (this.props.mode == 'Freeform') {
                if (isNumber(this.state.tempValue) && Math.abs(this.state.tempValue - Number(this.props.value)) > 1) {
                    this.setState({ tempValue: Number(this.props.value) });
                }
            }
        }
        if (prevProps.update != this.props.update) {
            this.externalUpdate();
        }
    }

    externalUpdate = () => {
        this.setState({ tempValue: Number(this.props.value) });
        this.setState({ tempRadianValue: (Number(this.props.value) * Math.PI) / 180 });
    };

    onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        let value = event.target.value == '' ? 0 : Number(event.target.value);
        if (value > this.props.upperBound) {
            value = this.props.upperBound;
        } else if (value < this.props.lowerBound) {
            value = this.props.lowerBound;
        }
        if (this.props.prop != '') {
            this.props.dataDoc[this.props.prop] = value;
        }
        this.setState({ tempValue: event.target.value == '' ? event.target.value : value });
        this.setState({ tempRadianValue: (value * Math.PI) / 180 });
        if (this.props.effect) {
            this.props.effect(value);
        }
    };

    onChangeRadianValue = (event: React.ChangeEvent<HTMLInputElement>) => {
        let value = event.target.value === '' ? 0 : Number(event.target.value);
        if (value > 2 * Math.PI) {
            value = 2 * Math.PI;
        } else if (value < 0) {
            value = 0;
        }
        if (this.props.prop != '') {
            this.props.dataDoc[this.props.prop] = (value * 180) / Math.PI;
        }
        this.setState({ tempValue: (value * 180) / Math.PI });
        this.setState({ tempRadianValue: value });
        if (this.props.effect) {
            this.props.effect((value * 180) / Math.PI);
        }
    };

    render() {
        return (
            <div
                style={{
                    display: 'flex',
                    lineHeight: '1.5',
                    textAlign: 'right',
                    alignItems: 'center',
                }}>
                {this.props.label && (
                    <div
                        style={{
                            marginTop: '0.3em',
                            marginBottom: '-0.5em',
                            width: this.props.labelWidth ?? '2em',
                        }}>
                        {this.props.label}
                    </div>
                )}
                <TextField
                    type="number"
                    variant="standard"
                    value={this.state.tempValue}
                    onChange={this.onChange}
                    sx={{
                        height: '1em',
                        width: this.state.width,
                        marginLeft: this.state.margin,
                        zIndex: 'modal',
                    }}
                    inputProps={{
                        step: this.props.step,
                        min: this.props.lowerBound,
                        max: this.props.upperBound,
                        type: 'number',
                    }}
                    InputProps={{
                        startAdornment: (
                            <InputAdornment position="start">
                                {Math.abs(Number(this.props.value) - (this.props.correctValue ?? 0)) < this.epsilon && this.props.showIcon && <TaskAltIcon color={'success'} />}
                                {Math.abs(Number(this.props.value) - (this.props.correctValue ?? 0)) >= this.epsilon && this.props.showIcon && <ErrorOutlineIcon color={'error'} />}
                            </InputAdornment>
                        ),
                        endAdornment: <InputAdornment position="end">{this.props.unit}</InputAdornment>,
                    }}
                />
                {this.props.radianEquivalent && (
                    <div style={{ marginTop: '0.3em', marginBottom: '-0.5em', width: '1em' }}>
                        <p>≈</p>
                    </div>
                )}
                {this.props.radianEquivalent && (
                    <TextField
                        type="number"
                        variant="standard"
                        value={this.state.tempRadianValue}
                        onChange={this.onChangeRadianValue}
                        sx={{
                            height: '1em',
                            width: this.state.width,
                            marginLeft: this.state.margin,
                            zIndex: 'modal',
                        }}
                        inputProps={{
                            step: Math.PI / 8,
                            min: 0,
                            max: 2 * Math.PI,
                            type: 'number',
                        }}
                        InputProps={{
                            endAdornment: <InputAdornment position="end">rad</InputAdornment>,
                        }}
                    />
                )}
            </div>
        );
    }
}
