import { useState, useMemo, useCallback, useEffect } from 'react';
import { BuildTheme, ThemeOverride, Flex, FormDialog, Input } from '@pega/cosmos-react-core';
import { CodeEditor, DynamicInput } from '@pega/cosmos-react-build';
import { useFieldReferenceMock } from '../FieldReference/FieldReference.mocks';
import { baseRuleTypes, defaultRuleState, fetchRules } from './DynamicInput.mocks';
export default {
    title: 'Build/DynamicInput',
    component: DynamicInput,
    args: {
        constantFormat: 'Text',
        defaultSource: 'Rule',
        required: true
    },
    argTypes: {
        constantFormat: {
            control: { type: 'select' },
            options: [
                'Text',
                'Text (paragraph)',
                'Boolean',
                'Currency',
                'Percentage',
                'Integer',
                'Decimal',
                'Phone',
                'DateTime',
                'Date',
                'Time'
            ]
        },
        defaultSource: {
            control: { type: 'select' },
            options: ['Rule', 'Constant', 'FieldReference', 'Expression']
        },
        required: {
            control: { type: 'boolean' }
        }
    }
};
export const DynamicInputDemo = (args) => {
    const defaultSource = args.defaultSource || 'Rule';
    const constantFormat = args.constantFormat || 'Text';
    const timeout = args.timeout || true;
    const [sources, setSources] = useState([
        {
            type: 'Constant',
            selected: defaultSource === 'Constant'
        },
        {
            type: 'Rule',
            selected: defaultSource === 'Rule'
        },
        {
            type: 'FieldReference',
            selected: defaultSource === 'FieldReference'
        },
        {
            type: 'Expression',
            selected: defaultSource === 'Expression'
        }
    ]);
    useEffect(() => {
        setSources([
            {
                type: 'Constant',
                selected: defaultSource === 'Constant'
            },
            {
                type: 'Rule',
                selected: defaultSource === 'Rule'
            },
            {
                type: 'FieldReference',
                selected: defaultSource === 'FieldReference'
            },
            {
                type: 'Expression',
                selected: defaultSource === 'Expression'
            }
        ]);
    }, [defaultSource]);
    const [constantValue, setConstantValue] = useState('');
    const constant = useMemo(() => {
        if (constantFormat === 'Boolean') {
            return {
                format: 'Boolean',
                props: {
                    value: constantValue === true,
                    onChange: value => {
                        setConstantValue(value);
                    }
                }
            };
        }
        if (constantFormat === 'Date' || constantFormat === 'DateTime' || constantFormat === 'Time') {
            return {
                format: constantFormat,
                props: {
                    value: constantValue,
                    onChange: (value) => {
                        setConstantValue(value.valueAsISOString);
                    }
                }
            };
        }
        return {
            format: constantFormat,
            props: {
                value: String(constantValue),
                onChange: (value) => {
                    setConstantValue(value);
                }
            }
        };
    }, [constantValue, constantFormat]);
    const [ruleState, setRuleState] = useState({
        props: defaultRuleState
    });
    const [ruleConfigDialogTarget, setRuleConfigDialogTarget] = useState();
    const onRuleExpand = useCallback((itemId) => {
        const expandedItem = ruleState.props.ruleTypes?.find(item => item.id === itemId);
        if (expandedItem?.rules.length === 0) {
            const { promise } = fetchRules({ ruleType: expandedItem.type, delay: timeout ? 1000 : 0 });
            promise
                .then(res => {
                const newItems = ruleState.props.ruleTypes?.map(item => {
                    if (item.id === expandedItem.id) {
                        return { ...item, rules: res.results };
                    }
                    return item;
                });
                setRuleState({
                    ...ruleState,
                    props: { ...ruleState.props, loading: false, ruleTypes: newItems }
                });
            })
                .catch(() => { });
            setRuleState({
                ...ruleState,
                props: { ...ruleState.props, loading: true }
            });
        }
    }, [ruleState]);
    const onRuleFilter = useCallback((filterValue) => {
        if (ruleState.pendingFetch) {
            ruleState.pendingFetch.abort();
        }
        if (!filterValue) {
            setRuleState({
                ...ruleState,
                props: {
                    ...defaultRuleState
                }
            });
            return;
        }
        const fetch = fetchRules({ filter: filterValue, delay: timeout ? 1000 : 0 });
        fetch.promise.then(fetchedRules => {
            if (!ruleState.props) {
                return undefined;
            }
            setRuleState({
                pendingFetch: undefined,
                props: {
                    ...ruleState.props,
                    filterValue,
                    loading: false,
                    items: fetchedRules.results
                }
            });
        });
        setRuleState({
            pendingFetch: fetch,
            props: {
                ...ruleState.props,
                loading: true,
                filterValue,
                ruleTypes: [],
                items: undefined
            }
        });
    }, [ruleState]);
    const ruleLoadMore = useCallback((itemId) => {
        const ruleStateProps = ruleState.props;
        const ruleItems = ruleStateProps.items;
        const directList = !!ruleState.props.items;
        if (!itemId && !directList) {
            return ruleStateProps;
        }
        const expandedItem = ruleState.props.ruleTypes?.find(item => item.id === itemId);
        let fetchParams = {};
        if (!directList && expandedItem) {
            const currentLength = expandedItem?.rules.length;
            const totalCount = baseRuleTypes.find(item => item.id === itemId).count;
            if (currentLength >= totalCount) {
                return ruleStateProps;
            }
            fetchParams = {
                ruleType: itemId,
                start: currentLength,
                delay: timeout ? 1000 : 0
            };
        }
        if (ruleState.pendingFetch) {
            ruleState.pendingFetch.abort();
        }
        const fetch = fetchRules(fetchParams);
        fetch.promise.then(res => {
            setRuleState({
                pendingFetch: undefined,
                props: {
                    ...ruleState.props,
                    loading: false,
                    items: ruleItems
                        ? {
                            ...ruleItems,
                            ...res.results
                        }
                        : undefined,
                    ruleTypes: expandedItem
                        ? ruleState.props.ruleTypes?.map(item => {
                            if (item.id === expandedItem.id) {
                                return {
                                    ...item,
                                    rules: [...item.rules, ...res.results]
                                };
                            }
                            return item;
                        })
                        : defaultRuleState.ruleTypes
                }
            });
        });
        setRuleState({
            pendingFetch: fetch,
            props: {
                ...ruleState.props,
                loading: true
            }
        });
    }, [ruleState]);
    const onRuleSelect = useCallback((selectedRule) => {
        setRuleState({
            ...ruleState,
            props: {
                ...ruleState.props,
                filterValue: undefined,
                selectedRule: {
                    ...selectedRule,
                    href: `/rules/${selectedRule.id}`,
                    onPreview: () => {
                        alert('Link previewed');
                    },
                    onLinkClick: () => {
                        alert('Link clicked');
                    },
                    onConfig: configTarget => {
                        setRuleConfigDialogTarget(configTarget);
                    },
                    onClear: () => {
                        setRuleConfigDialogTarget(undefined);
                        setRuleState({
                            props: defaultRuleState
                        });
                    }
                }
            }
        });
    }, [ruleState]);
    const fieldReferenceMock = useFieldReferenceMock('static');
    return (<ThemeOverride theme={BuildTheme}>
      <DynamicInput required={args.required} sources={sources} onSourceChange={selectedSource => {
            const updatedSources = sources.map(source => ({
                ...source,
                selected: source.type === selectedSource
            }));
            setSources(updatedSources);
        }} controls={{
            constant,
            rule: {
                props: {
                    ...ruleState.props,
                    onExpand: onRuleExpand,
                    onFilter: onRuleFilter,
                    loadMore: ruleLoadMore,
                    onSelect: onRuleSelect,
                    onCreateNew: () => { }
                }
            },
            fieldReference: {
                props: {
                    placeholder: 'Choose a field...',
                    onSelectedChange: fieldReferenceMock.handleSelectedChange,
                    menu: {
                        items: fieldReferenceMock.itemsToRender,
                        altContexts: fieldReferenceMock.altContexts,
                        currentContext: fieldReferenceMock.currentContext,
                        parentItem: fieldReferenceMock.parentItem,
                        loading: fieldReferenceMock.menuLoading
                    },
                    selected: fieldReferenceMock.selected,
                    filterValue: fieldReferenceMock.filterValue,
                    onFilterChange: fieldReferenceMock.setFilterValue,
                    onBlur: () => {
                        fieldReferenceMock.setFilterValue('');
                    }
                }
            },
            expression: {
                component: CodeEditor,
                props: {
                    list: {
                        onItemAdd: () => { },
                        details: {}
                    },
                    search: {
                        filters: [],
                        onFilterChange: () => { },
                        onSearchChange: () => { },
                        value: ''
                    },
                    codeEditorHandle: {
                        current: {
                            getValue: () => {
                                return undefined;
                            },
                            insertText: (text) => {
                                console.log(text);
                            }
                        }
                    }
                }
            }
        }}/>

      
      {ruleConfigDialogTarget && ruleState && ruleState.props?.selectedRule && (<FormDialog target={ruleConfigDialogTarget} heading={ruleState.props?.selectedRule.name} onCancel={() => {
                setRuleConfigDialogTarget(undefined);
            }} onSubmit={() => {
                setRuleConfigDialogTarget(undefined);
            }}>
          <Flex container={{ direction: 'column', gap: 2 }}>
            <Input label='Config field 1'/>
            <Input label='Config field 2'/>
            <Input label='Config field 3'/>
          </Flex>
        </FormDialog>)}
    </ThemeOverride>);
};
//# sourceMappingURL=DynamicInput.stories.jsx.map