import React, { useState } from 'react';
import PropTypes from 'prop-types';
import ReactHtmlParser from 'react-html-parser';
import Button, { allowedThemes as buttonThemes } from '../button/Button';
import EditionButtonIcon from '../edition-button-icon/EditionButtonIcon';
import './styles/buttons-list.scss';
import { createNamespace } from '../../tools/namingTools';
import { isAppStackable } from '../../tools/application';
import { handleAddToCartAction, handleBuyAction } from '../../tools/callToActions';
import UpgradeModal from '../../components/upgrade-modal/UpgradeModal';
import { CTA_ADD_TO_CART, CTA_BUY, CTA_BUY_MORE, CTA_NO_ACTION, CTA_UPGRADE } from '../../constants/actions';
import { DOMAIN_APP } from '../../constants/application';
import { editionPropTypes } from '../../constants/prop-types/application/editions';

const n = createNamespace('ButtonsList');

// Page Objects returns string with HTML
const parseStringHtml = htmlString => (
    ReactHtmlParser(htmlString)
);

const isDomainAppBuyableCTA = (applicationType, actionType) => (
    applicationType === DOMAIN_APP
      && (actionType === CTA_ADD_TO_CART || actionType === CTA_BUY || actionType === CTA_BUY_MORE)
);

const ButtonsList = ({
    data: {
        applicationType,
        callToActions: { items, caption },
        primaryButtonType,
        referUrl,
        defaultSelectedEdition,
        isAddedToCart,
        i18n,
        productId
    }
}) => {
    const [upgradeDetails, setUpgradeDetails] = useState(null);
    const isNonStackable = !isAppStackable(applicationType);

    if (!items || !items.length) {
        return null;
    }

    const renderModal = () => {
        const handleClose = () => {
            setUpgradeDetails(null);
        };

        return (
            upgradeDetails && <UpgradeModal upgrades={upgradeDetails} handleClose={handleClose} />
        );
    };

    const renderButton = item => {
        const { label, a11yLabel, enabled, isPrimary, url, actionType, popup, onClick } = item;

        if (actionType === CTA_NO_ACTION || isDomainAppBuyableCTA(applicationType, actionType)) {
            return null;
        }

        const buttonProps = { ctaType: actionType,
            className: actionType && `btn-product-${actionType.toLowerCase()}`,
            key: label,
            referUrl,
            url,
            onClick,
            'aria-label': a11yLabel,
            ...isPrimary && {
                type: primaryButtonType || 'primary'
            },
            ...!enabled && {
                disabled: true
            },
            ...actionType === CTA_UPGRADE && {
                onClick: () => {
                    setUpgradeDetails(popup);
                }
            },
            ...actionType === CTA_BUY && isNonStackable && isAddedToCart && {
                url: null, // use onClick handler instead of CTA url directly
                onClick: () => {
                    handleBuyAction(
                        {
                            ...item,
                            urlCreator: {
                                actionType,
                                base: url,
                                addonParam: 'appid',
                                editionParam: 'eppid'
                            }
                        },
                        defaultSelectedEdition,
                        null,
                        productId
                    );
                }
            },
            ...actionType === CTA_ADD_TO_CART && {
                type: 'emphasisAlt',
                url: null, // use AD_addToCart instead of CTA url
                onClick: () => {
                    handleAddToCartAction(defaultSelectedEdition);
                }
            } };

        if (actionType === CTA_ADD_TO_CART && isAddedToCart) {
            return (
                <EditionButtonIcon
                    {...buttonProps}
                    theme="emphasisAlt-outline"
                    type="button"
                    icon="check"
                    notClickable
                    iconClass="addedToCart"
                >
                    {i18n.cart.addedToCart}
                </EditionButtonIcon>
            );
        }
        return (
            <Button {...buttonProps}>
                {label}
            </Button>
        );
    };

    return (
        <div {...n('container').props}>
            <div {...n('buttonGroup').withTestId('actions-container').withE2EId('actions-container').props}>
                {items.map(renderButton)}
            </div>
            {caption && (
                <div {...n('caption').props}>
                    {parseStringHtml(caption.text)}
                </div>
            )}
            {renderModal()}
        </div>
    );
};

export const callToActionsShape = {
    items: PropTypes.arrayOf(PropTypes.shape({
        label: PropTypes.string,
        tooltip: PropTypes.string,
        isPrimary: PropTypes.bool,
        enabled: PropTypes.bool,
        url: PropTypes.string,
        onClick: PropTypes.func,
        actionType: PropTypes.string
    })),
    caption: PropTypes.shape({
        text: PropTypes.string
    })
};

ButtonsList.propTypes = {
    data: PropTypes.shape({
        applicationType: PropTypes.string,
        callToActions: PropTypes.shape(callToActionsShape),
        primaryButtonType: PropTypes.oneOf(buttonThemes),
        referUrl: PropTypes.string,
        defaultSelectedEdition: PropTypes.shape(editionPropTypes),
        isAddedToCart: PropTypes.bool,
        i18n: PropTypes.object,
        productId: PropTypes.string
    })
};

ButtonsList.defaultProps = {
    data: {
        applicationType: '',
        callToActions: {
            items: [{
                label: 'Default',
                tooltip: '',
                isPrimary: true,
                enabled: true,
                url: '',
                onClick: null,
                actionType: ''
            }],
            caption: {
                text: ''
            }
        },
        primaryButtonType: null,
        referUrl: null,
        defaultSelectedEdition: null,
        isAddedToCart: false,
        i18n: {
            cart: {
                addedToCart: 'Added to Cart'
            }
        }
    }
};

export default ButtonsList;
