import React from 'react';
import { withStyles } from '@material-ui/core/styles';
import withWidth from '@material-ui/core/withWidth';
import PropTypes from 'prop-types';
import clsx from 'clsx';

const styles = theme => ({
    root: {
        display: 'flex',
        flexDirection: 'column',
        position: 'absolute',
        top: 0,
        bottom: 0,
        left: 0,
        right: 0,
        overflowX: 'hidden',
        overflowY: 'hidden',
        '&$fallbackMode': {
            '& $main': {
                [theme.breakpoints.up('md')]: {
                    width: '100%',
                },
                '@media (orientation: landscape)': {
                    flexDirection: 'row',
                },
            },
        },
        // helper classes can be used on contained elements
        '& .noShrink': {
            flexShrink: 0,
        },
        '& .verticalSpacing': {
            marginTop: theme.spacing(1),
            marginBottom: theme.spacing(1),
        },
        '& .md': {
            [theme.breakpoints.up('md')]: {},
        },
        '& .sm': {
            [theme.breakpoints.down('sm')]: {},
        },
    },
    fallbackMode: {},
    header: {
        zIndex: 1,
    },
    container: {
        flex: 1,
        display: 'flex',
        flexDirection: 'row',
        position: 'relative',

        [theme.breakpoints.down('xs')]: {
            flexDirection: 'column',
        },
        '&.fullSize': {
            width: '100%',
            height: '100%',
            paddingLeft: 0,
        },
        '&.reducedSize': {
            width: 'calc(100% - 140px)',
            marginLeft: 140,
        },
        '&.fullScreen': {
            width: '100%',
            height: '100%',
            marginLeft: 0,
        },
        [theme.breakpoints.between('xs', theme.creator.viewSelectBreakpoint)]: {
            height: 'calc(100% - 136px)',
        },
    },
    containerTabletPortrait: {
        flexDirection: 'column',
    },
    main: {
        flex: 1,
        display: 'flex',
        flexDirection: 'column',
        position: 'relative',

        // the pointer events should be passed through to the visualization component
        pointerEvents: 'none', // important: don't remove this
    },
    productsList: {
        position: 'absolute',

        '&.horizontal': {
            bottom: 2,
            [theme.breakpoints.down('xs')]: {
                width: '100%',
                left: 0,
                bottom: 88,
            },
            [theme.breakpoints.up('sm')]: {
                width: 'calc(100% - 370px)',
                minWidth: 215,
                marginBottom: 0,
            },
        },
        '&.vertical': {
            float: 'left',
            height: 'calc(100% - 68px)',
            minHeight: 120,
            width: 140,
            left: theme.spacing(1),
            top: theme.spacing(1),
        },
    },
    shoppingCart: {
        display: 'block',
    },
    outerContainer: {
        height: '100%',
        position: 'relative',
        flex: 1,
        display: 'flex',
        marginRight: 20,
        [theme.breakpoints.up('md')]: {
            marginBottom: 24,
        },
        [theme.breakpoints.down('md')]: {
            marginBottom: 16,
        },
        [theme.breakpoints.down('xs')]: {
            margin: 16,
        },
        '&.withBottomList': {
            [theme.breakpoints.down('xs')]: {
                height: 'calc(100% - 36px)',
            },
            '& .dots-container': {
                bottom: 0,
                [theme.breakpoints.down('xs')]: {
                    bottom: -16,
                },
            },
        },
    },
    visualization: {
        // the visualization is in the background with absolute positioning
        position: 'absolute',
        width: '100%',
        height: '100%',
        [theme.breakpoints.down('xs')]: {
            height: '75%',
        },
        [theme.breakpoints.down(theme.creator.viewSelectBreakpoint)]: {
            height: 'calc(100% - 18px)',
        },
        '&.withBottomList': {
            [theme.breakpoints.between('xs', 'sm')]: {
                height: 'calc(100% - 198px)',
            },
            [theme.breakpoints.up('sm')]: {
                height: 'calc(100% - 152px)',
            },
        },
        '&.fullScreen': {
            height: '100%',
        },
    },
});

const DefaultLayout = ({
    width,
    classes,

    renderHeader,
    renderMain,
    renderInForeground,
    renderProductsList,
    renderShoppingCart,
    renderVisualization,
    renderLoader,
    renderLicenseNotice,
    renderInvalidConfigurationNotice,

    fallbackMode,
    isPortraitMode,
    displayVerticalList,
    imageOnly,
}) => {
    const content = imageOnly ? (
        <React.Fragment>
            <div className={clsx(classes.outerContainer, !displayVerticalList && 'withBottomList')}>
                <div
                    className={`${classes.container}  ${imageOnly ? 'fullScreen' : ''} ${
                        isPortraitMode ? classes.containerTabletPortrait : ''
                    } ${displayVerticalList ? 'reducedSize' : 'fullSize'}`}
                >
                    {!fallbackMode && (
                        <div
                            className={`${classes.visualization} ${imageOnly ? 'fullScreen' : ''} ${
                                displayVerticalList ? '' : 'withBottomList'
                            }`}
                        >
                            {renderVisualization()}
                        </div>
                    )}
                    <div className={classes.main}>
                        {renderMain({
                            area: 'main',
                            width,
                            classes,
                        })}
                    </div>
                </div>
            </div>
        </React.Fragment>
    ) : (
        renderInForeground() || (
            <React.Fragment>
                {renderLicenseNotice({ mobileOffset: 110 })}
                {renderInvalidConfigurationNotice()}
                <div className={classes.header}>
                    {renderHeader({
                        area: 'header',
                        width,
                        classes,
                    })}
                </div>
                <div className={clsx(classes.outerContainer, !displayVerticalList && 'withBottomList')}>
                    <div
                        className={`${classes.productsList} ${
                            displayVerticalList ? 'vertical' : 'horizontal'
                        }`}
                    >
                        {renderProductsList({
                            area: 'products',
                            width,
                            classes,
                            displayVerticalList,
                        })}
                    </div>
                    <div
                        className={`${classes.container} ${
                            isPortraitMode ? classes.containerTabletPortrait : ''
                        } ${displayVerticalList ? 'reducedSize' : 'fullSize'}`}
                    >
                        {!fallbackMode && (
                            <div
                                className={`${classes.visualization} ${
                                    displayVerticalList ? '' : 'withBottomList'
                                }`}
                            >
                                {renderVisualization()}
                            </div>
                        )}
                        <div className={classes.main}>
                            {renderMain({
                                area: 'main',
                                width,
                                classes,
                            })}
                        </div>
                    </div>
                    <div className={classes.shoppingCart}>
                        {renderShoppingCart({
                            area: 'cart',
                            width,
                            classes,
                        })}
                    </div>
                </div>
            </React.Fragment>
        )
    );
    return (
        <div className={`${classes.root} ${fallbackMode ? classes.fallbackMode : ''}`}>
            {content}
            {renderLoader()}
        </div>
    );
};

const getDefaultComponent = () => null;

DefaultLayout.propTypes = {
    classes: PropTypes.object,
    width: PropTypes.string,

    renderHeader: PropTypes.func,
    renderMain: PropTypes.func,
    renderInForeground: PropTypes.func,
    renderProductsList: PropTypes.func,
    renderShoppingCart: PropTypes.func,
    renderVisualization: PropTypes.func,
    renderLoader: PropTypes.func,
    renderLicenseNotice: PropTypes.func,
    renderInvalidConfigurationNotice: PropTypes.func,

    fallbackMode: PropTypes.bool,
    isPortraitMode: PropTypes.bool,
    displayVerticalList: PropTypes.bool,
    imageOnly: PropTypes.bool,
};

DefaultLayout.defaultProps = {
    renderHeader: getDefaultComponent,
    renderLoader: getDefaultComponent,
    renderMain: getDefaultComponent,
    renderInForeground: getDefaultComponent,
    renderProductsList: getDefaultComponent,
    renderShoppingCart: getDefaultComponent,
    renderVisualization: getDefaultComponent,
    displayVerticalList: true,
};

export default withStyles(styles, { name: 'DefaultLayout' })(
    withWidth({ initialWidth: 'xl' })(DefaultLayout)
);
