var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { css, html, customElement, property, repeat, state, when } from '../../../../external/lit/index.js';
import { splitStringToArray } from '../../utils/index.js';
import { UmbChangeEvent } from '../../event/index.js';
import { UmbLitElement } from '../../lit-element/index.js';
import { UmbSorterController } from '../../sorter/index.js';
import { UmbFormControlMixin } from '../../validation/index.js';
import { getItemFallbackName } from '../../entity-item/index.js';
let UmbInputEntityElement = class UmbInputEntityElement extends UmbFormControlMixin(UmbLitElement) {
    #sorter;
    getFormElement() {
        return undefined;
    }
    set min(value) {
        this.#min = value;
        if (this.#pickerContext) {
            this.#pickerContext.min = value;
        }
    }
    get min() {
        return this.#min;
    }
    #min;
    set max(value) {
        this.#max = value;
        if (this.#pickerContext) {
            this.#pickerContext.max = value;
        }
    }
    get max() {
        return this.#max;
    }
    #max;
    set selection(uniques) {
        this.#pickerContext?.setSelection(uniques);
        this.#sorter.setModel(uniques);
    }
    get selection() {
        return this.#pickerContext?.getSelection() ?? [];
    }
    set value(selectionString) {
        this.selection = splitStringToArray(selectionString);
    }
    get value() {
        return this.selection.length > 0 ? this.selection.join(',') : undefined;
    }
    set pickerContext(ctor) {
        if (this.#pickerContext)
            return;
        this.#pickerContext = ctor ? new ctor(this) : undefined;
        this.#observePickerContext();
    }
    get pickerContext() {
        return this.#pickerContext;
    }
    #pickerContext;
    constructor() {
        super();
        this.#sorter = new UmbSorterController(this, {
            getUniqueOfElement: (element) => {
                return element.id;
            },
            getUniqueOfModel: (modelEntry) => {
                return modelEntry;
            },
            identifier: 'Umb.SorterIdentifier.InputEntity',
            itemSelector: 'uui-ref-node',
            containerSelector: 'uui-ref-list',
            onChange: ({ model }) => {
                this.selection = model;
                this.dispatchEvent(new UmbChangeEvent());
            },
        });
        this.#min = 0;
        this.minMessage = 'This field need more items';
        this.#max = Infinity;
        this.maxMessage = 'This field exceeds the allowed amount of items';
        this.addValidator('rangeUnderflow', () => this.minMessage, () => !!this.min && (this.#pickerContext?.getSelection().length ?? 0) < this.min);
        this.addValidator('rangeOverflow', () => this.maxMessage, () => !!this.max && (this.#pickerContext?.getSelection().length ?? 0) > this.max);
    }
    async #observePickerContext() {
        if (!this.#pickerContext)
            return;
        this.#pickerContext.min = this.min;
        this.#pickerContext.max = this.max;
        this.observe(this.#pickerContext.selection, (selection) => (this.value = selection.join(',')), '_observeSelection');
        this.observe(this.#pickerContext.selectedItems, (selectedItems) => (this._items = selectedItems), '_observerItems');
    }
    #openPicker() {
        this.#pickerContext?.openPicker({
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore
            // TODO: ignoring this for now to prevent breaking existing functionality.
            // if we want a very generic input it should be possible to pass in picker config
            hideTreeRoot: true,
        });
    }
    #removeItem(item) {
        this.#pickerContext?.requestRemoveItem(item.unique);
    }
    render() {
        return html `${this.#renderItems()} ${this.#renderAddButton()}`;
    }
    #renderAddButton() {
        if (this.max === 1 && this.selection && this.selection.length >= this.max)
            return;
        return html `
			<uui-button
				id="btn-add"
				look="placeholder"
				@click=${this.#openPicker}
				label=${this.localize.term('general_choose')}></uui-button>
		`;
    }
    #renderItems() {
        if (!this._items)
            return;
        return html `
			<uui-ref-list>
				${repeat(this._items, (item) => item.unique, (item) => this.#renderItem(item))}
			</uui-ref-list>
		`;
    }
    #renderItem(item) {
        if (!item.unique)
            return;
        const icon = this.getIcon?.(item) ?? item.icon ?? '';
        return html `
			<uui-ref-node name=${item.name ?? getItemFallbackName(item)} id=${item.unique}>
				${when(icon, () => html `<umb-icon slot="icon" name=${icon}></umb-icon>`)}
				<uui-action-bar slot="actions">
					<uui-button @click=${() => this.#removeItem(item)} label=${this.localize.term('general_remove')}></uui-button>
				</uui-action-bar>
			</uui-ref-node>
		`;
    }
    static { this.styles = [
        css `
			#btn-add {
				width: 100%;
			}
		`,
    ]; }
};
__decorate([
    property({ type: Number })
], UmbInputEntityElement.prototype, "min", null);
__decorate([
    property({ type: String, attribute: 'min-message' })
], UmbInputEntityElement.prototype, "minMessage", void 0);
__decorate([
    property({ type: Number })
], UmbInputEntityElement.prototype, "max", null);
__decorate([
    property({ attribute: false })
], UmbInputEntityElement.prototype, "getIcon", void 0);
__decorate([
    property({ type: String, attribute: 'min-message' })
], UmbInputEntityElement.prototype, "maxMessage", void 0);
__decorate([
    property({ type: Array })
], UmbInputEntityElement.prototype, "selection", null);
__decorate([
    property({ type: String })
], UmbInputEntityElement.prototype, "value", null);
__decorate([
    property({ attribute: false })
], UmbInputEntityElement.prototype, "pickerContext", null);
__decorate([
    state()
], UmbInputEntityElement.prototype, "_items", void 0);
UmbInputEntityElement = __decorate([
    customElement('umb-input-entity')
], UmbInputEntityElement);
export { UmbInputEntityElement };
export default UmbInputEntityElement;
