import React from 'react';
import PropTypes from 'prop-types';
import findIndex from 'lodash/findIndex';
import get from 'lodash/get';
import clsx from 'clsx';
import { makeStyles } from '@material-ui/core/styles';
import DialogContent from '@material-ui/core/DialogContent';
import LoadingOverlay from 'Framework/Components/LoadingOverlay';
import CustomDialog from 'Shared/Components/CustomDialog';
import customClassName from 'App/Utils/customClassName';
import Option from '../Option';

const useStyles = makeStyles(
    theme => {
        return {
            dialogStyle: {
                height: '100%',
                [theme.breakpoints.down('sm')]: {
                    width: '100%',
                    maxWidth: '390px',
                },
                [theme.breakpoints.between('sm', 'xl')]: {
                    width: '470px',
                    maxWidth: '470px',
                },
                [theme.breakpoints.up('md')]: {
                    marginLeft: '120px',
                    '& .MuiBackdrop-root': {
                        left: '140px',
                    },
                },
            },
            [theme.breakpoints.between('sm', 'md')]: {
                [theme.orientation.portrait]: {
                    top: '-110px !important',
                },
            },
            '& > div.MuiDialog-container': {
                [theme.breakpoints.between('sm', 'lg')]: {
                    [theme.orientation.portrait]: {
                        alignItems: 'flex-end',
                    },
                    [theme.orientation.landscape]: {
                        alignItems: 'flex-start',
                        marginTop: 35,
                    },
                },
            },
            contentStyle: {},
            backDrop: {
                backgroundColor: 'rgba(0,0,0,0.0)',
            },
        };
    },
    {
        name: 'OptionsList',
    }
);

const OptionsList = ({ render, ...props }) => {
    const {
        addCheckedOptionclassification,
        children,
        isLoading,
        onClose,
        onSelect,
        onToggle,
        optionclassification,
        options,
        show,
        viewDetails,
        viewStockInformation,
        LoadingComponent,
        OptionComponent,
        isAdminMode,
        setOptionInputText,
    } = props;

    const classes = useStyles();

    const createOptions = () => {
        const onOptionClicked = () => {
            addCheckedOptionclassification(optionclassification);
        };

        return options.map(option => {
            let optionIndex = -1;

            const optionGroupChildren = get(option, 'option_group.children', []);

            if (optionGroupChildren.length === 0) {
                optionIndex = findIndex(get(optionclassification, 'selectedoptions'), {
                    identifier: option.identifier,
                });
            } else {
                for (const item of optionGroupChildren) {
                    optionIndex = findIndex(get(optionclassification, 'selectedoptions'), {
                        identifier: item.identifier,
                    });
                    if (optionIndex > -1) {
                        // we need the first selected option
                        break;
                    }
                }
            }

            const selected = optionIndex <= -1 ? false : !(option.amount_is_selectable && option.amount < 1);

            return (
                <OptionComponent
                    key={'optionlistitem' + option.identifier}
                    option={option}
                    optionclassification={optionclassification}
                    onSelect={onSelect}
                    selected={selected}
                    viewDetails={viewDetails}
                    viewStockInformation={viewStockInformation}
                    onClick={onOptionClicked}
                    onInputTextChange={setOptionInputText}
                    onToggle={onToggle}
                    isAdminMode={isAdminMode}
                />
            );
        });
    };

    const renderOptions = () => {
        const optionListItems = createOptions();

        return (
            <div>
                {children ? children : optionListItems.length > 0 ? optionListItems : null}
                <LoadingComponent show={isLoading} />
            </div>
        );
    };

    const renderOptionsList = () => {
        return (
            <CustomDialog
                className={clsx(classes.dialogStyle, customClassName('options'))}
                dialogTitle={optionclassification.title}
                onCancel={onClose}
                onClose={onClose}
                open={show && !!optionclassification.identifier}
                BackdropProps={{
                    classes: {
                        root: classes.backDrop,
                    },
                }}
            >
                <DialogContent className={classes.contentStyle}>{renderOptions()}</DialogContent>
            </CustomDialog>
        );
    };

    const getRenderProps = () => ({
        ...props,
        renderOptions,
        createOptions,
        renderOptionsList,
    });

    return typeof render === 'function' ? render(getRenderProps()) : renderOptionsList();
};

OptionsList.defaultProps = {
    addCheckedOptionclassification: () => {},
    isLoading: false,
    onClose: () => {},
    onSelect: () => {},
    onToggle: () => {},
    options: [],
    optionclassification: {},
    show: false,
    viewDetails: () => {},
    viewStockInformation: () => {},
    LoadingComponent: LoadingOverlay,
    OptionComponent: Option,
};

OptionsList.propTypes = {
    addCheckedOptionclassification: PropTypes.func,
    children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
    isLoading: PropTypes.bool,
    onClose: PropTypes.func,
    onSelect: PropTypes.func,
    onToggle: PropTypes.func,
    setOptionInputText: PropTypes.func,
    options: PropTypes.array,
    optionclassification: PropTypes.object,
    show: PropTypes.bool,
    viewDetails: PropTypes.func,
    viewStockInformation: PropTypes.func,
    LoadingComponent: PropTypes.elementType,
    OptionComponent: PropTypes.elementType,
    isAdminMode: PropTypes.bool,
    render: PropTypes.func,
};

export default OptionsList;
