import {lazy, Suspense} from "react";
import {FieldType} from "../../fields";
import {MultiSelectSearchProps} from "../../fields/MultiSelectSearch";
import {NumberProps} from "../../fields/Number";
import {AmountValidatorOptions} from "../filterinterfaces";
import {usingTestableOptions} from "../CardHelpers";
import {__} from "../../../globals";

export type CustomFieldOptions = {
    name: string, // the html name of the field
    type: 'text' | 'number' | 'exists',
    comparisonTypes: {
        text: {
            expectedValue: string,
            comparisonType: 'is' | 'not_is' | 'startswith' | 'not_startswith' | 'endswith' | 'not_endswith' | 'contains' | 'not_contains'
        },
        number: AmountValidatorOptions,
        exists: true | false
    }
}

const SingleFieldRenderer = lazy(() =>
    import('../../../Fields').then(module => ({default: module.SingleFieldRenderer}))
);

function CustomFieldTopRow(props: {
    componentRuntimeData: any,
    onUpdate: any,
    type: CustomFieldOptions['type'],
}) {
    return <Suspense fallback={null}>
        <SingleFieldRenderer
            componentRuntimeData={props.componentRuntimeData}
            onUpdate={props.onUpdate}
            extraOptionalStructure={false}
            field={{
                id: 'name',
                renderType: FieldType.Text,
                fieldProps: {
                    name: __('Name'),
                    emptyMinWidth: 120,
                    inputRight: props.type === 'text' && <SingleFieldRenderer
                        componentRuntimeData={props.componentRuntimeData}
                        onUpdate={props.onUpdate}
                        extraOptionalStructure={false}
                        field={{
                            id: 'comparisonTypes.text.comparisonType',
                            renderType: FieldType.Select,
                            fieldOptions: {optionsKey: '_allowed', centered: false},
                            fieldProps: {size: 'small', style: 'gray', width: 'auto'} as MultiSelectSearchProps<any>,
                        }}
                    />
                }
            }}
        />
    </Suspense>
}

export const customFieldFieldsMap = ({options: {type}}: {options: CustomFieldOptions}) => [
    [{id: 'type', renderType: FieldType.Tab},],
    [
        {
            id: 'name',
            renderType: FieldType.Custom,
            fieldProps: (options, onUpdate, {componentRuntimeData}) => ({
                component: <CustomFieldTopRow componentRuntimeData={componentRuntimeData} onUpdate={onUpdate} type={type}/>
            }),
        },
        ...(type === 'text' ? [
            {id: 'comparisonTypes.text.expectedValue', renderType: FieldType.Text},
        ] : (type === 'number' ? [
            {id: 'comparisonTypes.number.quantity', renderType: FieldType.Number, fieldProps: {} as NumberProps}
        ] : []))
    ],
]

export const CustomFieldComputedValue = usingTestableOptions<CustomFieldOptions>(({type, name, comparisonTypes: {text, number, exists}}, {}) => {
    const textLabels: Record<typeof text.comparisonType, string> = {
        is: text.expectedValue,
        not_is: __('(not) *').replace('*', text.expectedValue),
        startswith: __('(starts with) *').replace('*', text.expectedValue),
        not_startswith: __('(doesn\'t start with) *').replace('*', text.expectedValue),
        endswith: __('(ends with) *').replace('*', text.expectedValue),
        not_endswith: __('(doesn\'t end with) *').replace('*', text.expectedValue),
        contains: __('(contains) *').replace('*', text.expectedValue),
        not_contains: __('(doesn\'t contain) *').replace('*', text.expectedValue),
    }

    if (type === 'text') {
        return <RenderedField name={name} value={textLabels[text.comparisonType]}/>
    } else if (type === 'number') {
        const numberLabels: Record<AmountValidatorOptions['quantity']['type'], string | number> = {
            equals: number.quantity.amount,
            minimum: __('Minimum *').replace('*', number.quantity.amount),
            maximum: __('Maximum *').replace('*', number.quantity.amount),
            range: `${__('* - *').replace('*', number.quantity.range.minimum).replace('*', number.quantity.range.maxmimum)}`,
        }
        return <RenderedField name={name} value={numberLabels[number.quantity.type]} />
    }

    return <RenderedField name={name} value={__('(selected)')}/>
})

function RenderedField(props: {
    name: string,
    value: string | number,
}) {
    return <p><span className="opacity-70">{props.name}</span>: {props.value}</p>;
}
