import React, { useState } from 'react';
import PropTypes from 'prop-types';
import HtmlReactParser from 'html-react-parser';
import Button, { allowedThemes as buttonThemes } from '../button/Button';
import EditionButtonIcon from '../edition-button-icon/EditionButtonIcon';
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, CTA_FREE_TRIAL } from '../../constants/actions';
import { DOMAIN_APP } from '../../constants/application';
import { editionPropTypes } from '../../constants/prop-types/application/editions';
import { callToActionsShape } from '../../constants/atoms/prop-types/buttons-list';
// IMPORTANT: (s)css should be imported after other atoms/components
import './styles/buttons-list.scss';
import { isInPreviewMode } from '../../tools/helpers';

const n = createNamespace('ButtonsList');

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

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

/**
 * Determines if a caption override is needed based on URL parameters or request status
 * @param {Object} actionMessages - Available message texts for different states
 * @param {Object} requestStatus - Object containing request status flags
 * @returns {string|null} - The caption override text if applicable, null otherwise
 */
const getCaptionOverride = (actionMessages, requestStatus) => {
    if (!actionMessages) { return null; }

    // Define mappings between request status and message keys
    const messageMapping = [
        { status: 'isAccessRequested', key: 'requestAccessSuccess' },
        { status: 'isPurchaseRequested', key: 'requestPurchaseSuccess' }
    ];

    // Find the first matching message
    const match = messageMapping.find(
        ({ status }) => requestStatus && requestStatus[status]
    );

    return match ? actionMessages[match.key] : null;
};

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

    // Check if access or purchase was requested (used for disabling buttons)
    const isAccessOrPurchaseRequested = requestStatus
        ? (requestStatus.isAccessRequested || requestStatus.isPurchaseRequested)
        : false;

    // Get caption override text if applicable based on request status
    const captionOverride = getCaptionOverride(actionMessages, requestStatus);

    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 || isAccessOrPurchaseRequested) && {
                disabled: true
            },
            ...actionType === CTA_UPGRADE && {
                onClick: () => {
                    setUpgradeDetails(popup);
                }
            },
            ...actionType === CTA_FREE_TRIAL && {
                onClick: () => {
                    setDisabledFreeTrial(true);
                },
                disabled: isDisabledFreeTrial
            },
            ...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_BUY && isInPreviewMode() && {
                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>
            {(captionOverride || caption) && (
                <div {...n('caption').props}>
                    {parseStringHtml(captionOverride || caption.text)}
                </div>
            )}
            {renderModal()}
        </div>
    );
};

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,
        actionMessages: PropTypes.shape({
            requestAccessSuccess: PropTypes.string,
            requestPurchaseSuccess: PropTypes.string
        }),
        requestStatus: PropTypes.shape({
            isAccessRequested: PropTypes.bool,
            isPurchaseRequested: PropTypes.bool,
            isAccessRequestFailed: PropTypes.bool,
            isPurchaseRequestFailed: PropTypes.bool
        })
    })
};

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'
            }
        },
        actionMessages: null,
        requestStatus: null
    }
};

export default ButtonsList;
