import React, { useMemo, useEffect } from 'react';

import withListener from '../withListener';
import { useResponsive } from '../../tools/widths/useResponsive';
import { createNamespace } from '../../tools/namingTools';
import { parseToBool } from '../../tools/helpers';
import { unescapeHtml } from '../../tools/stringTools';
import { parsePricingActions } from '../../tools/callToActions';
import { isProductEditionAddedToCart } from '../../tools/cart';
import { BACKGROUND_IMAGE } from '../../constants/backgroundSettings';
import { CTA_NO_ACTION } from '../../constants/actions';
import { productBannerFormSchema } from '../../constants/components/schemas/product-banner';
import { productBannerPropTypes } from '../../constants/components/prop-types/product-banner';
import ProductCard from '../../atoms/product-card/ProductCard';
import ButtonsList from '../../atoms/buttons-list/ButtonsList';
import BreadCrumbs from '../../atoms/bread-crumbs/BreadCrumbs';
import GlobalAlertsComponent from '../global-alerts/GlobalAlerts';
import { alertTypes } from '../../atoms/alert/Alert';
import { marketplaceProductDataStore } from '../../store/marketplaceProductData';
import { cartPreviewStore } from '../../store/cartPreview';
// IMPORTANT: (s)css should be imported after other atoms/components
import './styles/ProductBanner.scss';

const n = createNamespace('ProductBanner');

const AVAILABLE_TYPES = [BACKGROUND_IMAGE.value];

/**
 * Get request statuses from URL parameters
 * @returns {Object} Object containing request status flags
 */
const getRequestStatusFromUrl = () => {
    const urlParams = new URLSearchParams(window.location.search);
    return {
        isAccessRequested: urlParams.get('accessRequested') === 'true',
        isPurchaseRequested: urlParams.get('purchaseRequested') === 'true',
        isAccessRequestFailed: urlParams.get('accessRequested') === 'false',
        isPurchaseRequestFailed: urlParams.get('purchaseRequested') === 'false'
    };
};

/**
 * Create global alerts based on request statuses and action messages
 * @param {Object} requestStatus - Request status flags
 * @param {Object} actionMessages - Action messages for different states
 * @returns {Array} Array of global alert objects
 */
const createGlobalAlerts = (requestStatus, actionMessages) => {
    if (!actionMessages) { return []; }

    const alerts = [];

    // Define request types configuration
    const requestTypes = [
        {
            name: 'access',
            isRequested: requestStatus.isAccessRequested,
            isFailed: requestStatus.isAccessRequestFailed,
            successMessage: actionMessages.requestAccessSuccess,
            failureMessage: actionMessages.requestPurchaseFail,
            alertType: 'accessRequestAlert'
        },
        {
            name: 'purchase',
            isRequested: requestStatus.isPurchaseRequested,
            isFailed: requestStatus.isPurchaseRequestFailed,
            successMessage: actionMessages.requestPurchaseSuccess,
            failureMessage: actionMessages.requestPurchaseFail,
            alertType: 'purchaseRequestAlert'
        }
    ];

    // Process each request type
    requestTypes.forEach(request => {
        if (request.isRequested && request.successMessage) {
            alerts.push({
                message: request.successMessage,
                type: request.alertType,
                alertType: alertTypes.SUCCESS_ALERT
            });
        } else if (request.isFailed && request.failureMessage) {
            alerts.push({
                message: request.failureMessage,
                type: request.alertType,
                alertType: alertTypes.ERROR_ALERT
            });
        }
    });

    return alerts;
};

export const ProductBannerComponent = ({
    settings,
    data: {
        applicationType,
        callToActions = { items: [] },
        categories,
        config,
        i18n: i18nProp,
        listingPageUrl,
        relatedContent,
        summary,
        defaultSelectedEdition,
        locale,
        editions,
        addonProducts,
        actionMessages
    }
}) => {
    const { marketplaceProductData } = marketplaceProductDataStore();

    const { cart, fetchCart } = cartPreviewStore();

    // fetch once, cart is updated by zustand store
    useEffect(() => {
        fetchCart(locale);
    }, [fetchCart, locale]);

    const isAddedToCart = isProductEditionAddedToCart(
        editions?.items,
        cart,
        config?.uuid,
        applicationType,
        addonProducts
    );

    const hasRequiredProduct = Boolean(
        Array.isArray(marketplaceProductData?.product?.editions)
        && marketplaceProductData.product.editions.some(element => (element.upstreamAssociations?.length))
    );

    // Get request statuses and create global alerts
    const requestStatus = getRequestStatusFromUrl();
    const globalAlerts = createGlobalAlerts(requestStatus, actionMessages);

    // build the crumb's back button link. If we come from a listing page, clicking back will go history -1.
    // Otherwise (for example if we come from an external site) the crumb's root will be a link to the listings page
    const breadcrumbRoot = useMemo(() => {
        const i18n = { ...ProductBannerComponent.defaultProps.data.i18n, ...i18nProp };
        if (!listingPageUrl) {
            return {};
        }

        const { referrer } = document;
        const i18nWithDefaults = { ...ProductBannerComponent.defaultProps.data.i18n, ...i18n };

        // we come from a listings page
        if (referrer.indexOf(listingPageUrl) !== -1) {
            return {
                baseLinkText: i18nWithDefaults.backToResults,
                baseLinkAction: () => window.history.go(-1)
            };
        }

        return {
            baseLinkText: i18nWithDefaults.allProducts,
            baseLinkUrl: listingPageUrl
        };
    }, [listingPageUrl, i18nProp]);

    const { largeDown: isMobile } = useResponsive();

    if (!summary) {
        return null;
    }

    const cardSummary = {
        ...summary,
        hasRequiredProduct
    };

    const settingsWithDefaults = { ...ProductBannerComponent.defaultProps.settings, ...settings };
    const {
        backgroundType,
        bannerBackgroundColor,
        backgroundImg,
        settingsHeight,
        productNameSize,
        descTextSize,
        textColor
    } = settingsWithDefaults;
    const [showRatings] = parseToBool(settings.showRatings);
    const pricingActions = parsePricingActions(callToActions);

    const textSettings = {
        showRatings,
        settingsHeight,
        productNameSize,
        descTextSize,
        textColor
    };

    const hasButtons = Boolean(
        pricingActions?.items?.[0]?.actionType !== CTA_NO_ACTION
    );

    const containerModifiers = [
        textColor && textColor.toLowerCase()
    ];

    const wrapperModifiers = [
        settingsHeight && settingsHeight.toLowerCase()
    ];

    const buildBackgroundStyle = () => {
        const imageOrColor = AVAILABLE_TYPES.includes(backgroundType)
            ? { backgroundImage: `url(${unescapeHtml(backgroundImg.url)})` }
            : { backgroundColor: bannerBackgroundColor };

        return {

            ...imageOrColor
        };
    };

    const breadcrumb = [];

    if (categories && categories.items && categories.items.length) {
        breadcrumb.push({
            ...categories,
            label: categories.label || ProductBannerComponent.defaultProps.data.categories.label
        });
    }

    const breadCrumbsProps = {
        ...breadcrumbRoot,
        crumbs: breadcrumb
    };

    const i18nSummaryWithDefaults = { ...ProductBannerComponent.defaultProps.data.summary.i18n, ...summary.i18n };

    return (
        <div {...n('container', containerModifiers).withTestId().withE2EId().props}>
            {globalAlerts.length > 0 && (
                <GlobalAlertsComponent
                    data={{
                        rawAlerts: globalAlerts,
                        i18n: i18nProp
                    }}
                />
            )}
            <div
                {...n('backgroundWrapper').withTestId().props}
                style={buildBackgroundStyle()}
            />
            <div {...n('breadCrumbs').props}>
                <BreadCrumbs {...breadCrumbsProps} />
            </div>
            <section {...n('wrapper', wrapperModifiers).withTestId().props}>
                <h1 {...n('title', 'hidden').props}>{i18nSummaryWithDefaults.title}</h1>
                <div {...n('row').props}>
                    <div {...n('card').props}>
                        <ProductCard
                            cardData={cardSummary}
                            reviewData={relatedContent}
                            settings={textSettings}
                            referUrl={config && config.referUrl}
                            i18nRating={i18nProp?.rating}
                        />
                    </div>
                    {hasButtons && !isMobile && (
                        <div {...n('buttons').props}>
                            <ButtonsList data={{
                                applicationType,
                                callToActions: pricingActions,
                                primaryButtonType: 'emphasis',
                                referUrl: config && config.referUrl,
                                defaultSelectedEdition,
                                isAddedToCart,
                                i18n: i18nProp,
                                actionMessages,
                                requestStatus
                            }}
                            />
                        </div>
                    )}
                </div>
            </section>
        </div>
    );
};

ProductBannerComponent.schema = () => ({
    name: 'ProductBanner',
    title: 'uieditor.sfbComponent.productBanner.title',
    iconName: 'banner',
    form: productBannerFormSchema,
    marketplaceData: {
        applicationType: 'application.config.type',
        callToActions: 'application.callToActions',
        actionMessages: 'application.actionMessages',
        categories: 'application.categories',
        config: 'application.config',
        configurator: 'application.configurator',
        i18n: 'i18n',
        listingPageUrl: 'config.listingEndpoint',
        relatedContent: 'application.relatedContent',
        summary: 'application.summary',
        defaultSelectedEdition: 'application.defaultSelectedEdition',
        locale: 'config.locale.code',
        editions: 'application.editions',
        addonProducts: 'application.addonProducts'
    }
});

ProductBannerComponent.propTypes = productBannerPropTypes;

const SETTINGS = ProductBannerComponent.schema().form;

ProductBannerComponent.defaultProps = {
    settings: {
        backgroundType: SETTINGS.backgroundType.defaultValue,
        bannerBackgroundColor: SETTINGS.bannerBackgroundColor.defaultValue,
        textColor: SETTINGS.textColor.defaultValue,
        backgroundImg: SETTINGS.backgroundImg.defaultValue,
        showRatings: SETTINGS.showRatings.defaultValue,
        settingsHeight: SETTINGS.settingsHeight.defaultValue,
        productNameSize: SETTINGS.productNameSize.defaultValue,
        descTextSize: SETTINGS.descTextSize.defaultValue
    },
    data: {
        summary: {
            i18n: {
                title: 'Summary'
            }
        },
        actionMessages: {
            requestAccessFail: 'Your request was not sent, please try again.',
            requestAccessSuccess: 'You have successfully requested access.',
            requestPurchaseFail: 'Your request was not sent, please try again.',
            requestPurchaseSuccess: 'Your purchase request was sent.'
        },
        categories: {
            label: 'Categories',
            items: null
        },
        config: {},
        configurator: {
            url: ''
        },
        callToActions: null,
        relatedContent: {
            details: {
                reviews: {
                    rating: 0,
                    numRatings: 0,
                    caption: '',
                    title: ''
                },
                vendor: {
                    title: '',
                    items: [
                        {
                            label: ''
                        }
                    ]
                }
            }
        },
        applicationType: '',
        i18n: {
            backToResults: 'Back to Results',
            allProducts: 'All Products',
            cart: {
                addedToCart: 'Added to Cart'
            }
        },
        defaultSelectedEdition: null
    }
};

export default withListener(ProductBannerComponent);
