import React, { useEffect, useState, useRef } from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import debounce from 'lodash/debounce';
import { makeStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';
import AddIcon from '@material-ui/icons/Add';
import RemoveIcon from '@material-ui/icons/Remove';
import AccessibleButton from '../../../../Shared/Components/AccessibleButton/AccessibleButton';

const useStyles = makeStyles(
    () => {
        const amountColor = 'rgba(0,0,0,0.1)';
        const plusBorder = '1px solid ' + amountColor;

        return {
            minus: {
                '&:hover': {
                    color: 'rgba(0,0,0, 0.5)',
                },
                '&.disable': {
                    color: 'rgba(0, 0, 0, 0.26)',
                    cursor: 'auto',
                    '&:hover': {
                        color: 'rgba(0,0,0, 0.26)',
                    },
                },
            },
            plus: {
                '&:hover': {
                    color: 'rgba(0,0,0, 0.5)',
                },
            },
            value: {
                borderTop: '1px solid rgba(0,0,0,0.1)',
                borderBottom: '1px solid rgba(0,0,0,0.1)',
                '& .MuiInput-underline:before': {
                    content: 'none',
                },
                '& .MuiInput-underline:after': {
                    borderBottom: 'none',
                },
                '& input': {
                    textAlign: 'center',
                },
            },
            root: {
                display: 'flex',
                alignItems: 'center',
                flexDirection: 'column',
                maxWidth: 35,
                float: 'right',
                border: plusBorder,
                '&.horizontal': {
                    flexDirection: 'row-reverse',
                    maxWidth: '100%',
                    float: 'left',
                    marginBottom: 8,
                    '& $value': {
                        width: 35,
                        minWidth: 35,
                        borderWidth: '0 1px 0 1px',
                        borderStyle: 'solid',
                        borderColor: 'rgba(0,0,0,0.1)',
                    },
                    '& svg': {
                        padding: 8,
                    },
                },
                '& svg': {
                    height: 20,
                    width: 20,
                    padding: '6px 0',
                },
                '& > span': {
                    display: 'block',
                    height: 30,
                    textAlign: 'center',
                    verticalAlign: 'middle',
                    lineHeight: '30px',
                    fontSize: 20,
                    fontFamily: 'Roboto',
                    '& $plus': {
                        backgroundColor: amountColor,
                    },
                    '& $minus': {
                        backgroundColor: amountColor,
                    },
                    '& $value': {
                        backgroundColor: 'white',
                    },
                },
            },
        };
    },
    { name: 'OptionAmount' }
);

const OptionAmount = ({ option, onAmountChange, onSelect, view }) => {
    const classes = useStyles();
    const textRef = useRef();
    const [optionAmount, setOptionAmount] = useState(0);
    useEffect(() => {
        setOptionAmount(option.amount === null ? 0 : option.amount);
    }, [option]);

    const onAmountClicked = event => {
        event.stopPropagation();
    };

    const plus = () => {
        onAmountChange(parseInt(textRef.current.value) + 1);
    };

    const minus = () => {
        onAmountChange(parseInt(textRef.current.value) - 1);
    };

    const onChangeDebounced = debounce(() => {
        onSelect({
            ...option,
            amount: isNaN(parseInt(textRef.current.value)) ? 0 : parseInt(textRef.current.value),
        });
    }, 1000);

    const updateAmount = async e => {
        if (!isNaN(parseInt(e.target.value))) {
            setOptionAmount(parseInt(e.target.value));
        } else {
            setOptionAmount('');
        }
        onChangeDebounced();
    };

    return (
        <div className={clsx(classes.root, view)} onClick={onAmountClicked}>
            <AccessibleButton onClick={plus}>
                <AddIcon className={classes.plus} />
            </AccessibleButton>
            <TextField
                value={optionAmount}
                inputRef={textRef}
                onChange={updateAmount}
                className={classes.value}
                onFocus={event => {
                    // select text async for mac os safari
                    const target = event.target;
                    setTimeout(() => target.select(), 0);
                }}
            />
            <AccessibleButton onClick={minus} disabled={!optionAmount}>
                <RemoveIcon className={clsx(classes.minus, !optionAmount && 'disable')} />
            </AccessibleButton>
        </div>
    );
};

OptionAmount.defaultProps = {
    option: {},
    onAmountChange: () => {},
    onSelect: () => {},
};

OptionAmount.propTypes = {
    option: PropTypes.object,
    onAmountChange: PropTypes.func,
    onSelect: PropTypes.func,
    view: PropTypes.string,
};

export default OptionAmount;
