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, nothing, repeat, customElement, property, state } from '../../../../external/lit/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';
/**
 * @element umb-input-multiple-text-string
 */
let UmbInputMultipleTextStringElement = class UmbInputMultipleTextStringElement extends UmbFormControlMixin(UmbLitElement, undefined) {
    #sorter;
    /**
     * Disables the input
     * @type {boolean}
     * @attr
     * @default
     */
    set disabled(value) {
        this.#disabled = value;
        if (value) {
            this.#sorter.disable();
        }
    }
    get disabled() {
        return this.#disabled;
    }
    #disabled;
    /**
     * Makes the input readonly
     * @type {boolean}
     * @attr
     * @default
     */
    set readonly(value) {
        this.#readonly = value;
        if (value) {
            this.#sorter.disable();
        }
    }
    get readonly() {
        return this.#readonly;
    }
    #readonly;
    constructor() {
        super();
        this.#sorter = new UmbSorterController(this, {
            getUniqueOfElement: (element) => {
                return element.getAttribute('data-sort-entry-id');
            },
            getUniqueOfModel: (modelEntry) => {
                return modelEntry;
            },
            identifier: 'Umb.SorterIdentifier.MultipleTextString',
            itemSelector: 'umb-input-multiple-text-string-item',
            containerSelector: '#sorter-wrapper',
            onChange: ({ model }) => {
                const oldValue = this._items;
                this._items = model;
                this.requestUpdate('_items', oldValue);
                this.dispatchEvent(new UmbChangeEvent());
            },
        });
        /**
         * Min validation message.
         * @type {boolean}
         * @attr
         * @default
         */
        this.minMessage = 'This field need more items';
        /**
         * Max validation message.
         * @type {boolean}
         * @attr
         * @default
         */
        this.maxMessage = 'This field exceeds the allowed amount of items';
        this.#disabled = false;
        this.#readonly = false;
        this._items = [];
        // TODO: we need a way to overwrite the missing value validator. Se we can validate on other properties than value
        /*
        this.removeValidator('valueMissing');

        this.addValidator(
            'valueMissing',
            () => this.requiredMessage,
            () => this.items.length > 0
        );
        */
        this.addValidator('rangeUnderflow', () => this.minMessage, () => !!this.min && this._items.length < this.min);
        this.addValidator('rangeOverflow', () => this.maxMessage, () => !!this.max && this._items.length > this.max);
    }
    get items() {
        return this._items;
    }
    set items(items) {
        // TODO: when we have a way to overwrite the missing value validator we can remove this
        this.value = items?.length > 0 ? 'some value' : '';
        this._items = items ?? [];
        this.#sorter.setModel(this.items);
    }
    // TODO: Some inputs might not have a value that is either FormDataEntryValue or FormData.
    //  How do we handle this?
    /*
    @property()
    public set value(value: FormDataEntryValue | FormData) {
        throw new Error(`${this} does not support to set the value directly. Use items instead.`);
    }
    public get value() {
        throw new Error(`${this} does not support to get the value directly. Use items instead.`);
    }
    */
    #onAdd() {
        this._items = [...this._items, ''];
        this.pristine = false;
        this.dispatchEvent(new UmbChangeEvent());
        this.#focusNewItem();
    }
    #onInput(event, currentIndex) {
        event.stopPropagation();
        const target = event.currentTarget;
        const value = target.value;
        this._items = this._items.map((item, index) => (index === currentIndex ? value : item));
        this.dispatchEvent(new UmbChangeEvent());
    }
    async #focusNewItem() {
        await this.updateComplete;
        const items = this.shadowRoot?.querySelectorAll('umb-input-multiple-text-string-item');
        const newItem = items[items.length - 1];
        newItem.focus();
    }
    #deleteItem(event, itemIndex) {
        event.stopPropagation();
        this._items = this._items.filter((item, index) => index !== itemIndex);
        this.pristine = false;
        this.dispatchEvent(new UmbChangeEvent());
    }
    getFormElement() {
        return undefined;
    }
    render() {
        return html `<div id="sorter-wrapper">${this.#renderItems()}</div>
			${this.#renderAddButton()}`;
    }
    #renderItems() {
        return html `
			${repeat(this._items, (item, index) => index, (item, index) => html `
					<umb-input-multiple-text-string-item
						name="item-${index}"
						data-sort-entry-id=${item}
						required
						required-message="Item ${index + 1} is missing a value"
						value=${item}
						?disabled=${this.disabled}
						?readonly=${this.readonly}
						@enter=${this.#onAdd}
						@delete=${(event) => this.#deleteItem(event, index)}
						@input=${(event) => this.#onInput(event, index)}>
					</umb-input-multiple-text-string-item>
				`)}
		`;
    }
    #renderAddButton() {
        if (this.disabled || this.readonly)
            return nothing;
        if (this.max === 1 && this._items.length > 0)
            return nothing;
        return html `
			<uui-button
				color="default"
				id="action"
				label="Add"
				look="placeholder"
				?disabled=${this.disabled}
				@click=${this.#onAdd}></uui-button>
		`;
    }
    static { this.styles = [
        css `
			#action {
				display: block;
			}

			.--umb-sorter-placeholder {
				position: relative;
				visibility: hidden;
			}
			.--umb-sorter-placeholder::after {
				content: '';
				position: absolute;
				inset: 0px;
				border-radius: var(--uui-border-radius);
				border: 1px dashed var(--uui-color-divider-emphasis);
			}
		`,
    ]; }
};
__decorate([
    property({ type: Number })
], UmbInputMultipleTextStringElement.prototype, "min", void 0);
__decorate([
    property({ type: String, attribute: 'min-message' })
], UmbInputMultipleTextStringElement.prototype, "minMessage", void 0);
__decorate([
    property({ type: Number })
], UmbInputMultipleTextStringElement.prototype, "max", void 0);
__decorate([
    property({ type: String, attribute: 'min-message' })
], UmbInputMultipleTextStringElement.prototype, "maxMessage", void 0);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbInputMultipleTextStringElement.prototype, "disabled", null);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbInputMultipleTextStringElement.prototype, "readonly", null);
__decorate([
    state()
], UmbInputMultipleTextStringElement.prototype, "_items", void 0);
__decorate([
    property({ type: Array })
], UmbInputMultipleTextStringElement.prototype, "items", null);
UmbInputMultipleTextStringElement = __decorate([
    customElement('umb-input-multiple-text-string')
], UmbInputMultipleTextStringElement);
export { UmbInputMultipleTextStringElement };
export default UmbInputMultipleTextStringElement;
