import React, {FC, ReactNode} from "react";
import {ComponentAction, ComponentRuntimeDataWithParentType, getDefaultRuntimeComponentData} from "./tree/components";
import {Tabs} from "./tree/fields/tabs";
import {__} from "./globals";
import {ComponentsMeta, getComponentMeta, getComponentMetaData} from "./tree/ComponentsMeta";
import {QuantityRenderer, QuantityMeta} from "./tree/cards/Quantity";
import classNames from "classnames";
import {ProductsRenderer} from "./tree/cards/ProductsRenderer";
import {NULL} from "sass";
import {QuantityDecision} from "./TestablesPopupWindow";
import {getCardRendererFromType} from "./tree/cards";
import {TestableData} from "./tree/store";
import {withDecodedEntities} from "./helpers";

export type ExtraTestableFieldsProps = {
    componentRuntimeData: ComponentRuntimeDataWithParentType[],
    onSetComponents: (actions: {
        add?: ComponentRuntimeDataWithParentType[],
        remove?: ComponentRuntimeDataWithParentType[]
    }) => void,
    currentFilterId: string | null,
    fields: () => ReactNode,
    testableType: TestableData['testableType']
}

const getDefaultRuntimeComponentDataWithParentType = (type: string): ComponentRuntimeDataWithParentType => ({
        parentType: 'filters',
        ...getDefaultRuntimeComponentData(getComponentMeta('filters', type))!,
    }
)

const quantityDefaultRuntimeData: ComponentRuntimeDataWithParentType = getDefaultRuntimeComponentDataWithParentType(QuantityRenderer.type!)

const getExtraComponentsAvailable = (componentRuntimeData: ComponentRuntimeDataWithParentType[], currentFilterId, testableType: TestableData['testableType']): {
    type: string,
    name: string,
    prename: string,
    action: string
}[] => {
    const filters = ComponentsMeta[`${testableType}s`]
    const allRegisteredFiltersExceptSelected = filters.filter(({id}) => {
        return !componentRuntimeData.find((selectedComponentData) => {
            const {type} = selectedComponentData
            const selected = type === id
            let canShowAsAvailableAfterBeingSelected = false
            if (selected) {
                const renderer = getCardRendererFromType(type)

                const extraCheck = renderer.canShowAsAvailableWhileBeingAmongstSelected?.(selectedComponentData.options, currentFilterId)

                if (typeof extraCheck === 'boolean') {
                    canShowAsAvailableAfterBeingSelected = extraCheck
                }
            }
            // needs to be ==== false, don't change it.
            return selected && canShowAsAvailableAfterBeingSelected === false
        })
    })

    const filtersCompatibleWithCurrentSelection = allRegisteredFiltersExceptSelected.filter(componentMeta => {
        // get the selected filters
        //loop though each of them and check that the componentMeta is not present in the incompatibleWith array of the selected filter
        const selectedFilters = componentRuntimeData; // not redundant, its more readable

        for (const selectedFilter of selectedFilters) {
            const selectedFilterMeta = getComponentMeta(selectedFilter.parentType, selectedFilter.type);
            const incompatibleWith = selectedFilterMeta?.incompatibleWith || [];
            // if the componentMeta is not in the incompatibleWith array, then it is compatible
            if (incompatibleWith.includes(componentMeta.id)) {
                return false;
            }
        }

        return true
    })

    return filtersCompatibleWithCurrentSelection.map(componentMeta => ({
        type: componentMeta.id,
        name: withDecodedEntities(getComponentMetaData(componentMeta)).name,
        prename: componentMeta?.prename?.(componentRuntimeData) || 'Any',
        action: componentMeta?.action?.(componentRuntimeData) === ComponentAction.Exclude ? 'Exclude' : 'Select',
    }))
    /*[
    {
        name: getComponentMetaData(['filters', Products.type!]).name,
        prename: getComponentMeta('filters', Products.type!)?.prename?.(componentRuntimeData) || 'Any',
        action: getComponentMeta('filters', Products.type!)?.action?.(componentRuntimeData) === ComponentAction.Exclude ? 'Exclude' : 'Select',
    }/ * {
                prename: 'No excluded',
                name: 'Products',
                action: 'Exclude Products'
            }, {
                prename: 'With any',
                name: 'Attributes',
                action: 'Select Attributes'
            }, {
                prename: 'Any',
                name: 'Brands',
                action: 'Select Brands'
            }* /];*/
}
export const ExtraTestableFields: FC<ExtraTestableFieldsProps> = ({
                                                                      componentRuntimeData,
                                                                      onSetComponents,
                                                                      currentFilterId,
                                                                      fields,
                                                                      testableType
                                                                  }) => {
    const extraComponentsAvailable = getExtraComponentsAvailable(componentRuntimeData, currentFilterId, testableType);

    return <div className="space-y-30 flex flex-col justify-between w-69 border-px border-gray-150 rounded-1 px-4 py-6">
        {false && <div className="space-y-5">
            {fields()}
        </div>}
        {!!extraComponentsAvailable.length && <div className="--border-t-px --border-t-gray-200 --pt-4 space-y-5">
            <div>
                <h2 className="text-3x leading-5 inline-block space-x-2 text-gray-600 --text-center">
                    <span>{__('Narrow down product selection') || __('Further filter products') || __('Combine with other filters')}</span><span
                    className="text-gray-450">({__('Optional')})</span></h2>
                <p className="text-smaller-1 ----text-center text-gray-400">{__('Products must match every selected filter to be eligible') || __('Products must match all selected filters')}</p>
            </div>
            <div className="space-y-3 w-full">
                {extraComponentsAvailable.map(({
                                                   type,
                                                   name,
                                                   prename,
                                                   action
                                               }) =>
                    <button
                        className={classNames({
                            'flex items-center text-gray-800 rounded-2 group': true,
                            'border-px border-gray-200 w-full hover:bg-purple-tint-10 hover:border-purple-tint-50 hover:bg-opacity-50 ': true,
                            'space-x-3 py-4 px-7': true,
                        })}
                        onClick={() => onSetComponents({add: [getDefaultRuntimeComponentDataWithParentType(type)]})}>
                        <svg xmlns="http://www.w3.org/2000/svg"
                             className={"w-5 h-5 text-gray-350 group-hover:text-purple-tint-90"} fill="none"
                             viewBox="0 0 24 24" stroke="currentColor">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
                                  d="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"/>
                        </svg>
                        <div className="flex flex-row justify-between space-x-5 w-full">
                            <div className="space-x-1">
                                {true && (<><span className="text-gray-350">{prename}</span><span
                                    className="text-1x font-medium group-hover:text-purple-tint-90">{name}</span></>)}
                            </div>
                            <button className="flex items-center space-x-1">
                                <div>{action || 'Select'}</div>
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                     strokeWidth={1.5}
                                     stroke="currentColor" className="min-w-4 max-w-4 min-h-4 max-h-4">
                                    <path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15"/>
                                </svg>
                            </button>
                        </div>
                    </button>)}

            </div>
        </div>}
    </div>;
}
