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 * as labelCss from '../theme/default/label.m.css';
import Label from '../label';
const factory = create({
    icache: createICacheMiddleware(),
    theme,
    resource: createResourceMiddleware(),
    focus
})
    .properties()
    .children();
export function arraysDifferent(arr1, arr2) {
    if (arr1.length !== arr2.length) {
        return true;
    }
    for (let i = 0; i < arr1.length; i++) {
        if (arr1[i] !== arr2[i]) {
            return true;
        }
    }
    return false;
}
export const ChipTypeahead = factory(function ChipTypeahead({ id, middleware: { icache, theme, focus, resource }, properties, children }) {
    const { createOptions, find } = resource;
    const { initialValue = [], disabled, itemsInView, position, name, placement = 'inline', strict, resource: { template, options = createOptions(id) } } = properties();
    const [{ label, items, selected } = {}] = children();
    const themeCss = theme.classes(css);
    const { value, classes = {}, variant } = properties();
    const focused = icache.getOrSet('focused', false);
    if (value !== undefined && arraysDifferent(value || [], icache.get('value') || [])) {
        icache.set('value', value || []);
    }
    if (value === undefined && arraysDifferent(icache.getOrSet('initialValue', []), initialValue)) {
        icache.set('value', initialValue);
        icache.set('initialValue', initialValue);
    }
    const storedValues = icache.getOrSet('value', []);
    const findOptions = createOptions(`${id}-find`);
    findOptions({ size: options().size, page: options().page });
    const chips = storedValues.map((value, index) => {
        let option;
        if (value) {
            option = (find(template, {
                options: findOptions(),
                start: 0,
                query: { value },
                type: 'exact'
            }) || {
                item: undefined
            }).item;
        }
        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, onClose: disabled
                ? undefined
                : () => {
                    const { onValue } = properties();
                    const options = [...icache.getOrSet('options', [])];
                    options.splice(index, 1);
                    icache.set('value', options.map((option) => option.value));
                    icache.set('options', options);
                    onValue && onValue(options);
                    focus.focus();
                } }, {
            label: selected
                ? selected(value, option ? option.label : value)
                : option
                    ? option.label
                    : value
        }));
    });
    const values = icache.getOrSet('value', []);
    const active = focused || values.length > 0;
    return (tsx("div", { key: "root", classes: [
            theme.variant(),
            themeCss.root,
            values.length > 0 ? themeCss.hasValue : null,
            focused ? themeCss.focused : null,
            label ? themeCss.hasLabel : null
        ] },
        label && (tsx(Label, { focused: focused, active: active, theme: theme.compose(labelCss, css, 'label'), classes: {
                '@dojo/widgets/label': {
                    root: [themeCss.label]
                }
            }, variant: variant }, label)),
        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];
                });
                const values = icache.set('value', (values = []) => {
                    return [...values, value.value];
                });
                icache.set('value', values);
                icache.set('options', options);
                onValue && onValue(options);
                focus.focus();
            }, value: "", onFocus: () => icache.set('focused', true), onBlur: () => icache.set('focused', false), classes: {
                '@dojo/widgets/text-input': {
                    inputWrapper: [themeCss.inputWrapper],
                    input: [themeCss.input],
                    wrapper: [themeCss.wrapper]
                }
            }, itemDisabled: (item) => {
                const { duplicates = false, strict = true } = properties();
                const selected = icache.getOrSet('value', []).indexOf(item.value) !== -1;
                return item.disabled || (!duplicates && strict && selected);
            } }, {
            items: (item, props) => {
                const selected = icache.getOrSet('value', []).indexOf(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 : undefined
        }),
        placement === 'bottom' && tsx("div", { classes: themeCss.values }, chips)));
});
export default ChipTypeahead;

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