import React, { useState } from 'react';
import PropTypes from 'prop-types';
import './styles/SelectionPreview.scss';
import { useBodyFixed } from '../../tools/useBodyFixed';
import SelectedAddon from '../selected-addon/SelectedAddon';
import SelectedEdition from '../selected-edition/SelectedEdition';
import Button from '../button/Button';
import Icon from '../icon/Icon';
import { createNamespace } from '../../tools/namingTools';
import { CTA_BUY, CTA_BUY_NOW, CTA_ADD_TO_CART, CTA_MANAGE_APP, CTA_UPDATE_CART_ITEM, CTA_CANCEL, CART_URL } from '../../constants/actions';
import { handleBuyAction, handleAddToCartAction, handleFollowUrlAction } from '../../tools/callToActions';

const n = createNamespace('SelectionPreview');

export const SelectionPreviewComponent = ({
    data: {
        configurator,
        selectedEdition,
        selectedAddons,
        callToActions,
        productImgSrc
    },
    isCondensed,
    isFullscreen,
    onCollapseAddons
}) => {
    const i18n = Object.assign({}, SelectionPreviewComponent.defaultProps.data.configurator.i18n, configurator.i18n);
    const buyActions = callToActions ? callToActions.items : [];
    const defaultAddonsLimit = 1;
    const fullscreenModifier = isFullscreen && 'fullscreen';
    const condensedModifier = isCondensed && 'condensed';
    const [isAddonsCollapsed, setAddonsCollapseState] = useState(true);
    const [addonsLimit, setAddonsLimit] = useState(defaultAddonsLimit);
    // If fullscreen add fixed position to body
    useBodyFixed(isFullscreen, true);

    if (!selectedEdition) {
        return '';
    }

    const handleCollapse = () => {
        const newLimit = isAddonsCollapsed ? selectedAddons.length : defaultAddonsLimit;

        setAddonsLimit(newLimit);
        setAddonsCollapseState(!isAddonsCollapsed);
        onCollapseAddons(isAddonsCollapsed);
    };

    const handleActionTypes = item => {
        let buttonStyle;
        let icon;

        switch (item.actionType) {
            case CTA_MANAGE_APP:
                buttonStyle = 'emphasisAlt';
                break;
            case CTA_ADD_TO_CART:
                buttonStyle = 'emphasisAlt';
                icon = 'cart';
                break;
            case CTA_BUY:
            case CTA_BUY_NOW:
                buttonStyle = 'emphasis';
                break;
            case CTA_UPDATE_CART_ITEM:
                buttonStyle = 'primary';
                break;
            default:
                buttonStyle = item.isPrimary ? 'primary' : 'secondary';
        }
        return { buttonStyle, icon };
    };

    const handleClick = action => {
        const { actionType } = action;

        switch (actionType) {
            case CTA_MANAGE_APP:
            case CTA_CANCEL:
                return handleFollowUrlAction(action);
            case CTA_ADD_TO_CART:
                return handleAddToCartAction(action, selectedEdition, selectedAddons);
            case CTA_BUY:
            case CTA_BUY_NOW:
            case CTA_UPDATE_CART_ITEM:
            default:
                return handleBuyAction(action, selectedEdition, selectedAddons);
        }
    };

    const renderActionButtons = action => {
        const dataId = action.actionType.toLowerCase();
        const actionTypeData = handleActionTypes(action);
        const buttonModifiers = [actionTypeData.icon && 'with-icon', fullscreenModifier];


        // if there is an UPDATE_CART_ITEM action, it means that we also need
        // a CANCEL button which is not defined in calltoactions
        const hasCancelButton = action.actionType === CTA_UPDATE_CART_ITEM;

        const cancelButton = hasCancelButton ? (
            <div {...n('button').props} key="cancel-action">
                <Button
                    wide={!isFullscreen}
                    onClick={() => handleClick({
                        url: CART_URL,
                        actionType: CTA_CANCEL
                    })}
                >
                    {i18n.cancel}
                </Button>
            </div>
        ) : null;

        return (
            <React.Fragment key={action.actionType}>
                <div {...n('button', buttonModifiers).withTestId('actions-container').withE2EId('actions-container').props} key="main-action">
                    <Button
                        data-testid={`button:${dataId}:product`}
                        type={actionTypeData.buttonStyle}
                        wide={!isFullscreen}
                        extraClass={dataId && `btn-${dataId}`}
                        onClick={() => handleClick(action)}
                    >
                        {actionTypeData.icon && <Icon type="cart" {...n('buttonIcon').props} />}
                        {action.label}
                    </Button>
                </div>
                {cancelButton}
            </React.Fragment>

        );
    };

    const renderCollapseAddonsButton = () => {
        const label = isAddonsCollapsed ? `+ ${selectedAddons.length - addonsLimit} ${i18n.more}` : i18n.showLess;

        return (
            <div {...n('btnCollapse').props}>
                <Button
                    buttonType="link"
                    data-testid="button:collapse:addons"
                    type="primary"
                    onClick={() => handleCollapse()}
                >
                    {label}
                </Button>
            </div>
        );
    };

    const renderAddons = () => {
        if (!selectedAddons || !selectedAddons.length) {
            return null;
        }
        return (
            <div {...n('previewList', condensedModifier).props}>
                <div {...n('previewTitle', isCondensed && 'hidden').withTestId().props}>{i18n.selectedAddons}</div>
                {(isAddonsCollapsed ? selectedAddons.slice(0, addonsLimit) : selectedAddons).map(selectedAddon => (
                    <div {...n('previewItem', ['addon', condensedModifier]).withTestId('previewAddonItem').props} key={`selectedAddon-${selectedAddon.name}`}>
                        <SelectedAddon
                            data={selectedAddon}
                            showDescription={!isFullscreen && !isCondensed}
                            showPricing={!isFullscreen && !isCondensed}
                        />
                    </div>
                ))}
                {!isFullscreen && selectedAddons.length > defaultAddonsLimit && renderCollapseAddonsButton()}
            </div>
        );
    };

    const contentModifiers = [condensedModifier, fullscreenModifier];

    return (
        <div {...n('wrapper', contentModifiers).withE2EId().props}>
            <div {...n('content', contentModifiers).props}>
                <div {...n('previewTitle', isCondensed && 'hidden').withTestId().props}>{i18n.selectedEdition}</div>
                <div {...n('previewWrapper', contentModifiers).props}>
                    {isFullscreen && (
                        <React.Fragment>
                            <div {...n('fullscreenTitle').props}>{i18n.selectedProduct}</div>
                            <div {...n('closeFullscreen').props}>
                                <Button buttonType="icon" onClick={() => handleCollapse()}>
                                    <Icon type="close" width="12px" fill="#fff" {...n('closeFullscreenIcon').props} />
                                </Button>
                            </div>
                        </React.Fragment>
                    )}
                    <div {...n('previewContent', contentModifiers).props}>
                        <div {...n('previewItem', 'edition').withTestId('previewEditionItem').props}>
                            <SelectedEdition
                                isCondensed={isCondensed}
                                selectedEdition={selectedEdition}
                                i18n={i18n}
                                productImgSrc={productImgSrc}
                                showDescription={!isFullscreen && !isCondensed}
                                showPricing={!isFullscreen}
                            />
                        </div>
                        {renderAddons()}
                    </div>
                    {buyActions && buyActions.length ? (
                        <div {...n('buttons', contentModifiers).props}>
                            {buyActions.map(renderActionButtons)}
                        </div>
                    ) : ''}
                </div>
            </div>
        </div>
    );
};

export const defaultSelectionPreviewProps = {
    data: PropTypes.shape({
        configurator: PropTypes.shape({
            i18n: PropTypes.shape({
                selectedEdition: PropTypes.string,
                selectedAddons: PropTypes.string,
                selectedProduct: PropTypes.string,
                startingAt: PropTypes.string,
                showLess: PropTypes.string,
                more: PropTypes.string,
                cancel: PropTypes.string
            })
        }),
        selectedEdition: PropTypes.shape({
            name: PropTypes.string,
            plans: PropTypes.arrayOf(
                PropTypes.shape({
                    costs: PropTypes.shape({
                        unitPrice: PropTypes.arrayOf(
                            PropTypes.shape({
                                usageRange: PropTypes.arrayOf(
                                    PropTypes.shape({
                                        formattedFullPriceElements: PropTypes.array
                                    })
                                )
                            })
                        )
                    })
                })
            )
        }),
        selectedAddons: PropTypes.arrayOf(
            PropTypes.shape({
                name: PropTypes.string,
                edition: PropTypes.arrayOf(
                    PropTypes.shape({
                        costs: PropTypes.shape({
                            unitPrice: PropTypes.arrayOf(
                                PropTypes.shape({
                                    usageRange: PropTypes.arrayOf(
                                        PropTypes.shape({
                                            formattedFullPriceElements: PropTypes.array
                                        })
                                    )
                                })
                            )
                        })
                    })
                )
            })
        ),
        callToActions: PropTypes.shape({
            items: PropTypes.arrayOf(
                PropTypes.shape({
                    label: PropTypes.string,
                    tooltip: PropTypes.string,
                    isPrimary: PropTypes.bool,
                    enabled: PropTypes.bool,
                    url: PropTypes.string,
                    actionType: PropTypes.string
                })
            )
        }),
        productImgSrc: PropTypes.string
    }),
    isCondensed: PropTypes.bool,
    isFullscreen: PropTypes.bool,
    onCollapseAddons: PropTypes.func
};

SelectionPreviewComponent.propTypes = defaultSelectionPreviewProps;

SelectionPreviewComponent.defaultProps = {
    data: {
        configurator: {
            i18n: {
                selectedEdition: 'Selected Edition',
                selectedAddons: 'Selected Addons',
                selectedProduct: 'Selected Product',
                startingAt: 'Starting at',
                showLess: 'Show Less',
                more: 'more',
                cancel: 'Cancel'
            }
        },
        selectedEdition: {
            name: 'Default Edition',
            plans: [
                {
                    costs: {
                        unitPrice: [
                            {
                                usageRange: [
                                    {
                                        formattedFullPriceElements: []
                                    }
                                ]
                            }
                        ]
                    }
                }
            ]
        },
        selectedAddons: [],
        callToActions: {
            items: [
                {
                    label: 'Buy',
                    tooltip: '',
                    isPrimary: true,
                    enabled: true,
                    url: '',
                    actionType: ''
                }
            ]
        },
        productImgSrc: null
    },
    onCollapseAddons: () => { },
    isCondensed: false,
    isFullscreen: false
};

export default SelectionPreviewComponent;
