import React, {FC} from "react";
import {convertTestableData, useNodesStore} from "../store";
import {NoAdvancedGetYItemsSelected} from "./NoAdvancedGetYItemsSelected";
import {useOpenTestablesPopupWindow} from "../useOpenTestablesPopupWindow";
import {__, CouponsPlus} from "../../globals";
import {PopupWindowStateContext, TreeContextData} from "../atoms";
import {wrapTestablesInContext} from "../NodeHelpers";
import {getOpenPopupsCount} from "../hooks";
import {TestableFormat, Testables} from "../testables";
import {TestableComposite} from "../TestableComposite";
import {Button} from "./Button";
import {Number} from "../fields/Number";
import {NumberInput} from "../fields/NumberInput";
import {MultiSelectSearch} from "../fields/MultiSelectSearch";
import {convertDictToArrayOfOptions} from "./FieldHelpers";
import {getBOGOOfferNumberInputProps, getNumberContainerClasses} from "../fields/NumberFieldUtils";
import {ProductDiscountOptions, qtyType} from "./BuyXGetX";
import {getPopupStackDimensionCalculators} from "../ulitilies";
import {merge} from "lodash";
import {FieldSection} from "../FieldSection";
import {QuantityMeta} from "./Quantity";
import {getAdvancedYCardColor, getYUnsupportedComponents} from "./GetYAdvancedComponents";

const qtyTypesOptions = [
    {
        id: 'simple',
        value: 'simple',
        label: __('Fixed Qty.'),
    },
    {
        id: 'advanced',
        value: 'advanced',
        label: __('Any Qty.'),
    }
]

export type AdvancedGetYItemsMapFieldProps = {
    id: string;
    source?: string[], // context ids...
    onGroupAdd: (groupId: string) => void,
    discountOptions: ProductDiscountOptions,
    onQtyTypeChange: (qtyType: qtyType) => void,
    onQuantityChange: (quantity: number) => void,
    onDiscountTypeChange: (discountType: ProductDiscountOptions['discount']['type']) => void,
    onDiscountAmountChange: (discountAmount: number) => void,
}

export const AdvancedGetYItemsMapField: FC<AdvancedGetYItemsMapFieldProps> = ({
                                                                                  id,
                                                                                  source = [],
                                                                                  onGroupAdd,
                                                                                  discountOptions,
                                                                                  onQtyTypeChange,
                                                                                  onQuantityChange,
                                                                                  onDiscountTypeChange,
                                                                                  onDiscountAmountChange,
                                                                              },) => {
    const openTestablePopupWindow = useOpenTestablesPopupWindow()

    /*
        const addTestable = useNodesStore(store => store.addTestable)
    */
    const addTestables = useNodesStore(store => store.addTestables)
    const [contextIDs] = useNodesStore(store => {
        const testables = new Testables(store)
        const validIDs: string[] = []
        const invalidIDs: string[] = []

        for (let sourceId of source) {
            if (testables.getNode(sourceId)) {
                validIDs.push(sourceId)
            } else {
                invalidIDs.push(sourceId)
            }
        }
        /**
         * For the "zombie" ids, let's just remove then when we export the source
         */
        return [validIDs, invalidIDs]
    })
    const openTestablesPopup = () => {
        // here we'll open an instance of the custom filtered items map modal with only filters supported
        const context = {
            id: 'custom-get-y-group',
            scope: 'custom-filtered-items-map',
            data: {
                supportedComponentTypes: ['filter'],
                supportsMultipleComponents: true,
                unsupportedComponents: getYUnsupportedComponents(),
                /*
                                supportedComponents: [],
                */
                componentType: 'filter',
                targetType: 'ghost',
                mode: 'create',
                mainWindow: {
                    title: __('Select products to discount'),
                    description: __('These are the products that will be eligible for discount after the customer has added them to the cart. You can add several groups that will be eligible. For example, in one group you can select categories and in another group you can select specific products and any of these will be eligible for the discount.'),
                }

            }
        } as PopupWindowStateContext<TreeContextData>

        openTestablePopupWindow({
            // @ts-ignore
            context: merge(
                {
                    data: getPopupStackDimensionCalculators( getOpenPopupsCount() + 1)
                },
                context
            ),
            onClose: (data) => {
                if (data?.status === 'fail') {
                    return; // ignore
                }
                /**
                 * This might be the source of a leak because if the user cancels this popup, these filters would have been added to memory
                 * we have no reliable way to remove them on cancel because what if the user has added other filters prior to
                 * opening the offers popup and then decides to cancel? if we remove the id on cancel, we might remove the filters that were added before
                 *
                 */
                const selectedFilters = convertTestableData(data.components).map(filter => ({
                    ...filter,
                    testableType: data.componentType,
                }));

                let newContext = wrapTestablesInContext(selectedFilters);

                addTestables([[newContext], TestableFormat.Nested, false], (newTestables, testables) => {
                    if (newTestables.length) {
                        onGroupAdd(newTestables[0])
                    }
                })
            }
        })
    }
    if (!contextIDs.length) {
        return <NoAdvancedGetYItemsSelected onTestablesOpen={openTestablesPopup}/>
    }

    const selectedQtyType = discountOptions.qtyType ?? 'simple';
    const defaultDiscountNumberinputProps = getBOGOOfferNumberInputProps(discountOptions.discount.type)

    return <div className="flex flex-col items-center space-y-6">
        <FieldSection title={__('Discount options')}>
            <div className="flex flex-row items-center justify-center space-x-2 px-6 py-10 bg-gray-250/10 rounded-[28px] w-full">
                {/*quantity*/}
                <div className={getNumberContainerClasses({border: false})}>
                    <NumberInput numberId={`${id}+quantity`}
                                 fieldType={'text'}
                                 value={discountOptions.quantity}
                                 onChange={value => onQuantityChange(value)}
                                 type={selectedQtyType === 'advanced' ? 'custom' : undefined}
                                 customRenderer={<div className={"flex flex-col gap-0 items-center"}>
                                     {<p className="uppercase text-4x">{__('Unlimited')}</p>}
                                 </div>}
                                 input={{
                                     top: () => <div className="">
                                         <MultiSelectSearch size={'extra-small'}
                                                            style={'gray-lighter'}
                                                            options={qtyTypesOptions}
                                                            selectedValue={selectedQtyType}
                                                            onSelectedValue={({id}) => {
                                                                onQtyTypeChange(id as qtyType)
                                                            }}
                                         />
                                     </div>

                                 }}
                                 size={"normal"}
                    />
                </div>
                {/*discount*/}
                <div className={'inline-flex'}><Number
                    id={`${id}+discount`}
                    fieldMeta={{}}
                    /*
                                                                fieldMeta={CouponsPlus.components.offers.BuyXGetX.fields.discount}
                    */
                    input={{
                        ...defaultDiscountNumberinputProps.labels?.input,
                        top: () => <MultiSelectSearch
                            // @ts-ignore
                            options={
                                convertDictToArrayOfOptions(
                                    CouponsPlus.components.offers.BuyXGetX.fields.discount.type.meta._allowed
                                )
                            }
                            isSearchable={false}
                            selectedValue={discountOptions.discount.type}
                            onSelectedValue={
                                ({id}) => onDiscountTypeChange(id as ProductDiscountOptions['discount']['type'])
                            }
                            size={'extra-small'}
                            width={'auto'}
                            style={'gray-lighter'}
                        />
                    }}
                    {...defaultDiscountNumberinputProps}
                    hasAmountStructure={false}
                    onChange={
                        (thisfieldisemptyshouldbeignored, newValue) => {
                            return typeof newValue === 'number' && onDiscountAmountChange(newValue);
                        }
                    }
                    value={discountOptions.discount.amount}
                /></div>
            </div>

        </FieldSection>
        <FieldSection title={__('Products to discount')}>
            <div className="relative flex flex-row justify-center space-y-3 p-5 border-px border-gray-200 rounded-1 w-full max-w-full whitespace-nowrap flex-nowrap overflow-x-auto">
                <div className="relative space-y-2">
                    {contextIDs.map(contextID => {
                        return <div className="grid grid-cols-1 items-center justify-center gap-1">
                            <TestableComposite id={contextID} isRoot={false} buttonsAreEnabled={false} unsupportedComponents={getYUnsupportedComponents()} confirmRemoval={false} color={getAdvancedYCardColor()}/>
                            <div className="text-smaller-2 text-gray-350 text-center">{__('OR')}</div>
                        </div>
                    })}
                    <Button preset="gray" size={'extra-small'} onClick={openTestablesPopup}>
                        {__('Add group')} +
                    </Button>
                </div>
            </div>
        </FieldSection>
    </div>
}
