import {ComponentMeta} from "../ComponentsMeta";
import {iconWithClassName} from "../IconWithClassName";
import {CardRenderer} from "../CardRenderers";
import {__, CouponsPlus} from "../../globals";
import {usingOfferOptions, withPrefix} from "./CardHelpers";
import {FieldType} from "../fields";
import {TabsProps} from "../fields/tabs";
import {CustomProductOptionValue, CustomProductsFieldLabel} from "./Products";
import {merge} from "lodash";
import {SelectOption} from "../fields/MultiSelectSearch";
import {fieldsCacheContainer} from "../FieldsCache";
import {AdvancedGetYItemsMapField} from "./AdvancedGetYItemsMapField";
import {ProductDiscountOptions} from "./BuyXGetX";
import {DiscountQuantity, DiscountValue} from "./DiscountValue";
import {CardItemSecondaryValue} from "../CardItemSecondaryValue";
import {Testables} from "../testables";
import {useNodesStore} from "../store";
import {colors} from "../Colors";
import {Card} from "../Card";
import {CardItem} from "../CardItem";
import {BuyXGetYProductsFields} from "./BuyXGetYProductsFields";
import {ComponentCategory} from "../components";
import {WhenNotInCartCustomFields} from "./WhenNotInCartCustomFields";
import {NonImplementedMessage} from "../actions/NonImplementedMessage";
import {TestableComposite} from "../TestableComposite";
import React, {useMemo} from "react";
import {hover} from "../Color";
import {BaseOfferOptions} from "./OfferTypes";
import {RepeatingLabel} from "./Recusrive";
import {resolveData} from "../export/custom/BuyXGetYExporterImporter";
import {useOffer} from "../OfferHooks";
import classNames from "classnames";
import {RemoveButton} from "../RemoveButton";
import {ListItem} from "./ListItem";
import {useOpenBuyXGetYProductPopupFlow} from "./BuyXGetYProductPopupFlow";
import {useOpenEditOfferPopup} from "../hooks";
import {FloatingMarker} from "../FloatingMarker";
import {EditHintTextStrip} from "../EditHintTextStrip";
import {QuantityMeta} from "./Quantity";
import {getAdvancedYCardColor, getYUnsupportedComponents} from "./GetYAdvancedComponents";

export type ProductData = (ProductDiscountOptions & {
    id: string,
    isVariable: boolean,
})[];
export type AdvancedData = {
    source: string[], // ids of contexts at runtime, should be fully nested data while saving and while importing...
    discountOptions: ProductDiscountOptions
};

export type NotInCartNotification = {
    message: string,
    button: {
        text: string,
        url: {
            type: string, // smart, page, etc.
            value: string,
        }
    }
};
export type BuyXGetYOptions<Data extends ProductData | AdvancedData = ProductData> = BaseOfferOptions & {
    mode: 'products' | 'advanced',
    data: ProductData | AdvancedData,
    // for local use only, not saved in the database, used to keep track of the values in the UI when switching between modes and prevent data corruption and then bugs.
    __local?: {
        data_products?: ProductData,
        data_advanced?: AdvancedData,
    }
    whenNotInCart: {
        notification: NotInCartNotification
    }
}

const getLocalDataFromCurrentOptions = (options: BuyXGetYOptions): NonNullable<BuyXGetYOptions['__local']> => ({
    data_products: Array.isArray(options.data)
        ? options.data as ProductData
        : (options.__local?.data_products || resolveData('products', options) as ProductData),
    data_advanced: !Array.isArray(options.data)
        ? options.data as AdvancedData
        : (options.__local?.data_advanced || resolveData('advanced', options) as AdvancedData),
})

const getSyncedLocalData = (
    options: BuyXGetYOptions,
    mode: BuyXGetYOptions['mode'],
    data: ProductData | AdvancedData,
): NonNullable<BuyXGetYOptions['__local']> => ({
    data_products: mode === 'products'
        ? data as ProductData
        : (options.__local?.data_products || resolveData('products', options) as ProductData),
    data_advanced: mode === 'advanced'
        ? data as AdvancedData
        : (options.__local?.data_advanced || resolveData('advanced', options) as AdvancedData),
})

export const type = 'BuyXGetY'
export const BuyXGetYMeta: ComponentMeta = {
    id: type,
    type: 'offers',
    fieldsTitlePrefix: false,
    category: ComponentCategory.BOGO,
    listTitle: withPrefix(__('BOGO:')),
    titlePrefix: <span className={'text-gray-450'}>{__('BOGO:')}</span>,
    icon: iconWithClassName(({className, context}) => {
        if (context === 'card') {
            // solid
            return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="size-6">
                <path
                    d="M9.375 3a1.875 1.875 0 0 0 0 3.75h1.875v4.5H3.375A1.875 1.875 0 0 1 1.5 9.375v-.75c0-1.036.84-1.875 1.875-1.875h3.193A3.375 3.375 0 0 1 12 2.753a3.375 3.375 0 0 1 5.432 3.997h3.943c1.035 0 1.875.84 1.875 1.875v.75c0 1.036-.84 1.875-1.875 1.875H12.75v-4.5h1.875a1.875 1.875 0 1 0-1.875-1.875V6.75h-1.5V4.875C11.25 3.839 10.41 3 9.375 3ZM11.25 12.75H3v6.75a2.25 2.25 0 0 0 2.25 2.25h6v-9ZM12.75 12.75v9h6.75a2.25 2.25 0 0 0 2.25-2.25v-6.75h-9Z"/>
            </svg>
        }
        // outline
        return <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5}
                    stroke="currentColor" className="size-6">
            <path strokeLinecap="round" strokeLinejoin="round"
                  d="M21 11.25v8.25a1.5 1.5 0 0 1-1.5 1.5H5.25a1.5 1.5 0 0 1-1.5-1.5v-8.25M12 4.875A2.625 2.625 0 1 0 9.375 7.5H12m0-2.625V7.5m0-2.625A2.625 2.625 0 1 1 14.625 7.5H12m0 0V21m-8.625-9.75h18c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125h-18c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125Z"/>
        </svg>

    }),
    fieldHooks: {
        data: {
            add: (id: string, value: SelectOption<CustomProductOptionValue>): ProductData[number] => {
                return {
                    id,
                    isVariable: value.value.option.isVariable,
                    quantity: 1,
                    discount: {
                        type: 'free',
                        amount: 0
                    }
                }
            }
        }
    },
    canShowBottomNavigation: ({options}) => {
        const {mode, data} = options as BuyXGetYOptions
        // can only show when we have actually selected products.
        return mode === 'products'? (data as ProductData)?.length : (data as AdvancedData)?.source?.length
    },
    fieldsMap: ({options}) => {
        let hasSelectedProducts = true && options.mode === 'products' ? (options.data as ProductData)?.length : (options.data as AdvancedData)?.source?.length;
        return [
            [
                {
                    id: 'mode',
                    renderType: FieldType.Tab,
                    fieldProps: {dimUnselected: true} as Partial<TabsProps>,
                    fieldOptions: (options, onUpdate, {componentRuntimeData, field}) => ({
                        onUpdate: (value: BuyXGetYOptions['mode']) => {
                            const newData = resolveData(options.mode, options)

                            onUpdate(
                                componentRuntimeData,
                                {
                                    ...field,
                                    id: 'data',
                                },
                                newData,
                                {
                                    action: 'update',
                                    merge: {
                                        __local: {
                                            ...options.__local,
                                            [(options as BuyXGetYOptions).mode === 'products' ? 'data_products' : 'data_advanced']: newData
                                        }
                                    }
                                },
                            )
                        }
                    })
                },
            ],
            options.mode === 'products' && [
                {
                    id: 'data',
                    renderType: FieldType.Custom,
                    fieldProps: (options: BuyXGetYOptions, onUpdate, {componentRuntimeData, field}) => {
                        return {
                            component: <BuyXGetYProductsFields offerId={componentRuntimeData.id} options={options} onUpdate={(data) => {
                                const localData = getSyncedLocalData(options, 'products', data)
                                onUpdate(
                                    componentRuntimeData,
                                    field,
                                    data,
                                    // @ts-ignore
                                    {
                                        action: 'update',
                                        merge: {
                                            __local: localData
                                        }
                                    } // cannot import the enum because of a circular dependency
                                )
                            }}/>
                        }
                    }
                }
            ],
            options.mode === 'advanced' && (CouponsPlus.implementations.offers.GetY.advanced? [
                {
                    id: 'data',
                    renderType: FieldType.Custom,
                    fieldProps: (options, onUpdate, {componentRuntimeData, field}) => ({
                            component: <AdvancedGetYItemsMapField id={componentRuntimeData.id}
                                                                   source={options.data?.source || []}
                                                                   onGroupAdd={id => {
                                                                        const currentAdvancedData = resolveData('advanced', options) as AdvancedData
                                                                        const nextAdvancedData: AdvancedData = {
                                                                            ...currentAdvancedData,
                                                                            source: [...(currentAdvancedData.source || []), id]
                                                                       }
                                                                       onUpdate(
                                                                           componentRuntimeData,
                                                                           field, // this field is already for options.data
                                                                           id,
                                                                           {
                                                                               action: 'add',
                                                                               merge: {
                                                                                   __local: getSyncedLocalData(options, 'advanced', nextAdvancedData)
                                                                               }
                                                                           },
                                                                           'source' // so we only need .source here
                                                                       )
                                                                   }}
                                                                   discountOptions={merge(
                                                                       {
                                                                           qtyType: 'simple',
                                                                           qty: {
                                                                               type: 'any',
                                                                               amount: 1
                                                                           },
                                                                           quantity: 1,
                                                                           discount: {
                                                                               amount: 0,
                                                                               type: 'free'
                                                                           },
                                                                           missingItemsInCart: {
                                                                               mode: 'manual-add'
                                                                           }
                                                                       },
                                                                       options.data?.discountOptions ?? {},
                                                                   )}
                                                                   onQtyTypeChange={qtyType => {
                                                                       const currentAdvancedData = resolveData('advanced', options) as AdvancedData
                                                                       const nextAdvancedData: AdvancedData = {
                                                                           ...currentAdvancedData,
                                                                           discountOptions: {
                                                                               ...currentAdvancedData.discountOptions,
                                                                               qtyType
                                                                           }
                                                                       }
                                                                       onUpdate(
                                                                           componentRuntimeData,
                                                                           field, // this represents the whole options.data prop
                                                                           qtyType,
                                                                           {
                                                                               action: 'update',
                                                                               merge: {
                                                                                   __local: getSyncedLocalData(options, 'advanced', nextAdvancedData)
                                                                               }
                                                                           },
                                                                           `discountOptions.qtyType`
                                                                       )
                                                                   }}
                                                                   onQuantityChange={newValue => {
                                                                        if (typeof newValue === 'number') {
                                                                            const currentAdvancedData = resolveData('advanced', options) as AdvancedData
                                                                            const nextAdvancedData: AdvancedData = {
                                                                                ...currentAdvancedData,
                                                                               discountOptions: {
                                                                                   ...currentAdvancedData.discountOptions,
                                                                                   quantity: newValue
                                                                               }
                                                                           }
                                                                           onUpdate(
                                                                               componentRuntimeData,
                                                                               field, // this represents the whole options.data prop
                                                                               newValue,
                                                                               {
                                                                                   action: 'update',
                                                                                   merge: {
                                                                                       __local: getSyncedLocalData(options, 'advanced', nextAdvancedData)
                                                                                   }
                                                                               },
                                                                               `discountOptions.quantity`
                                                                           )
                                                                       }
                                                                   }}
                                                                   onDiscountTypeChange={type => {
                                                                       const currentAdvancedData = resolveData('advanced', options) as AdvancedData
                                                                       const nextAdvancedData: AdvancedData = {
                                                                           ...currentAdvancedData,
                                                                           discountOptions: {
                                                                               ...currentAdvancedData.discountOptions,
                                                                               discount: {
                                                                                   ...currentAdvancedData.discountOptions.discount,
                                                                                   type
                                                                               }
                                                                           }
                                                                       }
                                                                       onUpdate(
                                                                           componentRuntimeData,
                                                                           field, // this represents the whole options.data prop
                                                                           type,
                                                                           {
                                                                               action: 'update',
                                                                               merge: {
                                                                                   __local: getSyncedLocalData(options, 'advanced', nextAdvancedData)
                                                                               }
                                                                           },
                                                                           `discountOptions.discount.type`
                                                                       )
                                                                   }}
                                                                   onDiscountAmountChange={value => {
                                                                       const currentAdvancedData = resolveData('advanced', options) as AdvancedData
                                                                       const nextAdvancedData: AdvancedData = {
                                                                           ...currentAdvancedData,
                                                                           discountOptions: {
                                                                               ...currentAdvancedData.discountOptions,
                                                                               discount: {
                                                                                   ...currentAdvancedData.discountOptions.discount,
                                                                                   amount: value
                                                                               }
                                                                           }
                                                                       }
                                                                       onUpdate(
                                                                           componentRuntimeData,
                                                                           field, // this represents the whole options.data prop
                                                                           value,
                                                                           {
                                                                               action: 'update',
                                                                               merge: {
                                                                                   __local: getSyncedLocalData(options, 'advanced', nextAdvancedData)
                                                                               }
                                                                           },
                                                                           `discountOptions.discount.amount`
                                                                       )
                                                                   }}
                             />
                         }
                     )
                }
            ] : [
                {
                    id: 'data',
                    renderType: FieldType.Custom,
                    fieldProps: () => ({
                        component: <NonImplementedMessage />
                    })
                }
            ]),
            hasSelectedProducts && [
                {
                    id: 'whenNotInCart.notification',
                    title: __("Notification when items can't be added to the cart automatically"),
                    //description: __(''),
                    renderType: FieldType.Custom,
                    fieldProps: (options: BuyXGetYOptions, onUpdate, {componentRuntimeData, field}) => {
                        return {
                            component: <WhenNotInCartCustomFields
                                            notification={(componentRuntimeData.options as BuyXGetYOptions).whenNotInCart.notification}
                                            onUpdate={(notification) => {
                                                onUpdate(
                                                    componentRuntimeData,
                                                    field,
                                                    notification,
                                                    // @ts-ignore
                                                    {action: 'update'} // cannot import the enum because of a circular dependency
                                                )
                                            }}
                            />
                        }
                    }
                }
            ],
        ]
    },
}

export const BuyXGetYRenderer: CardRenderer = {
    type: type,
    prefix: "*",
    example: __('Buy 1 hoodie, get 1 t-shirt free, Buy 1 hoodie, get 1 t-shirt or sweatshirt at 50% off'),
    icon: BuyXGetYMeta.icon!,
    AboveComputedValue: () => false,
    suggestedScopeMarker: (suggestedScope) => {
        // only shows in default cards, custom cards must handle the suggested scope marker themselves.
        if (suggestedScope === 'bogo') {
            return {
                prefix: __('BOGO'),
                label: __('Get')
            }
        }
    },
    CustomCardComponent: ({id}) => {
        const offer = useOffer<BuyXGetYOptions>(id)
        const removeOffer = useNodesStore(store => store.removeOffer)

        const openEditOffer = useOpenEditOfferPopup(id)
        if (!offer) {
            return false
        }
        if (offer.options.mode !== 'products') {
            return false

        }
        return ({parameters: {color}, extraData: {afterContentInside, showRightContextButton, rightContextButton, branchId, suggestedScope}}) => {
            const data = offer.options.data as ProductData
            let isInsideAnotherBranch = false//branch.isInsideAnotherBranch()
            const isRecursive = offer.options.__BASE__.isRecursive
            const updateOffer = useNodesStore(store => store.updateOffer)

            const updateProductsData = (nextData: ProductData) => {
                const latestOffer = useNodesStore.getState().getOffer(offer.id) || offer
                const latestOptions = latestOffer.options as BuyXGetYOptions

                updateOffer({
                    ...latestOffer,
                    options: {
                        ...latestOptions,
                        data: nextData,
                        __local: {
                            ...latestOptions.__local,
                            data_products: nextData,
                        }
                    }
                })
            }

            const removeProductByIndex = (indexToRemove: number) => {
                const latestOffer = useNodesStore.getState().getOffer(offer.id) || offer
                const latestData = (latestOffer.options.data as ProductData) || []

                updateProductsData(
                    latestData.filter((_, index) => index !== indexToRemove)
                )
            }

            const openProductPopup = useOpenBuyXGetYProductPopupFlow({
                offerId: offer.id,
                openOfferEditorFirst: true,
            })

            let productsList = ((data as ProductData) ?? [])?.map((productData, index, itemsArray) => {
                const {id, quantity, discount, missingItemsInCart, qty} = productData
                const productDiscountOptions = {
                    quantity,
                    discount
                }
                const productOption = fieldsCacheContainer.get('products').get<SelectOption<CustomProductOptionValue>>(id)?.value?.option
                const productName = productOption?.type === 'variation'
                    ? (productOption?.parent_name || productOption?.name)
                    : (productOption?.name || id)
                const isFirst = index  === 0;

                if (!isFirst) {
                    afterContentInside = null
                    showRightContextButton = false
                }
                const cardItem = <CardItem
                    color={colors.blue}
                    colors={useMemo(() => ({
                        background: {
                            color,
                            tint: (color) => `${color.background(110)} ${color.background(hover(100))}`
                        },
                        icon: {
                            background: {
                                color,
                                tint: (color) => color.background(10)
                            },
                            color: {
                                color,
                                tint: (color) => color.text(90)
                            }
                        }
                    }), [color])}
                    customPadding={'pt-1 pb-[6px] px-[6px]'}
                    position={'first last'}
                    onClick={() => {
                        openProductPopup({
                            index,
                            data: productData
                        })
                    }}
                    cardRenderer={{
                        icon: false,//BuyXGetYMeta.icon!,
                        ComputedValue: () => <div className={`w-full --w-[max-content] flex items-center justify-center space-x-2 px-5 --pl-3 ${color.text(10)}`}>
                            <div className={'flex space-x-1 text-3x  text-white'}>
                                <div className={'text-opacity-60 text-white'}>{__('Get')}</div>
                                <DiscountQuantity productDiscountOptions={productData} />
                            </div>
                            <div className="min-w-[6px] min-h-[6px] max-w-[6px] max-h-[6px] bg-white rounded-full opacity-60">
                            </div>
                            <div className={'flex items-center space-x-1'}>
                                <DiscountValue productDiscountOptions={productData}/>
                            </div>
                            {false && <span
                                className="flex leading-5 px-1 rounded-6 bg-gray-250 bg-opacity-40 text-gray-350">
                                        {productData.missingItemsInCart.mode === 'auto-add' ? __('Auto') : __('Manual')}
                                    </span>
                            }                                </div>,
                        BelowComputedValue: () => <div className={`flex items-center space-x-2 ${color.text(10)} px-4 py-2 --bg-gray-450 ${color.background(120)} rounded-[16px]`}>
                            <CustomProductsFieldLabel {...fieldsCacheContainer.get('products').get<SelectOption<CustomProductOptionValue>>(id)} showType={'variation'} size={'small'} />
                        </div>
                    }}
                />

                return <>
                    <div className={'flex flex-col gap-1'} key={`${id}-${index}`}>
                        <Card color={colors.blue}
                              outerRing={true}
                              outerRingWidth={'border-[2px]'}
                              outerRingRoundness="rounded-[26px]"
                              roundness={'rounded-[24px]'}
                              innerRing={false}
                              outerRingColor={{
                                  default: {
                                      color,
                                      tint: (color) => color.border(40)
                                  },
                                  highlight: {
                                      color,
                                      tint: (color) => color.border(20)
                                  }
                              }}
                              scaleOnHover={true}
                              animateLayout={false}
                              beforeCardInsideContent={afterContentInside}
                              enableSelfHovering={true}
                               afterContent={
                                   isHovered => <>
                                       <RemoveButton positionX={'right-corner'}
                                                     onClick={(e) => {
                                                         // prevent bubbling and thus bugs
                                                            e.stopPropagation()
                                                         removeProductByIndex(index)
                                                     }}
                                                     entityID={offer.id}
                                                     show={isHovered}
                                       />
                                   </>
                              }
                              outsideContent={() => {
                                  return <ul className="text-smaller-1 leading-3 text-gray-600 pl-6 pr-2 pt-2">
                                      <ListItem
                                          icon={missingItemsInCart.mode === 'auto-add' ?
                                              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
                                                   fill="currentColor" className="min-w-3 min-h-3 max-w-3 max-h-3">
                                                  <path fillRule="evenodd"
                                                        d="M14.615 1.595a.75.75 0 0 1 .359.852L12.982 9.75h7.268a.75.75 0 0 1 .548 1.262l-10.5 11.25a.75.75 0 0 1-1.272-.71l1.992-7.302H3.75a.75.75 0 0 1-.548-1.262l10.5-11.25a.75.75 0 0 1 .913-.143Z"
                                                        clipRule="evenodd"/>
                                              </svg> :
                                              <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                                   strokeWidth={1.5} stroke="currentColor"
                                                   className="min-w-4 min-h-4 max-w-4 max-h-4">
                                                  <path strokeLinecap="round" strokeLinejoin="round"
                                                        d="M15.042 21.672 13.684 16.6m0 0-2.51 2.225.569-9.47 5.227 7.917-3.286-.672Zm-7.518-.267A8.25 8.25 0 1 1 20.25 10.5M8.288 14.212A5.25 5.25 0 1 1 17.25 10.5"/>
                                              </svg>
                                          }
                                          className={missingItemsInCart.mode === 'auto-add' ? "text-blue-normal" : ''}
                                      >
                                          {missingItemsInCart.mode === 'auto-add' ? __('Automatically added') : __('Manually added')}
                                      </ListItem>
                                  </ul>
                              }}
                        >
                            {isInsideAnotherBranch ? <div className={classNames('', {
                                'relative flex items-center': true,
                            })}>
                                {afterContentInside}
                                {cardItem}
                            </div> : <>
                                {afterContentInside}
                                {cardItem}
                            </>}
                        </Card>
                        {showRightContextButton && rightContextButton}
                    </div>
                    <div className="last:hidden px-2">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" className="min-w-5 min-h-5 max-w-5 max-h-5 text-gray-600">
                            <path d="M10.75 4.75a.75.75 0 0 0-1.5 0v4.5h-4.5a.75.75 0 0 0 0 1.5h4.5v4.5a.75.75 0 0 0 1.5 0v-4.5h4.5a.75.75 0 0 0 0-1.5h-4.5v-4.5Z" />
                        </svg>
                    </div>
                </>
            });

            return <div className="relative flex flex-col gap-3">
                {suggestedScope === 'bogo' && <FloatingMarker prefix={__('BOGO')} label={__('Get')} paddingRight={'pr-6'}/>}
                <div
                    className={'relative grid grid-cols-1 gap-2 py-4 px-[14px] group rounded-[24px] bg-gray-400 bg-opacity-[.05] hover:bg-opacity-[.15] ring-1 ring-gray-150 ring-offset-1 hover:ring-offset-[3px] active:scale-[.97] hover:cursor-pointer transition-all ease'} onClick={openEditOffer} style={{backdropFilter: 'blur(1.45px)'}}>
                    <EditHintTextStrip
                        label={__('click to edit')}
                        className="absolute overflow-visible pointer-events-none top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[calc(100%+36px)] h-[calc(100%+36px)] origin-center scale-[.94] opacity-0 group-hover:opacity-100 group-hover:scale-100 transition-all duration-200 ease-out"
                    />
                    <div
                        className="absolute pointer-events-none group ---for-area-debugging--bg-[#000] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[calc(100%+36px)] h-[calc(100%+60px)] --group-hover:opacity-100 --opacity-0 transition-all ease">
                        <div
                            className={"pointer-events-auto group-hover:opacity-100 opacity-0 group-hover:scale-100 scale-[.84] transition-transform ease"}>
                            <RemoveButton positionX={'right-inset'} positionY={'top-inset'}
                                          onClick={(e) => {
                                              e.stopPropagation() // prevent bubbling and therefore a bug where the removed offer will be clicked to be opened right after being removed
                                              removeOffer(offer.id, branchId)
                                          }}
                                          entityID={offer.id}
                                          show={true}
                            />
                        </div>
                    </div>
                    {productsList?.length ? productsList :
                        <div className="w-full">
                            {isInsideAnotherBranch ? <div className={classNames('', {
                                'relative flex items-center': true,
                            })}>
                                {afterContentInside}
                                <button
                                    type="button"
                                    className="w-full flex items-center justify-center gap-2 py-7 text-gray-500 hover:text-gray-650 transition-colors ease"
                                    onClick={() => openProductPopup()}
                                >
                                    <div
                                        className="min-w-4 min-h-4 max-w-4 max-h-4 rounded-full bg-gray-300 flex items-center justify-center">
                                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
                                             className="min-w-2 min-h-2 max-w-2 max-h-2 text-white">
                                            <path fillRule="evenodd"
                                                  d="M8.75 4.25a.75.75 0 0 0-1.5 0v3h-3a.75.75 0 0 0 0 1.5h3v3a.75.75 0 0 0 1.5 0v-3h3a.75.75 0 0 0 0-1.5h-3v-3Z"
                                                  clipRule="evenodd"/>
                                        </svg>
                                    </div>
                                    <span className="text-smaller-1">{__('Select product discount')}</span>
                                </button>
                            </div> : <>
                                {afterContentInside}
                                <button
                                    type="button"
                                    className="w-full flex items-center justify-center gap-2 py-7 text-gray-500 hover:text-gray-650 transition-colors ease"
                                    onClick={() => openProductPopup()}
                                >
                                    <div
                                        className="min-w-4 min-h-4 max-w-4 max-h-4 rounded-full bg-gray-300 flex items-center justify-center">
                                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
                                             className="min-w-2 min-h-2 max-w-2 max-h-2 text-white">
                                            <path fillRule="evenodd"
                                                  d="M8.75 4.25a.75.75 0 0 0-1.5 0v3h-3a.75.75 0 0 0 0 1.5h3v3a.75.75 0 0 0 1.5 0v-3h3a.75.75 0 0 0 0-1.5h-3v-3Z"
                                                  clipRule="evenodd"/>
                                        </svg>
                                    </div>
                                    <span className="text-smaller-1">{__('Select product discount')}</span>
                                </button>
                            </>}
                        </div>}
                </div>
                <div className="pl-5 leading-3 text-gray-600">
                    {isRecursive && <RepeatingLabel /> }
                </div>
            </div>
        }
    },
    ComputedValue:  usingOfferOptions<BuyXGetYOptions>((opts, {color}) => {
        const {mode, data} = opts
        if (mode === 'products') {
            return /*<div className={'flex space-x-1 text-3x  text-white'}>
                <div className={'text-opacity-90 text-white'}>{__('Get')}</div>
            </div>
*/        }

        const advancedData: AdvancedData = data as AdvancedData

        /**
         * This copies a lot from buy x get x, should be refactored to remove duplication
         */
        return <div className="space-y-1">
            <div>
                <div className={`${color.text(10)} flex items-center`}>
                    {false && <span className="max-w-[6px] overflow-hidden text-4x font-black translate-y-1/4">-</span>}
                    <div className="--flex --items-center space-y-1">
                        <div className={'flex space-x-1 text-3x  text-white'}>
                            <div className={'text-opacity-60 text-white'}>{__('Get')}</div>
                            <div className={'font-semibold'}>{advancedData.discountOptions.quantity}</div>
                        </div>
                        {false && <span className={'opacity-60 px-1'}>-</span>}
                        {false && <CardItemSecondaryValue color={{
                            color,
                            tint: (color) => color.text(20)
                        }}>{__('Get')}</CardItemSecondaryValue>}
                        {<div className={'flex items-center space-x-1'}>
                            <DiscountValue productDiscountOptions={advancedData.discountOptions}/>
                            {/*
                        {interpolateElements(__(' {1} for {2} '), {
                            1: renderOfferMainValue(quantity),
                            2: renderDiscountValue(),
                        })}
*/}
                        </div>}
                    </div>
                </div>
            </div>
        </div>;

    }),
    OutsideComputedValue: usingOfferOptions<BuyXGetYOptions>(({mode, data, __BASE__: {isRecursive} }, {color},) => {
        const contextsWithChildrenIDs = useNodesStore(store => {
            if (mode !== 'advanced') {
                return []
            }

            const testables = new Testables(store)

            return ((data as AdvancedData)?.source || []).filter(contextID => {
                return testables.getNode(contextID)
            })
        })

        if (mode === 'products') {
/*
            let productsList = ((data as ProductData) ?? [])?.map((productData, index, itemsArray) => {
                const {id, quantity, discount} = productData
                const productDiscountOptions = {
                    quantity,
                    discount
                }
                const productOption = fieldsCacheContainer.get('products').get<SelectOption<CustomProductOptionValue>>(id)?.value?.option
                const productName = productOption?.type === 'variation'
                    ? (productOption?.parent_name || productOption?.name)
                    : (productOption?.name || id)

                return <div className={'flex flex-col gap-1'} key={`${id}-${index}`}>
                    <Card color={colors.blue}
                          outerRing={true}
                          outerRingWidth={'border-[2px]'}
                          outerRingRoundness="rounded-[22px]"
                          roundness={'rounded-[20px]'}
                          innerRing={false}
                          outerRingColor={{
                              default: {
                                  color,
                                  tint: (color) => color.border(40)
                              },
                              highlight: {
                                  color,
                                  tint: (color) => color.border(20)
                              }
                          }} scaleOnHover={false} animateLayout={false}>
                        <CardItem
                            color={colors.blue}
                            colors={useMemo(() => ({
                                background: {
                                    color,
                                    tint: (color) => `${color.background(110)} ${color.background(hover(100))}`
                                },
                                icon: {
                                    background: {
                                        color,
                                        tint: (color) => color.background(10)
                                    },
                                    color: {
                                        color,
                                        tint: (color) => color.text(90)
                                    }
                                }
                            }), [color])}
                            customPadding={'pt-1 pb-[6px] px-[6px]'}
                            position={'first last'}
                            cardRenderer={{
                                icon: false,//BuyXGetYMeta.icon!,
                                ComputedValue: () => <div className={`w-[max-content] flex items-center space-x-2 pl-3 ${color.text(10)}`}>
                                    <div className={'flex space-x-1 text-3x  text-white'}>
                                        <div className={'text-opacity-60 text-white'}>{__('Get')}</div>
                                        <div className={'font-semibold'}>{quantity}</div>
                                    </div>
                                    <div className={'flex items-center space-x-1'}>
                                        <DiscountValue productDiscountOptions={productData}/>
                                    </div>
                                    {false && <span
                                        className="flex leading-5 px-1 rounded-6 bg-gray-250 bg-opacity-40 text-gray-350">
                                        {productData.missingItemsInCart.mode === 'auto-add' ? __('Auto') : __('Manual')}
                                    </span>
                                    }                                </div>,
                                BelowComputedValue: () => <div className={`flex items-center space-x-2 ${color.text(10)} px-3 py-[6px] ${color.background(120)} rounded-2`}>
                                    <CustomProductsFieldLabel {...fieldsCacheContainer.get('products').get<SelectOption<CustomProductOptionValue>>(id)} showType={'variation'} />
                                </div>
                            }}
                        />
                    </Card>
                    {index + 1 !== itemsArray.length && <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="text-gray-650 ml-1 min-w-3 min-h-3 max-w-3 max-h-3">
                        <path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                    </svg>}
                </div>
            });
*/

            return <div className="space-y-2">
                <div className="px-[10px] py-2">
                    {productsList?.length ? <div className="space-y-1">{productsList}</div> :
                        <div className={`flex items-center gap-1 ${colors.gray.text(40)}`}>
                            <div
                                className="min-w-3 min-h-3 max-w-3 max-h-3 rounded-full bg-gray-300 flex items-center justify-center">
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
                                     className="min-w-2 min-h-2 max-w-2 max-h-2 text-white">
                                    <path fillRule="evenodd"
                                          d="M14 13.25a.75.75 0 0 0-.75-.75h-6.5V4.56l.97.97a.75.75 0 0 0 1.06-1.06L6.53 2.22a.75.75 0 0 0-1.06 0L3.22 4.47a.75.75 0 0 0 1.06 1.06l.97-.97v8.69c0 .414.336.75.75.75h7.25a.75.75 0 0 0 .75-.75Z"
                                          clipRule="evenodd"/>
                                </svg>
                            </div>
                            <span
                                className={`text-smaller-1`}>{__('Click card to select products')}</span>
                        </div>}
                </div>
                {isRecursive && <div className={"pl-2 text-gray-550"}><RepeatingLabel/></div> }
            </div>
        } else if (mode === 'advanced') {
            return <div className="space-y-1 py-1">
                <p className="px-2 text-gray-500 text-smaller-1 ---whitespace-nowrap w-[max-content] min-w-36 max-w-45">{__('On the cheapest item from any of these groups')}</p>
                <div className="relative space-y-1">
                    {contextsWithChildrenIDs.map((context) => {
                        return <>
                            <TestableComposite id={context} isRoot={false} removable={false}  buttonsAreEnabled={false} unsupportedComponents={getYUnsupportedComponents()} color={getAdvancedYCardColor()}/>
                            <p className="last:hidden w-full px-3 text-gray-500 font-semibold">{__('OR')}</p></>
                    })}
                </div>
            </div>
        }
    }),

}
