import React, {FC, lazy, Suspense} from "react";
import {InclusionValueValidatorOptions} from "./cards/InclusionValueValidator";
import {Tab, Tabs, TabsProps} from "./fields/tabs";
import {__, CouponsPlus} from "../globals";
import {FieldItem, FieldRow, FieldType} from "./fields";
import {merge} from "lodash";
import {MultiSelectProps} from "./fields/MultiSelect";
import {PartialDeep} from "type-fest";
import {ComponentMeta} from "./ComponentsMeta";
import {CardType} from "./cards";
import classNames from "classnames";

// Lazy load to break circular dependency
const SingleFieldRenderer = lazy(() =>
    import('../Fields').then(module => ({default: module.SingleFieldRenderer}))
);

export type InclusionValueValidatorFieldsProps = {
    type: ComponentMeta['type'],
    id: ComponentMeta['id'],
    selectExtraFieldProps?: FieldItem<PartialDeep<MultiSelectProps<any>>, InclusionValueValidatorOptions>['fieldProps'],
    expectedValuesKey: string,
    selectExtraFieldOptions: Record<string, any>,
    supportedComponents?: {
        inclusionType?: boolean,
        expectedValues?: boolean,
    },
    //......
    options: InclusionValueValidatorOptions,
    onUpdate?: (data) => void,
    componentRuntimeData?: unknown
}


const inclusionTypeTabs: Tab[] = [
    {
        id: 'allowed',
        label: __('Eligible'),
    },
    {
        id: 'forbidden',
        label: __('Not Eligible'),
    }
]
/**
 * Custom fields for the inclusion value validator because it's a tightly coupled boxed of specific fields with a specific style not obtainable though separate means.
 */
export const InclusionValueValidatorFields: FC<InclusionValueValidatorFieldsProps> = ({
    type,id, selectExtraFieldProps, selectExtraFieldOptions, supportedComponents,
                                                                                          options,
                                                                                          onUpdate,
                                                                                          expectedValuesKey = 'expectedValues',
                                                                                          componentRuntimeData
                                                                                      }) => {
    supportedComponents = merge({inclusionType: true, expectedValues: true}, supportedComponents);
    // Lazy getter function to avoid circular dependency
    const getComponentMetaData = () => {
        return CouponsPlus.components[type][id] as CardType;
    };

    const getInclusionTypeField = () => {
        const componentMetaData = getComponentMetaData();
        // @ts-ignore
        return componentMetaData?.fields?.['inclusionType']?.meta?.extraLabels as PartialDeep<{
            allowed: {
                placeholder: string,
                aboveList: string
            },
            forbidden: {
                placeholder: string,
                aboveList: string
            }
        }>;
    };

    const getExcludedSubsetValuesField = () => {
        const componentMetaData = getComponentMetaData();
        return componentMetaData?.fields?.['excludedSubsetValues']?.meta?.extraLabels as PartialDeep<{
            allowed: {
                placeholder: string,
                aboveList: string
            },
        }>;
    };

    const getSupportsExcludingSubset = () => {
        const componentMetaData = getComponentMetaData();
        const meta = componentMetaData?.fields?.['excludedSubsetValues']?.meta;
        // @ts-ignore
        return meta?.supportsExcludingSubset || false;
    };

    return <div className="">
        <Suspense fallback={null}>
            {supportedComponents.inclusionType && <SingleFieldRenderer componentRuntimeData={componentRuntimeData as any} onUpdate={onUpdate} field={{
                id: 'inclusionType',
                renderType: FieldType.Tab,
                fieldProps: {size: 'normal', connectedToThe: 'bottom'} as TabsProps
            }}/>}
        </Suspense>
        {supportedComponents.expectedValues && <div className={classNames('border-gray-150 border-px --border-t-0', {
            'rounded-b-1': supportedComponents.inclusionType,
            'rounded-1': !supportedComponents.inclusionType,
        })}>
            <Suspense fallback={<div className={'h-66 p-5'}></div>}>
                <div className="p-4">
                    <SingleFieldRenderer key={options.inclusionType}
                                         componentRuntimeData={componentRuntimeData as any}
                                        onUpdate={onUpdate}
                                        field={
                                            {
                                                id: expectedValuesKey,
                                                renderType: FieldType.MultiSelect,
                                                // merge here is probably terrible for performance (re-renders) but it will have to do for now
                                                fieldProps: (options: InclusionValueValidatorOptions) => {
                                                    const inclusionTypeField = getInclusionTypeField();
                                                    return merge({
                                                            SelectSearchProps: {
                                                                placeholder: () => {
                                                                    if (options.inclusionType === 'allowed') {
                                                                        return inclusionTypeField?.allowed?.placeholder || __('Search items to include...')
                                                                    }
                                                                    return inclusionTypeField?.forbidden?.placeholder || __('Search items to exclude...')
                                                                },
                                                            },
                                                            SelectStateProps: {
                                                                labels: {
                                                                    above: inclusionTypeField?.[options.inclusionType]?.aboveList
                                                                },
                                                                defaultItemOptions: {
                                                                    beforeLabel(): React.ReactNode {
                                                                        if (options.inclusionType === 'forbidden') {
                                                                            return <svg xmlns="http://www.w3.org/2000/svg"
                                                                                        viewBox="0 0 24 24"
                                                                                        fill="currentColor"
                                                                                        className="min-w-[18px] min-h-[18px] max-w-[18px] max-h-[18px] text-gray-250">
                                                                                <path fillRule="evenodd"
                                                                                      d="m6.72 5.66 11.62 11.62A8.25 8.25 0 0 0 6.72 5.66Zm10.56 12.68L5.66 6.72a8.25 8.25 0 0 0 11.62 11.62ZM5.105 5.106c3.807-3.808 9.98-3.808 13.788 0 3.808 3.807 3.808 9.98 0 13.788-3.807 3.808-9.98 3.808-13.788 0-3.808-3.807-3.808-9.98 0-13.788Z"
                                                                                      clipRule="evenodd"/>
                                                                            </svg>

                                                                        }

                                                                        return <svg xmlns="http://www.w3.org/2000/svg"
                                                                                    viewBox="0 0 24 24"
                                                                                    fill="currentColor"
                                                                                    className="min-w-5 min-h-5 max-w-5 max-h-5 text-gray-250">
                                                                            <path fillRule="evenodd"
                                                                                  d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z"
                                                                                  clipRule="evenodd"/>
                                                                        </svg>
                                                                    }
                                                                },
                                                            }
                                                        },
                                                        (typeof selectExtraFieldProps === 'function' ? selectExtraFieldProps(options) : selectExtraFieldProps) || {}
                                                    );
                                                },
                                                fieldOptions: selectExtraFieldOptions
                                            } as FieldItem<MultiSelectProps<any>, InclusionValueValidatorOptions>
                                        }/>
                </div>
            </Suspense>
        </div>
        }    </div>
}







