import StyledWrapper from "@insite/client-framework/Common/StyledWrapper";
import isTouchDevice from "@insite/client-framework/Common/Utilities/isTouchDevice";
import { CategoryContext } from "@insite/client-framework/Components/CategoryContext";
import { HasShellContext, withIsInShell } from "@insite/client-framework/Components/IsInShell";
import { ProductContext } from "@insite/client-framework/Components/ProductContext";
import ApplicationState from "@insite/client-framework/Store/ApplicationState";
import loadCarouselProducts from "@insite/client-framework/Store/Components/ProductCarousel/Handlers/LoadCarouselProducts";
import {
    getErrorMessage,
    getProductsForProductInfoList,
} from "@insite/client-framework/Store/Components/ProductInfoList/ProductInfoListSelectors";
import sendImpressionTracking from "@insite/client-framework/Store/Components/ProductRecommendations/Handlers/SendImpressionTracking";
import { BrandStateContext } from "@insite/client-framework/Store/Data/Brands/BrandsSelectors";
import { getCurrentPage } from "@insite/client-framework/Store/Data/Pages/PageSelectors";
import translate from "@insite/client-framework/Translate";
import { ProductModel } from "@insite/client-framework/Types/ApiModels";
import WidgetModule from "@insite/client-framework/Types/WidgetModule";
import WidgetProps from "@insite/client-framework/Types/WidgetProps";
import ProductCarouselProduct, {
    ProductCarouselProductStyles,
} from "@insite/content-library/Components/ProductCarouselProduct";
import SkipNav, { SkipNavStyles } from "@insite/content-library/Components/SkipNav";
import Button, { ButtonIcon, ButtonPresentationProps } from "@insite/mobius/Button";
import { BaseTheme } from "@insite/mobius/globals/baseTheme";
import GridContainer, { GridContainerProps } from "@insite/mobius/GridContainer";
import GridItem, { GridItemProps } from "@insite/mobius/GridItem";
import ChevronLeft from "@insite/mobius/Icons/ChevronLeft";
import ChevronRight from "@insite/mobius/Icons/ChevronRight";
import Typography, { TypographyPresentationProps } from "@insite/mobius/Typography";
import { injectCss } from "@insite/mobius/utilities";
import breakpointMediaQueries from "@insite/mobius/utilities/breakpointMediaQueries";
import InjectableCss from "@insite/mobius/utilities/InjectableCss";
import * as cssLinter from "css";
import { useEmblaCarousel } from "embla-carousel/react";
import React, { createRef, useCallback, useContext, useEffect, useState } from "react";
import { connect, ResolveThunks } from "react-redux";
import styled, { css, ThemeProps, withTheme } from "styled-components";

const enum fields {
    title = "title",
    carouselType = "carouselType",
    displayProductsFrom = "displayProductsFrom",
    selectedCategoryIds = "selectedCategoryIds",
    relatedProductType = "relatedProductType",
    numberOfProductsToDisplay = "numberOfProductsToDisplay",
    seedWithManuallyAssigned = "seedWithManuallyAssigned",
    maxNumberOfColumns = "maxNumberOfColumns",
    widgetPosition = "widgetPosition",
    showImage = "showImage",
    showTitle = "showTitle",
    showBrandName = "showBrandName",
    showPartNumbers = "showPartNumbers",
    showPrice = "showPrice",
    showAddToCart = "showAddToCart",
    showAddToList = "showAddToList",
    showImageBadges = "showImageBadges",
    maximumNumberOfImageBadges = "maximumNumberOfImageBadges",
    showTextBadges = "showTextBadges",
    maximumNumberOfTextBadges = "maximumNumberOfTextBadges",
    visibleElementsTitle = "visibleElementsTitle",
    titleAlignment = "titleAlignment",
    customCSS = "customCSS",
}

interface OwnProps extends WidgetProps {
    fields: {
        [fields.title]: string;
        [fields.carouselType]: string;
        [fields.displayProductsFrom]: string;
        [fields.selectedCategoryIds]: string[];
        [fields.relatedProductType]: string;
        [fields.numberOfProductsToDisplay]: number;
        [fields.seedWithManuallyAssigned]: string;
        [fields.maxNumberOfColumns]: number;
        [fields.widgetPosition]: number;
        [fields.showImage]: boolean;
        [fields.showTitle]: boolean;
        [fields.showBrandName]: boolean;
        [fields.showPartNumbers]: boolean;
        [fields.showPrice]: boolean;
        [fields.showAddToCart]: boolean;
        [fields.showAddToList]: boolean;
        [fields.showImageBadges]: boolean;
        [fields.maximumNumberOfImageBadges]: number;
        [fields.showTextBadges]: boolean;
        [fields.maximumNumberOfTextBadges]: number;
        [fields.visibleElementsTitle]: string;
        [fields.titleAlignment]: string;
        [fields.customCSS]: string;
    };
}

const mapStateToProps = (state: ApplicationState, ownProps: OwnProps) => ({
    products: getProductsForProductInfoList(state, ownProps.id),
    errorMessage: getErrorMessage(state, ownProps.id),
    pageType: getCurrentPage(state).type,
    productRecommendationWidgets: state.components.productRecommendations.widgets,
    session: state.context.session,
});

const mapDispatchToProps = {
    loadCarouselProducts,
    sendImpressionTracking,
};

type Props = OwnProps &
    ReturnType<typeof mapStateToProps> &
    ResolveThunks<typeof mapDispatchToProps> &
    ThemeProps<BaseTheme> &
    HasShellContext;

export interface ProductCarouselStyles {
    errorMessageText?: TypographyPresentationProps;
    titleText?: TypographyPresentationProps;
    skipCarouselButton?: SkipNavStyles;
    mainContainer?: GridContainerProps;
    prevArrowGridItem?: GridItemProps;
    prevArrowButton?: ButtonPresentationProps;
    nextArrowGridItem?: GridItemProps;
    nextArrowButton?: ButtonPresentationProps;
    carouselGridItem?: GridItemProps;
    carouselWrapper?: InjectableCss;
    carouselContainer?: InjectableCss;
    carouselSlidesContainer?: InjectableCss;
    carouselSlide?: InjectableCss;
    carouselSlideInner?: InjectableCss;
    carouselProductStyles?: ProductCarouselProductStyles;
}

export const productCarouselStyles: ProductCarouselStyles = {
    errorMessageText: {
        color: "danger",
        css: css`
            margin-top: 20px;
        `,
    },
    titleText: {
        variant: "h2",
        css: css`
            text-align: center;
            margin-bottom: 10px;
        `,
    },
    mainContainer: { gap: 0 },
    prevArrowGridItem: {
        width: 1,
        align: "middle",
        css: css`
            justify-content: flex-start;
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(theme, [
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                ])}
        `,
    },
    prevArrowButton: {
        variant: "secondary",
        color: "text.main",
        css: css`
            border: 0;
            padding: 0;
        `,
    },
    nextArrowGridItem: {
        width: 1,
        align: "middle",
        css: css`
            justify-content: flex-end;
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(theme, [
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                    css`
                        flex-basis: 5%;
                        max-width: 5%;
                    `,
                ])}
        `,
    },
    nextArrowButton: {
        variant: "secondary",
        color: "text.main",
        css: css`
            border: 0;
            padding: 0;
        `,
    },
    carouselGridItem: {
        width: 10,
        css: css`
            ${({ theme }: { theme: BaseTheme }) =>
                breakpointMediaQueries(theme, [
                    css`
                        flex-basis: 90%;
                        max-width: 90%;
                    `,
                    css`
                        flex-basis: 90%;
                        max-width: 90%;
                    `,
                    css`
                        flex-basis: 90%;
                        max-width: 90%;
                    `,
                    css`
                        flex-basis: 90%;
                        max-width: 90%;
                    `,
                    css`
                        flex-basis: 90%;
                        max-width: 90%;
                    `,
                ])}
        `,
    },
    carouselWrapper: {
        css: css`
            width: 100%;
            position: relative;
        `,
    },
    carouselContainer: {
        css: css`
            overflow: hidden;
        `,
    },
    carouselSlidesContainer: {
        css: css`
            display: flex;
        `,
    },
    carouselSlide: {
        css: css`
            padding: 0;
            position: relative;
            flex: 0 0 auto;
        `,
    },
    carouselSlideInner: {
        css: css`
            width: 100%;
            height: 100%;
            position: relative;
            padding: 0 20px;
            display: flex;
            flex-direction: column;
        `,
    },
};

const defaultCustomCss = `.wrapper {
}

.titleText {
}
`;

const basicTab = {
    displayName: "Basic",
    sortOrder: 0,
};

const advancedTab = {
    displayName: "Advanced",
    sortOrder: 1,
};

const styles = productCarouselStyles;

const ProductCarousel = ({
    id,
    theme,
    fields,
    products,
    errorMessage,
    loadCarouselProducts,
    pageType,
    shellContext,
    productRecommendationWidgets,
    sendImpressionTracking,
    session,
}: Props) => {
    const afterCarousel = createRef<HTMLSpanElement>();
    const isProductDetailsPage = pageType === "ProductDetailsPage";
    const isProductListPage = pageType === "ProductListPage";
    const isBrandDetailsPage = pageType === "BrandDetailsPage";
    const brand = useContext(BrandStateContext).value;
    const category = useContext(CategoryContext);
    const productContext = useContext(ProductContext);

    useEffect(() => {
        loadCarouselProducts({
            isShellEdit: shellContext.isInShell && shellContext.isEditing,
            carouselId: id,
            carouselType: fields.carouselType,
            relatedProductType: fields.relatedProductType,
            seedWithManuallyAssigned: fields.seedWithManuallyAssigned,
            displayProductsFrom: fields.displayProductsFrom,
            selectedCategoryIds: fields.selectedCategoryIds,
            numberOfProductsToDisplay: fields.numberOfProductsToDisplay,
            widgetPosition: fields.widgetPosition,
            isProductDetailsPage,
            productId: productContext?.product?.id,
            isProductListPage,
            category,
            isBrandDetailsPage,
            brand,
        });
    }, [
        fields.carouselType,
        fields.relatedProductType,
        fields.seedWithManuallyAssigned,
        fields.displayProductsFrom,
        fields.selectedCategoryIds,
        fields.numberOfProductsToDisplay,
        fields.widgetPosition,
        productContext?.product?.id,
        category?.id,
        brand?.id,
        productRecommendationWidgets,
        session?.pickUpWarehouse?.id,
    ]);

    const [emblaRef, embla] = useEmblaCarousel();
    const [windowResizeTime, setWindowResizeTime] = useState(0);
    const [canScrollPrev, setCanScrollPrev] = useState(false);
    const [canScrollNext, setCanScrollNext] = useState(false);
    const setCanScroll = () => {
        if (shellContext.isInShell) {
            return;
        }
        setCanScrollPrev(!!embla && embla.canScrollPrev());
        setCanScrollNext(!!embla && embla.canScrollNext());
    };

    const getSlidesToScroll = useCallback(() => {
        const maxNumberOfColumns = fields.maxNumberOfColumns || 4;
        if (typeof window === "undefined") {
            return maxNumberOfColumns;
        }

        let localSlidesToScroll: number;
        const { innerWidth } = window;
        if (innerWidth < theme.breakpoints.values[1]) {
            localSlidesToScroll = 1;
        } else if (innerWidth < theme.breakpoints.values[2]) {
            localSlidesToScroll = 2;
        } else if (innerWidth < theme.breakpoints.values[3]) {
            localSlidesToScroll = 3;
        } else {
            localSlidesToScroll = 4;
        }
        return Math.min(localSlidesToScroll, maxNumberOfColumns);
    }, [fields.maxNumberOfColumns]);

    const [slidesToScroll, setSlidesToScroll] = useState(0);

    useEffect(() => {
        const newSlidesToScroll = getSlidesToScroll();
        setSlidesToScroll(newSlidesToScroll);
    }, [fields.maxNumberOfColumns, windowResizeTime]);

    useEffect(() => {
        if (!embla) {
            return;
        }

        embla.on("init", setCanScroll);
        embla.on("select", setCanScroll);

        const onWindowResize = () => {
            setWindowResizeTime(Date.now());
        };

        window.addEventListener("resize", onWindowResize);
        onWindowResize();

        return () => {
            window.removeEventListener("resize", onWindowResize);
        };
    }, [embla]);

    useEffect(() => {
        if (!embla || !products || products.length === 0) {
            return;
        }

        embla.reInit({
            align: "start",
            slidesToScroll,
            draggable: isTouchDevice(),
            loop: products.length > slidesToScroll,
        });
        setCanScroll();
    }, [embla, slidesToScroll, products]);

    useEffect(() => {
        if (
            fields.carouselType !== "recommendedProducts" ||
            !productRecommendationWidgets ||
            fields.widgetPosition > productRecommendationWidgets.length ||
            !products
        ) {
            return;
        }

        const productRecommendationWidget = productRecommendationWidgets[fields.widgetPosition - 1];
        const recommendationIds: number[] = [];
        products?.forEach(o => {
            const id = productRecommendationWidget.recs.find(r => r.refCode === o.detail?.name)?.id;
            if (id) {
                recommendationIds.push(id);
            }
        });

        if (recommendationIds.length) {
            sendImpressionTracking({ recommendationIds });
        }
    }, [fields.carouselType, productRecommendationWidgets, products]);

    const getProductRecommendationId = (product: ProductModel) => {
        if (!productRecommendationWidgets || fields.widgetPosition > productRecommendationWidgets.length) {
            return;
        }

        const productRecommendationWidget = productRecommendationWidgets[fields.widgetPosition - 1];
        return productRecommendationWidget.recs.find(r => r.refCode === product.detail?.name)?.id;
    };

    if (errorMessage && shellContext.isInShell) {
        return (
            <Typography {...styles.errorMessageText} as="p">
                {`Failed to load carousel products. Error: '${errorMessage}'. Please check widget settings.`}
            </Typography>
        );
    }

    if (!products || products.length === 0) {
        return null;
    }

    const title =
        fields.title ||
        translate(carouselTypeOptions.find(o => o.value === fields.carouselType)?.displayName || "Product Carousel");
    const showBrandBlocks = fields.showBrandName && products.some(o => !!o.brand);

    const customCssWrapper = {
        css: css`
            ${fields.customCSS}
        `,
    };

    return (
        <StyledWrapper {...customCssWrapper}>
            <>
                <SkipNav
                    text={translate("Skip Carousel")}
                    extendedStyles={styles.skipCarouselButton}
                    destination={afterCarousel}
                />
                <ContentWrapper alignment={fields.titleAlignment} className="wrapper">
                    <Typography {...styles.titleText}>{title}</Typography>
                </ContentWrapper>

                <GridContainer
                    {...styles.mainContainer}
                    data-test-selector={`productCarousel_${fields.carouselType}${fields.relatedProductType}`}
                >
                    <GridItem {...styles.prevArrowGridItem}>
                        {products.length > slidesToScroll && (
                            <Button
                                {...styles.prevArrowButton}
                                onClick={() => embla && embla.scrollPrev()}
                                disabled={!canScrollPrev}
                                data-test-selector="prevBtn"
                            >
                                <ButtonIcon src={ChevronLeft} />
                            </Button>
                        )}
                    </GridItem>
                    <GridItem {...styles.carouselGridItem}>
                        <StyledWrapper {...styles.carouselWrapper}>
                            <StyledWrapper {...styles.carouselContainer} ref={emblaRef}>
                                <StyledWrapper {...styles.carouselSlidesContainer} data-test-selector="slides">
                                    {products.map(product => (
                                        <StyledWrapper
                                            {...styles.carouselSlide}
                                            key={product.id}
                                            style={{ width: `calc(100% / ${slidesToScroll})` }}
                                        >
                                            <StyledWrapper
                                                {...styles.carouselSlideInner}
                                                id={`product_${product.id}`}
                                                data-test-key={product.id}
                                                data-test-selector="carousel_slide"
                                            >
                                                <ProductCarouselProduct
                                                    carouselId={id}
                                                    product={product}
                                                    recommendationId={getProductRecommendationId(product)}
                                                    showImage={fields.showImage}
                                                    showBrand={showBrandBlocks}
                                                    showTitle={fields.showTitle}
                                                    showPartNumbers={fields.showPartNumbers}
                                                    showPrice={fields.showPrice}
                                                    showAddToCart={fields.showAddToCart}
                                                    showAddToList={fields.showAddToList}
                                                    showImageBadges={fields.showImageBadges}
                                                    maximumNumberOfImageBadges={fields.maximumNumberOfImageBadges}
                                                    showTextBadges={fields.showTextBadges}
                                                    maximumNumberOfTextBadges={fields.maximumNumberOfTextBadges}
                                                    extendedStyles={styles.carouselProductStyles}
                                                />
                                            </StyledWrapper>
                                        </StyledWrapper>
                                    ))}
                                </StyledWrapper>
                            </StyledWrapper>
                        </StyledWrapper>
                    </GridItem>
                    <GridItem {...styles.nextArrowGridItem}>
                        {products.length > slidesToScroll && (
                            <Button
                                {...styles.nextArrowButton}
                                onClick={() => embla && embla.scrollNext()}
                                disabled={!canScrollNext}
                                data-test-selector="nextBtn"
                            >
                                <ButtonIcon src={ChevronRight} />
                            </Button>
                        )}
                    </GridItem>
                </GridContainer>
                <span ref={afterCarousel} tabIndex={-1} />
            </>
        </StyledWrapper>
    );
};

const carouselTypeOptions = [
    { value: "crossSells", displayName: "Cross Sells" },
    { value: "customersAlsoPurchased", displayName: "Customers Also Purchased" },
    { value: "recentlyViewed", displayName: "Recently Viewed" },
    { value: "relatedProducts", displayName: "Related Products" },
    { value: "topSellers", displayName: "Top Sellers" },
    { value: "recommendedProducts", displayName: "Recommended Products" },
];

export const ContentWrapper = styled.div<InjectableCss & { alignment: string }>`
    display: flex;
    width: 100%;
    justify-content: ${props => props.alignment ?? "flex-start"};
    ${injectCss};
`;

const widgetModule: WidgetModule = {
    component: connect(mapStateToProps, mapDispatchToProps)(withIsInShell(withTheme(ProductCarousel))),
    definition: {
        group: "Common",
        icon: "gallery-thumbnails",
        fieldDefinitions: [
            {
                name: fields.title,
                displayName: "Title",
                editorTemplate: "TextField",
                defaultValue: "",
                fieldType: "Contextual",
                sortOrder: 0,
                tab: basicTab,
            },
            {
                name: fields.titleAlignment,
                displayName: "Title Alignment",
                editorTemplate: "RadioButtonsField",
                defaultValue: "center",
                horizontal: true,
                fieldType: "General",
                sortOrder: 1,
                tab: basicTab,
                options: [
                    {
                        displayName: "Left",
                        value: "flex-start",
                    },
                    {
                        displayName: "Center",
                        value: "center",
                    },
                    {
                        displayName: "Right",
                        value: "flex-end",
                    },
                ],
            },
            {
                name: fields.carouselType,
                displayName: "Carousel Type",
                editorTemplate: "DropDownField",
                options: carouselTypeOptions,
                defaultValue: "crossSells",
                fieldType: "Contextual",
                sortOrder: 2,
                tab: basicTab,
                customFilter: (item, pageType, settings) => {
                    const {
                        settingsCollection: {
                            websiteSettings: { enableDynamicRecommendations },
                            productSettings: { enableProductRecommendations },
                        },
                    } = settings;

                    if (!enableDynamicRecommendations && item.value === "topSellers") {
                        return false;
                    }

                    if (!enableProductRecommendations && item.value === "recommendedProducts") {
                        return false;
                    }

                    if (
                        (pageType.type !== "ProductDetailsPage" && item.value === "relatedProducts") ||
                        (pageType.type !== "ProductDetailsPage" &&
                            pageType.type !== "CartPage" &&
                            item.value === "customersAlsoPurchased")
                    ) {
                        return false;
                    }

                    return true;
                },
            },
            {
                name: fields.displayProductsFrom,
                displayName: "Display Products From",
                editorTemplate: "DropDownField",
                options: [
                    { value: "allCategories", displayName: "All Categories" },
                    { value: "selectedCategories", displayName: "Selected Categories" },
                    { value: "customerSegments", displayName: "Customer Segments" },
                ],
                defaultValue: "allCategories",
                fieldType: "Contextual",
                isVisible: item => item.fields[fields.carouselType] === "topSellers",
                sortOrder: 3,
                tab: basicTab,
            },
            {
                name: fields.selectedCategoryIds,
                displayName: "Selected Categories",
                editorTemplate: "CategoriesField",
                defaultValue: [],
                fieldType: "Contextual",
                isVisible: item =>
                    item.fields[fields.carouselType] === "topSellers" &&
                    item.fields[fields.displayProductsFrom] === "selectedCategories",
                sortOrder: 4,
                tab: basicTab,
            },
            {
                name: fields.relatedProductType,
                displayName: "Related Product Type",
                editorTemplate: "SystemListDropDownField",
                systemListName: "ProductRelationship",
                defaultValue: "",
                fieldType: "Contextual",
                isVisible: item => item.fields[fields.carouselType] === "relatedProducts",
                sortOrder: 5,
                tab: basicTab,
            },
            {
                name: fields.numberOfProductsToDisplay,
                displayName: "Number Of Products To Display",
                editorTemplate: "IntegerField",
                min: 1,
                max: 20,
                defaultValue: 10,
                fieldType: "Contextual",
                isVisible: item =>
                    item.fields[fields.carouselType] === "customersAlsoPurchased" ||
                    item.fields[fields.carouselType] === "topSellers",
                sortOrder: 6,
                tab: basicTab,
            },
            {
                name: fields.seedWithManuallyAssigned,
                displayName: "Seed With Manually Assigned",
                editorTemplate: "SystemListDropDownField",
                systemListName: "ProductRelationship",
                defaultValue: "",
                fieldType: "Contextual",
                isVisible: (item, _advancedFeaturesEnabled, _theme, pageType) =>
                    pageType === "ProductDetailsPage" && item.fields[fields.carouselType] === "customersAlsoPurchased",
                sortOrder: 7,
                tab: basicTab,
            },
            {
                name: fields.maxNumberOfColumns,
                displayName: "Max Number Of Columns",
                editorTemplate: "IntegerField",
                min: 1,
                max: 4,
                defaultValue: 4,
                fieldType: "Contextual",
                sortOrder: 8,
                tab: basicTab,
            },
            {
                name: fields.widgetPosition,
                displayName: "Widget Position",
                editorTemplate: "IntegerField",
                min: 1,
                defaultValue: 1,
                fieldType: "Contextual",
                isVisible: item => item.fields[fields.carouselType] === "recommendedProducts",
                sortOrder: 9,
                tab: basicTab,
            },
            {
                name: fields.visibleElementsTitle,
                displayName: "Visible Elements",
                editorTemplate: "LabelField",
                defaultValue: "",
                fieldType: "General",
                sortOrder: 10,
                tab: basicTab,
            },
            {
                name: fields.showImage,
                displayName: "Image",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                isEnabled: () => false,
                fieldType: "Contextual",
                sortOrder: 11,
                tab: basicTab,
            },
            {
                name: fields.showTitle,
                displayName: "Title",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                isEnabled: () => true,
                fieldType: "Contextual",
                sortOrder: 12,
                tab: basicTab,
            },
            {
                name: fields.showBrandName,
                displayName: "Brand Name",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "Contextual",
                sortOrder: 13,
                tab: basicTab,
            },
            {
                name: fields.showPartNumbers,
                displayName: "Part Numbers",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "Contextual",
                sortOrder: 14,
                tab: basicTab,
            },
            {
                name: fields.showPrice,
                displayName: "Price",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "Contextual",
                sortOrder: 15,
                tab: basicTab,
            },
            {
                name: fields.showAddToCart,
                displayName: "Add to Cart",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "Contextual",
                sortOrder: 16,
                tab: basicTab,
            },
            {
                name: fields.showAddToList,
                displayName: "Add to List",
                editorTemplate: "CheckboxField",
                defaultValue: true,
                fieldType: "Contextual",
                sortOrder: 17,
                tab: basicTab,
            },
            {
                name: fields.showImageBadges,
                displayName: "Image Badges",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "Contextual",
                sortOrder: 18,
                tab: basicTab,
            },
            {
                name: fields.maximumNumberOfImageBadges,
                editorTemplate: "DropDownField",
                isVisible: widget => widget.fields.showImageBadges,
                defaultValue: "4",
                options: [
                    { displayName: "1", value: "1" },
                    { displayName: "2", value: "2" },
                    { displayName: "3", value: "3" },
                    { displayName: "4", value: "4" },
                    { displayName: "5", value: "5" },
                    { displayName: "6", value: "6" },
                    { displayName: "7", value: "7" },
                    { displayName: "8", value: "8" },
                ],
                fieldType: "Contextual",
                sortOrder: 18,
                tab: basicTab,
            },
            {
                name: fields.showTextBadges,
                displayName: "Text Badges",
                editorTemplate: "CheckboxField",
                defaultValue: false,
                fieldType: "Contextual",
                sortOrder: 19,
                tab: basicTab,
            },
            {
                name: fields.maximumNumberOfTextBadges,
                editorTemplate: "DropDownField",
                isVisible: widget => widget.fields.showTextBadges,
                defaultValue: "4",
                options: [
                    { displayName: "1", value: "1" },
                    { displayName: "2", value: "2" },
                    { displayName: "3", value: "3" },
                    { displayName: "4", value: "4" },
                    { displayName: "5", value: "5" },
                    { displayName: "6", value: "6" },
                    { displayName: "7", value: "7" },
                    { displayName: "8", value: "8" },
                ],
                fieldType: "Contextual",
                sortOrder: 20,
                tab: basicTab,
            },
            {
                name: fields.customCSS,
                displayName: "Custom CSS",
                editorTemplate: "CodeField",
                fieldType: "General",
                tab: advancedTab,
                defaultValue: defaultCustomCss,
                isVisible: (item, shouldDisplayAdvancedFeatures) => !!shouldDisplayAdvancedFeatures,
                validate: value => {
                    if (value === undefined || value === null) {
                        return "";
                    }

                    const result = cssLinter.parse(value, { silent: true });
                    if (result?.stylesheet?.parsingErrors) {
                        // the error output at this time only has room for one line so we just show the first error
                        return result.stylesheet.parsingErrors.length <= 0
                            ? ""
                            : result.stylesheet.parsingErrors.map(error => `${error.reason} on line ${error.line}`)[0];
                    }

                    return "Unable to parse Css";
                },
                options: {
                    mode: "css",
                    lint: true,
                    autoRefresh: true,
                },
            },
        ],
    },
};

export default widgetModule;
