import React, { useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import isEqual from 'lodash/isEqual';
import { withStyles } from '@material-ui/core/styles';
import withWidth from '@material-ui/core/withWidth';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import CardActions from '@material-ui/core/CardActions';
import Grid from '@material-ui/core/Grid';
import { grey } from '@material-ui/core/colors';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogActions from '@material-ui/core/DialogActions';
import Icon from '@material-ui/core/Icon';
import RootRef from '@material-ui/core/RootRef';
import { InView } from 'react-intersection-observer';
import { t } from 'Framework/i18n';
import AnalyticsWrapper from 'App/Shared/Components/Analytics/AnalyticsWrapper';
import customClassName from 'App/Utils/customClassName';
import MainButton from 'Shared/Components/MainButton';
import PriceOverview from '../PriceOverview';
import Notification from '../Notification';
import PriceList from '../PriceList';
import AddToCart from '../AddToBasket';
import ReceiveOfferForm from '../ReceiveOfferForm';
import AcceptDesign from '../AcceptDesign';
import LoadingOverlay from '../../../../Framework/Components/LoadingOverlay';
import { debounce } from '@material-ui/core/utils';
import AcceptPrivacy from '../AcceptPrivacy';
import ConfigurationOverview from '../ConfigurationOverview';
import { isMobileDevice } from 'Framework/Helpers/isMobileDevice';
import IconButton from '@material-ui/core/IconButton';
import AutoFocusDialogContentContainer from '../AutoFocusDialogContentContainer/AutoFocusDialogContentContainer';

const styles = theme => ({
    contentPositioning: {
        paddingLeft: 32,
        paddingRight: 20,
        [theme.breakpoints.down('xs')]: {
            paddingLeft: 0,
            paddingRight: 8,
            marginRight: '-8px',
        },
        '& p': {
            fontSize: 15,
            letterSpacing: 'normal',
        },
        marginRight: 4,
        padding: 0,
    },
    dialogWrapper: {
        borderTop: '7px solid ' + theme.palette.primary.main,
        padding: '0 32px',
        overflow: 'hidden',
        [theme.breakpoints.down('xs')]: {
            padding: '0 16px',
        },
    },
    card: {
        marginBottom: 1,
        borderTop: '7px solid ' + theme.palette.primary.main,
        padding: 15,
        overflow: 'visible',
        [theme.breakpoints.between('xs', 'lg')]: {
            marginTop: 16,
        },
        [theme.breakpoints.down('xs')]: {
            overflow: 'hidden',
            display: 'flex',
            boxShadow: 'none',
            '&:last-child': {
                padding: '12px 0 0',
            },
            paddingTop: 0,
            borderTop: '1px solid ' + grey[500],
            borderRadius: 0,
        },
    },
    cardUnboxed: {
        borderTop: 'none',
        boxShadow: 'none',
        [theme.breakpoints.down('xs')]: {
            display: 'flex',
        },
    },
    cardContentWrapper: {
        [theme.breakpoints.down('xs')]: {
            '&:last-child': {
                paddingBottom: 4,
            },
        },
    },
    AmountPriceContent: {
        padding: 0,
        '&:last-child': {
            paddingBottom: 5,
        },
    },
    dialogPositioning: {
        overflow: 'hidden',
        '& .MuiDialog-container': {
            '& .MuiDialogTitle-root': {
                paddingTop: 25,
                paddingBottom: 15,
                '& p, h2': {
                    fontSize: 24,
                    fontWeight: 'bold',
                    letterSpacing: 'normal',
                },
            },
            '& .MuiDialogActions-root': {
                paddingBottom: 24,
                [theme.breakpoints.down('xs')]: {
                    marginRight: 0,
                },
                marginRight: 8,
            },
            '& .MuiDialogTitle-root, .MuiDialogActions-root': {
                paddingLeft: 32,
                paddingRight: 20,
                marginRight: 4,
                [theme.breakpoints.down('xs')]: {
                    paddingLeft: 0,
                    paddingRight: 0,
                },
                '& p': {
                    fontSize: 15,
                    letterSpacing: 'normal',
                },
            },
        },
        '& .MuiButton-root': {
            height: 40,
            textTransform: 'none',
            minWidth: 140,
            marginTop: 8,
            color: theme.palette.primary.darkText,
            [theme.breakpoints.down('xs')]: {
                height: 56,
            },
        },
    },
    AmountPriceButton: {
        textTransform: 'none',
        whiteSpace: 'nowrap',
        margin: 0,
        padding: '6px 15px',
        [theme.breakpoints.down('xs')]: {
            minWidth: 35,
            padding: 0,
        },
        color: theme.palette.primary.darkText,
    },
    smallButtonSize: {
        [theme.breakpoints.down('xs')]: {
            fontSize: 12,
            lineHeight: 1,
        },
    },
    mainButton: {
        margin: 0,
        padding: '6px 15px',
        height: 40,
        lineHeight: 1.5,
        [theme.breakpoints.down('xs')]: {
            height: 56,
        },
    },
    mainButtonLabel: {
        [theme.breakpoints.down('xs')]: {
            whiteSpace: 'normal',
            fontSize: 12,
        },
        whiteSpace: 'nowrap',
    },
    AmountPriceTypography: {
        textAlign: 'end',
        lineHeight: 1.2,
        fontSize: '1.5rem',
        [theme.breakpoints.down('xs')]: {
            padding: '3px 0',
            textAlign: 'start',
            fontSize: 12,
            lineHeight: 1,
        },
    },
    AmountPriceTypographyVat: {
        fontSize: 9,
        lineHeight: 1.2,
        textAlign: 'end',
        display: 'block',

        [theme.breakpoints.down('xs')]: {
            fontSize: 9,
            textAlign: 'start',
        },
    },
    cardActions: {
        padding: '8px 0',
        [theme.breakpoints.down('xs')]: {
            padding: 0,
        },
    },
    closeIcon: {
        position: 'absolute',
        right: 16,
        top: 16,
        [theme.breakpoints.down('xs')]: {
            right: 0,
        },
        '&:hover': {
            cursor: 'pointer',
        },
    },
    configurationButton: {
        '&:hover': {
            cursor: 'pointer',
        },
        fontWeight: 'bold',
        textTransform: 'none',
        padding: '6px 15px',
        marginRight: '5px',
    },
    summary: {
        display: 'flex',
        alignItems: 'center',
        '& svg': {
            marginRight: 5,
        },
    },
    dialogTitleRoot: {
        padding: '20px 0',
    },
});

const DialogActionsWrapper = ({ onTouchMove, ...props }) => {
    const ref = useRef();
    useEffect(() => {
        const { current } = ref;
        if (current) {
            current.addEventListener('touchmove', onTouchMove, { passive: false });
        }
        return () => {
            if (current) {
                current.removeEventListener('touchmove', onTouchMove, { passive: false });
            }
        };
    }, [onTouchMove]);
    return (
        // as of material-ui v3.x the refs are not forwarded, so the only way to get it is using RootRef
        // FIXME check after updating material-ui
        <RootRef rootRef={ref}>
            <DialogActions {...props} />
        </RootRef>
    );
};

DialogActionsWrapper.propTypes = {
    onTouchMove: PropTypes.func,
};

class AmountPrice extends React.Component {
    static propTypes = {
        boxed: PropTypes.bool,
        classes: PropTypes.object,
        amount: PropTypes.number,
        priceFormatted: PropTypes.string,
        vatNotice: PropTypes.string,
        ProductVariantComponent: PropTypes.elementType.isRequired,
        ConfigurationModeSwitchComponent: PropTypes.elementType.isRequired,
        showConfigurationModeSwitch: PropTypes.bool,
        error: PropTypes.object,
        width: PropTypes.string,
        hidePrices: PropTypes.bool,
        hidePieces: PropTypes.bool,
        priceList: PropTypes.array,
        showProductVariants: PropTypes.bool,
        title: PropTypes.string,
        showCallToAction: PropTypes.bool,
        showReceiveOfferForm: PropTypes.bool,
        onClose: PropTypes.func,
        sendReceiveOfferRequest: PropTypes.func,
        setConfigurationComment: PropTypes.func,
        onSelectableChanged: PropTypes.func,
        onAddToBasket: PropTypes.func,
        isBulkNamesSelected: PropTypes.bool,
        clientTexts: PropTypes.object,
        bulkSavings: PropTypes.array,
        notifications: PropTypes.array,
        displayAcceptDesign: PropTypes.bool,
        bulkNameErrors: PropTypes.array,
        onShowChange: PropTypes.func,
        wrapperClass: PropTypes.string,
        validateConfiguration: PropTypes.func,
        addToCartPopUpLoader: PropTypes.bool,
        ReceiveOfferFormComponent: PropTypes.elementType,
        AcceptDesignComponent: PropTypes.elementType,
        PriceOverviewComponent: PropTypes.elementType,
        ConfigurationOverviewComponent: PropTypes.elementType,
        NotificationComponent: PropTypes.elementType,
        PriceListComponent: PropTypes.elementType,
        AddToCartComponent: PropTypes.elementType,
        renderPriceBox: PropTypes.func,
        userComment: PropTypes.string,
        AcceptPrivacyComponent: PropTypes.elementType,
        userConfiguration: PropTypes.object,
        skipPriceOverview: PropTypes.bool,
        toggleGlobalLoader: PropTypes.func.isRequired,
        isCreator: PropTypes.bool,
        renderDialogTitle: PropTypes.func,
    };

    static defaultProps = {
        showCallToAction: true,
        showConfigurationModeSwitch: false,
        notifications: [],
        clientTexts: {
            termsAndConditionsLink: '',
        },
        hidePieces: false,
        ReceiveOfferFormComponent: ReceiveOfferForm,
        AcceptDesignComponent: AcceptDesign,
        PriceOverviewComponent: PriceOverview,
        ConfigurationOverviewComponent: ConfigurationOverview,
        NotificationComponent: Notification,
        PriceListComponent: PriceList,
        AddToCartComponent: AddToCart,
        AcceptPrivacyComponent: AcceptPrivacy,
        skipPriceOverview: false,
    };

    state = {
        showPriceOverview: false,
        showConfigurationOverview: false,
        notice: '',
        hasErrorReceiveOfferForm: false,
        bulkNameErrors: [],
        approval: {
            value: false,
            error: null,
        },
        inView: true,
        showErrors: false,
        dataPrivacyAccepted: false,
    };

    componentDidUpdate(prevProps, prevState) {
        const { error, bulkNameErrors } = this.props;
        if (error && !isEqual(error, prevProps.error) && this.dialogContentRef.current) {
            this.dialogContentRef.current.scrollTo(0, 0);
        }
        if (bulkNameErrors !== prevProps.bulkNameErrors) {
            this.setState({ bulkNameErrors });
        }
        if (prevProps.addToCartPopUpLoader && !this.props.addToCartPopUpLoader) {
            this.handleClose();
        }
        const { showPriceOverview } = this.state;
        if (showPriceOverview !== prevState.showPriceOverview) {
            const { onShowChange } = this.props;
            onShowChange && onShowChange(showPriceOverview);
        }

        const { showConfigurationOverview } = this.state;
        if (showConfigurationOverview !== prevState.showConfigurationOverview) {
            const { onShowChange } = this.props;
            onShowChange && onShowChange(showConfigurationOverview);
        }

        if (this.state.notice === prevState.notice && this.props.userComment !== this.state.notice) {
            this.setState({ notice: this.props.userComment });
        }
    }

    receiveOfferFormComponentRef = React.createRef();
    dialogContentRef = React.createRef();
    priceListRef = React.createRef();
    acceptDesignRef = React.createRef();
    acceptDataPrivacyRef = React.createRef();

    handleChange = event => {
        this.setState({
            [event.target.name]: {
                value: event.target.checked,
                error: null,
            },
        });
    };

    verifyRequestErrors = hasFormValidationErrors => {
        const { bulkNameErrors, displayAcceptDesign } = this.props;
        const designApproved = this.state.approval.value;
        if (bulkNameErrors && bulkNameErrors.length > 0) {
            this.setState({ showErrors: true });
            this.setState({ bulkNameErrors });
            this.dialogContentRef.current.scrollTo(0, 0);
        }
        if (displayAcceptDesign && !designApproved) {
            this.setState({
                approval: {
                    value: false,
                    error: true,
                },
            });
            !hasFormValidationErrors &&
                this.acceptDesignRef.current &&
                this.acceptDesignRef.current.scrollIntoView();
        }
        if (!this.dataPrivacyApproved()) {
            this.setState({
                dataPrivacyAccepted: {
                    value: false,
                    error: true,
                },
            });
            !hasFormValidationErrors &&
                this.acceptDataPrivacyRef.current &&
                this.acceptDataPrivacyRef.current.scrollIntoView();
        }
    };

    requestHasErrors = () => {
        const { bulkNameErrors, displayAcceptDesign } = this.props;
        const designApproved = this.state.approval.value;
        if (
            (bulkNameErrors && bulkNameErrors.length > 0) ||
            (displayAcceptDesign && !designApproved) ||
            !this.dataPrivacyApproved()
        ) {
            return true;
        }
        return false;
    };

    onAddToBasket = () => {
        const { onAddToBasket } = this.props;
        if (!this.requestHasErrors()) {
            onAddToBasket();
        } else {
            this.verifyRequestErrors();
        }
    };

    dataPrivacyApproved = () => {
        const { showReceiveOfferForm, clientTexts } = this.props;
        const { dataPrivacyLink } = clientTexts;
        const dataPrivacyApproved = this.state.dataPrivacyAccepted.value;
        return !dataPrivacyLink || !showReceiveOfferForm || dataPrivacyApproved;
    };

    handleTouchMove = (evt => {
        const dialogContent = this.dialogContentRef.current;
        evt.preventDefault();
        dialogContent.scrollTo(0, dialogContent.scrollTop);
    }).bind(this);

    openPriceOverview = async () => {
        try {
            await this.props.validateConfiguration();
            this.setState({
                showPriceOverview: !this.state.showPriceOverview,
                hasErrorReceiveOfferForm: false,
            });
        } catch (e) {
            // eslint-disable-next-line no-console
            console.warn(`Error while validating configuration: ${e}`);
        }
    };

    openConfigurationOverview = async () => {
        try {
            await this.props.validateConfiguration();
            this.setState({
                showConfigurationOverview: true,
                hasErrorReceiveOfferForm: false,
            });
        } catch (e) {
            // eslint-disable-next-line no-console
            console.warn(`Error while validating configuration: ${e}`);
        }
    };

    onAddToCartClick = async () => {
        if (this.props.skipPriceOverview) {
            try {
                this.props.toggleGlobalLoader(true);
                await this.props.validateConfiguration();
                return await this.props.onAddToBasket();
            } catch (e) {
                // eslint-disable-next-line no-console
                console.warn(`Error while validating configuration: ${e}`);
            } finally {
                this.props.toggleGlobalLoader(false);
            }
            return;
        }
        return this.openPriceOverview();
    };

    handleClose = () => {
        this.setState({
            showConfigurationOverview: false,
            showPriceOverview: false,
            bulkNameErrors: [],
            approval: {
                value: false,
                error: null,
            },
            showErrors: false,
        });
        this.props.onClose();
    };

    onReceiveOfferFormPress = async () => {
        const formValidation = this.receiveOfferFormComponentRef.current.validate();
        if (!this.requestHasErrors() && formValidation) {
            const result = await this.props.sendReceiveOfferRequest(formValidation);
            if (!result) {
                this.setState({ hasErrorReceiveOfferForm: true });
                this.dialogContentRef.current.scrollTo(0, 0);
            }
            if (result) {
                this.setState({ hasErrorReceiveOfferForm: false });
            }
        } else {
            this.verifyRequestErrors(formValidation.hasError);
        }
    };

    setConfigurationCommentDebounced = debounce(value => this.props.setConfigurationComment(value), 700);

    handleBasketNoticeChange = event => {
        this.setState({ notice: event.target.value });
        this.setConfigurationCommentDebounced(event.target.value);
    };

    onSelectableChanged = priceData => (key, newSelected) => {
        const nextData = priceData.map(currentElement => {
            if (currentElement.key === key) {
                return {
                    ...currentElement,
                    selected: newSelected,
                    price: newSelected ? '10,00 €' : '0,00 €',
                };
            }
            return currentElement;
        });
        this.setState({ priceData: nextData });
    };

    priceListClick = () => {
        this.priceListRef.current.scrollIntoView();
    };

    showPriceListButton = inView => {
        this.setState({ inView: inView });
    };

    renderConfigurationOverview() {
        const { showConfigurationOverview } = this.state;

        const { ConfigurationOverviewComponent, userConfiguration, width, classes } = this.props;

        const dialogTitleId = 'configuration-overview-dialog-title';

        return (
            <Dialog
                aria-labelledby={dialogTitleId}
                classes={{
                    paper: classes.dialogWrapper,
                    container: width === 'md' || width === 'xs' ? classes.dialogPositioning : '',
                    root: classes.dialogPositioning,
                }}
                BackdropProps={{ className: classes.dialogPositioning }}
                onClose={this.handleClose.bind(this)}
                open={showConfigurationOverview}
                fullWidth
                fullScreen={width === 'sm' || width === 'xs'}
                scroll="paper"
            >
                <LoadingOverlay show={this.props.addToCartPopUpLoader} />
                <DialogTitle classes={{ root: classes.dialogTitleRoot }}>
                    <Typography variant="body1" id={dialogTitleId}>
                        <b>{t('amountPrice.configurationOverview')}</b>
                    </Typography>
                    <IconButton className={classes.closeIcon} onClick={this.handleClose.bind(this)}>
                        <Icon>close</Icon>
                    </IconButton>
                </DialogTitle>
                <RootRef rootRef={this.dialogContentRef}>
                    <DialogContent classes={{ root: classes.contentPositioning }}>
                        <ConfigurationOverviewComponent
                            optionclassifications={userConfiguration.optionclassifications}
                        />
                    </DialogContent>
                </RootRef>
            </Dialog>
        );
    }

    renderDialogTitle(options) {
        const { dialogTitleId } = options;
        return this.props.renderDialogTitle ? (
            this.props.renderDialogTitle(this.props, options)
        ) : (
            <Typography variant="body1" id={dialogTitleId}>
                <b>
                    {t(
                        this.props.showReceiveOfferForm
                            ? 'receiveOfferForm.sendButton'
                            : 'amountPrice.intoCart'
                    )}
                </b>
            </Typography>
        );
    }

    renderPriceOverview() {
        const {
            notice,
            showPriceOverview,
            approval,
            inView,
            showErrors,
            bulkNameErrors,
            dataPrivacyAccepted,
        } = this.state;
        const {
            amount,
            priceList,
            priceFormatted,
            onSelectableChanged,
            showProductVariants,
            ProductVariantComponent,
            error,
            width,
            hidePrices,
            title,
            classes,
            showReceiveOfferForm,
            vatNotice,
            clientTexts,
            displayAcceptDesign,
            notifications,
            showCallToAction,
            ReceiveOfferFormComponent,
            AcceptDesignComponent,
            PriceOverviewComponent,
            NotificationComponent,
            PriceListComponent,
            AddToCartComponent,
            AcceptPrivacyComponent,
        } = this.props;

        const { termsAndConditionsLink, dataPrivacyLink } = clientTexts;
        const mergedNotifications = [...notifications] || [];

        if (showErrors && bulkNameErrors && bulkNameErrors.length > 0) {
            bulkNameErrors.map(error => {
                mergedNotifications.push({
                    message: error,
                    level: 'error',
                    color: 'error',
                });
            });
        }

        const dialogTitleId = 'price-overview-dialog-title';

        return (
            <Dialog
                aria-labelledby={dialogTitleId}
                classes={{
                    paper: classes.dialogWrapper,
                    container: width === 'md' || width === 'xs' ? classes.dialogPositioning : '',
                    root: classes.dialogPositioning,
                }}
                BackdropProps={{ className: classes.dialogPositioning }}
                onClose={this.handleClose.bind(this)}
                open={showPriceOverview}
                maxWidth={'md'}
                fullWidth
                fullScreen={width === 'sm' || width === 'xs'}
                scroll="paper"
            >
                <LoadingOverlay show={this.props.addToCartPopUpLoader} />
                <DialogTitle classes={{ root: classes.dialogTitleRoot }}>
                    {this.renderDialogTitle({ dialogTitleId })}
                    <IconButton onClick={this.handleClose.bind(this)} className={classes.closeIcon}>
                        <Icon>close</Icon>
                    </IconButton>
                </DialogTitle>
                <RootRef rootRef={this.dialogContentRef}>
                    <AutoFocusDialogContentContainer
                        Component={DialogContent}
                        classes={{ root: classes.contentPositioning }}
                    >
                        {this.state.hasErrorReceiveOfferForm && (
                            <Typography color="error" variant="body2">
                                {t('receiveOfferForm.checkInputsInForm')}
                            </Typography>
                        )}
                        <PriceOverviewComponent
                            title={t('amountPrice.productVariants')}
                            contactData={t('amountPrice.contactData')}
                            handleClose={this.handleClose}
                            amount={amount}
                            acceptDesignComponent={
                                showCallToAction ? (
                                    <div ref={this.acceptDesignRef}>
                                        <AcceptDesignComponent
                                            termsAndConditionsLink={termsAndConditionsLink}
                                            displayAcceptDesign={displayAcceptDesign}
                                            handleChangeCheckboxApproval={this.handleChange}
                                            approval={approval}
                                            closeProductOverviewDialog={this.handleClose}
                                            notice={notice}
                                            noteLabel={t('amountPrice.notice')}
                                            handleChange={this.handleBasketNoticeChange}
                                        />
                                    </div>
                                ) : null
                            }
                            acceptDataPrivacyComponent={
                                showReceiveOfferForm && dataPrivacyLink ? (
                                    <div ref={this.acceptDataPrivacyRef}>
                                        <AcceptPrivacyComponent
                                            dataPrivacyLink={dataPrivacyLink}
                                            displayAcceptDesign={true}
                                            handleChangeCheckboxApproval={this.handleChange}
                                            approval={dataPrivacyAccepted}
                                            closeProductOverviewDialog={this.handleClose}
                                            displayNote={false}
                                        />
                                    </div>
                                ) : null
                            }
                            notificationComponent={mergedNotifications.map(
                                ({ message, level, color }, key) => {
                                    return (
                                        <NotificationComponent
                                            key={key}
                                            icon={level}
                                            color={color}
                                            notification={message}
                                        />
                                    );
                                }
                            )}
                            priceListComponent={
                                <div ref={this.priceListRef}>
                                    <InView as="div" onChange={inView => this.showPriceListButton(inView)}>
                                        <PriceListComponent
                                            amount={amount}
                                            list={priceList}
                                            totalPrice={priceFormatted}
                                            taxNote={t('amountPrice.vatNotice')}
                                            onSelectableChanged={onSelectableChanged}
                                            hidePrices={hidePrices}
                                            showReceiveOfferForm={showReceiveOfferForm}
                                            productTitle={title}
                                        />
                                    </InView>
                                </div>
                            }
                            productVariantComponent={showProductVariants && <ProductVariantComponent />}
                            receiveOfferFormComponent={
                                <ReceiveOfferFormComponent innerRef={this.receiveOfferFormComponentRef} />
                            }
                            showReceiveOfferForm={showReceiveOfferForm}
                        />
                    </AutoFocusDialogContentContainer>
                </RootRef>
                <DialogActionsWrapper onTouchMove={this.handleTouchMove}>
                    <AddToCartComponent
                        buttonLabel={t(
                            showReceiveOfferForm ? 'receiveOfferForm.sendButton' : 'amountPrice.intoCart'
                        )}
                        showCallToAction={showCallToAction}
                        onPress={showReceiveOfferForm ? this.onReceiveOfferFormPress : this.onAddToBasket}
                        handleChange={this.handleBasketNoticeChange}
                        disabled={!!error}
                        totalPrice={priceFormatted}
                        taxNote={vatNotice}
                        showPriceList={!inView}
                        priceListLabel={t('amountPrice.showPriceList')}
                        priceListClick={this.priceListClick}
                        hidePrices={hidePrices}
                        amount={amount}
                        showReceiveOfferForm={showReceiveOfferForm}
                    />
                </DialogActionsWrapper>
            </Dialog>
        );
    }

    renderDefaultPriceBox = () => {
        const {
            classes,
            amount,
            boxed,
            priceFormatted,
            hidePrices,
            hidePieces,
            vatNotice,
            showReceiveOfferForm,
            showCallToAction,
            showConfigurationModeSwitch,
            ConfigurationModeSwitchComponent,
            isCreator,
            width,
        } = this.props;

        const isMobile = isMobileDevice() || width === 'xs';
        const boxStyle = boxed ? classes.card : classes.cardUnboxed;
        return (
            <Card className={clsx(boxStyle, customClassName('cta-box'))}>
                <Grid item xs={3} sm={12}>
                    <CardContent
                        className={classes.cardContentWrapper}
                        classes={{ root: classes.AmountPriceContent }}
                    >
                        {isCreator && !isMobile && (
                            <Grid container>
                                <Grid item xs={12} sm={12} md={12} lg={12} className={classes.summary}>
                                    <Icon>list_alt</Icon>
                                    <Button
                                        className={classes.configurationButton}
                                        variant="text"
                                        size="small"
                                        onClick={this.openConfigurationOverview}
                                    >
                                        {t('amountPrice.configurationOverview')}
                                    </Button>
                                </Grid>
                            </Grid>
                        )}
                        <Grid container>
                            {!hidePieces && (
                                <Grid item xs={12} sm={6} md={5} lg={5}>
                                    <Button
                                        variant="text"
                                        size="small"
                                        onClick={this.openPriceOverview}
                                        classes={{
                                            root: classes.AmountPriceButton,
                                            sizeSmall: classes.smallButtonSize,
                                        }}
                                    >
                                        {amount} {t('amountPrice.pieces')}
                                    </Button>
                                </Grid>
                            )}
                            {!hidePrices && (
                                <Grid item xs={12} sm={6} md={7} lg={7}>
                                    <Typography
                                        variant="body2"
                                        classes={{
                                            root: classes.AmountPriceTypography,
                                        }}
                                    >
                                        <b>{priceFormatted}</b>
                                    </Typography>
                                    {priceFormatted && (
                                        <Typography
                                            className={classes.pos}
                                            variant="caption"
                                            classes={{
                                                root: classes.AmountPriceTypographyVat,
                                            }}
                                        >
                                            <i>{vatNotice}</i>
                                        </Typography>
                                    )}
                                </Grid>
                            )}
                        </Grid>
                    </CardContent>
                </Grid>
                <Grid item xs={9} sm={12}>
                    <CardActions className={classes.cardActions}>
                        <Grid container spacing={1}>
                            {showConfigurationModeSwitch && (
                                <Grid item xs={showCallToAction ? 6 : 12}>
                                    <ConfigurationModeSwitchComponent
                                        className={customClassName('configuration-type-button')}
                                        classes={{
                                            root: classes.mainButton,
                                            label: classes.mainButtonLabel,
                                        }}
                                    />
                                </Grid>
                            )}
                            {showCallToAction && (
                                <Grid item xs={showConfigurationModeSwitch ? 6 : 12}>
                                    <AnalyticsWrapper targetId="add_to_cart">
                                        <MainButton
                                            className={customClassName('cta-button')}
                                            variant="contained"
                                            fullWidth
                                            size="medium"
                                            onClick={this.onAddToCartClick}
                                            classes={{
                                                root: classes.mainButton,
                                                label: classes.mainButtonLabel,
                                            }}
                                        >
                                            {t(
                                                showReceiveOfferForm
                                                    ? 'receiveOfferForm.sendButton'
                                                    : 'amountPrice.intoCart'
                                            )}
                                        </MainButton>
                                    </AnalyticsWrapper>
                                </Grid>
                            )}
                        </Grid>
                    </CardActions>
                </Grid>
            </Card>
        );
    };

    render() {
        const { wrapperClass, renderPriceBox, ...props } = this.props;

        const { showPriceOverview, showConfigurationOverview } = this.state;
        const { openPriceOverview, openConfigurationOverview, renderDefaultPriceBox } = this;

        return (
            <div className={wrapperClass}>
                {renderPriceBox
                    ? renderPriceBox({
                          ...props,
                          openPriceOverview,
                          openConfigurationOverview,
                          renderDefaultPriceBox,
                      })
                    : this.renderDefaultPriceBox()}
                {showPriceOverview && this.renderPriceOverview()}
                {showConfigurationOverview && this.renderConfigurationOverview()}
            </div>
        );
    }
}

export default withWidth()(withStyles(styles, { name: 'AmountPrice' })(AmountPrice));
