import { create, tsx } from '@dojo/framework/core/vdom';
import { createICacheMiddleware } from '@dojo/framework/core/middleware/icache';
import theme from '../middleware/theme';
import { createResourceMiddleware } from '@dojo/framework/core/middleware/resources';
import Typeahead from '../typeahead';
import * as css from '../theme/default/chip-typeahead.m.css';
import { ListItem } from '../list';
import Chip from '../chip';
import focus from '@dojo/framework/core/middleware/focus';
import * as typeaheadCss from '../theme/default/typeahead.m.css';
import * as chipCss from '../theme/default/chip.m.css';
import { find } from '@dojo/framework/shim/array';
const factory = create({
    icache: createICacheMiddleware(),
    theme,
    resource: createResourceMiddleware(),
    focus
})
    .properties()
    .children();
function valueChanged(values = [], options = []) {
    if (values.length !== options.length) {
        return true;
    }
    for (let i = 0; i < values.length; i++) {
        if (!options[i] || options[i].value !== values[i]) {
            return true;
        }
    }
    return false;
}
export const ChipTypeahead = factory(function ChipTypeahead({ middleware: { icache, theme, focus, resource }, properties, children }) {
    const { value, classes = {}, variant, initialValue = [], disabled, itemsInView, position, name, placement = 'inline', strict, resource: { template, options = resource.createOptions((curr, next) => (Object.assign({}, curr, next))) }, kind } = properties();
    const { get, template: { read } } = resource.template(template);
    const [{ label, items, selected } = {}] = children();
    const themeCss = theme.classes(css);
    const focused = icache.getOrSet('focused', false);
    const selectedOptions = icache.set('options', (current) => {
        if (!current && initialValue && !value) {
            const items = get(options(), { read });
            const initialSelectedOptions = initialValue.map((valueId) => {
                if (items) {
                    const findResult = find(items, (item) => item.value === valueId);
                    if (findResult) {
                        return findResult;
                    }
                }
                return {
                    value: '',
                    label: ''
                };
            });
            if (valueChanged(initialValue, initialSelectedOptions)) {
                return current || [];
            }
            return initialSelectedOptions;
        }
        else if (value && valueChanged(value, current)) {
            const controlledOptions = value.map((valueId) => {
                const items = get(options(), { read });
                if (items) {
                    const findResult = find(items, (item) => item.value === valueId);
                    if (findResult) {
                        return findResult;
                    }
                }
                return {
                    value: '',
                    label: ''
                };
            });
            if (valueChanged(value, controlledOptions)) {
                return current || [];
            }
            return controlledOptions;
        }
        return current || [];
    });
    const chips = selectedOptions.map(({ value, label }, index) => {
        return (tsx(Chip, { theme: theme.compose(chipCss, css, 'selection'), key: `value-${value}`, classes: Object.assign({}, classes, { '@dojo/widgets/chip': Object.assign({}, classes['@dojo/widgets/chip'], { root: [themeCss.value] }) }), variant: variant, disabled: disabled, onClose: disabled
                ? undefined
                : () => {
                    const { onValue } = properties();
                    const options = [...icache.getOrSet('options', [])];
                    options.splice(index, 1);
                    icache.set('options', options);
                    onValue && onValue(options);
                    focus.focus();
                } }, {
            label: selected ? selected(value, label) : label
        }));
    });
    return (tsx("div", { key: "root", classes: [
            theme.variant(),
            disabled ? themeCss.disabled : null,
            themeCss.root,
            selectedOptions.length > 0 ? themeCss.hasValue : null,
            focused ? themeCss.focused : null,
            label ? themeCss.hasLabel : themeCss.noLabel
        ] },
        tsx(Typeahead, { key: "typeahead", theme: theme.compose(typeaheadCss, css, 'input'), variant: variant, strict: strict, itemsInView: itemsInView, position: position, name: name, focus: focus.shouldFocus, disabled: disabled, resource: resource({ template, options }), onValue: (value) => {
                const { onValue } = properties();
                const options = icache.set('options', (values = []) => {
                    return [...values, value];
                });
                onValue && onValue(options);
                focus.focus();
            }, value: "", onFocus: () => icache.set('focused', true), onBlur: () => icache.set('focused', false), classes: {
                '@dojo/widgets/text-input': {
                    input: [themeCss.input],
                    wrapper: [themeCss.wrapper],
                    leading: [themeCss.inputLeading],
                    leadingWrapper: [themeCss.inputLeadingWrapper],
                    defaultKind: [themeCss.defaultKind],
                    outlinedKind: [themeCss.outlinedKind],
                    labelWrapper: [themeCss.inputLabel],
                    label: [themeCss.label, chips.length ? themeCss.labelActive : undefined],
                    notchedOutline: [
                        kind === 'outlined' && chips.length ? themeCss.notchActive : undefined
                    ]
                }
            }, itemDisabled: (item) => {
                const { duplicates = false, strict = true } = properties();
                const selected = icache
                    .getOrSet('options', [])
                    .findIndex((option) => option.value === item.value) !== -1;
                return item.disabled || (!duplicates && strict && selected);
            }, kind: kind }, {
            label,
            items: (item, props) => {
                const selected = icache
                    .getOrSet('options', [])
                    .findIndex((option) => option.value === item.value) !== -1;
                if (items) {
                    return items(Object.assign({}, item, { selected }), Object.assign({}, props, { selected }));
                }
                return (tsx(ListItem, Object.assign({}, props, { selected: selected }),
                    tsx("div", { classes: [themeCss.item, selected ? themeCss.selected : null] }, item.label)));
            },
            leading: placement === 'inline' && chips && chips.length ? chips : undefined
        }),
        placement === 'bottom' && tsx("div", { classes: themeCss.values }, chips)));
});
export default ChipTypeahead;

/*# sourceMappingURL=index.mjs.map*/