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 { UmbDocumentPickerInputContext } from './input-document.context.js';
import { css, customElement, html, nothing, property, repeat, state, when } from '../../../../../external/lit/index.js';
import { jsonStringComparison } from '../../../../../libs/observable-api/index.js';
import { splitStringToArray } from '../../../../core/utils/index.js';
import { UmbChangeEvent } from '../../../../core/event/index.js';
import { UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, UmbFormControlMixin } from '../../../../core/validation/index.js';
import { UmbInteractionMemoriesChangeEvent } from '../../../../core/interaction-memory/index.js';
import { UmbLitElement } from '../../../../core/lit-element/index.js';
import { UmbSorterController } from '../../../../core/sorter/index.js';
import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../../document-types/index.js';
let UmbInputDocumentElement = class UmbInputDocumentElement extends UmbFormControlMixin(UmbLitElement) {
    #sorter;
    /**
     * This is a minimum amount of selected items in this input.
     * @type {number}
     * @attr
     * @default
     */
    set min(value) {
        this.#pickerInputContext.min = value;
    }
    get min() {
        return this.#pickerInputContext.min;
    }
    /**
     * This is a maximum amount of selected items in this input.
     * @type {number}
     * @attr
     * @default
     */
    set max(value) {
        this.#pickerInputContext.max = value;
    }
    get max() {
        return this.#pickerInputContext.max;
    }
    set selection(ids) {
        this.#pickerInputContext.setSelection(ids);
        this.#sorter.setModel(ids);
    }
    get selection() {
        return this.#pickerInputContext.getSelection();
    }
    set value(selectionString) {
        this.selection = splitStringToArray(selectionString);
        super.value = selectionString; // Call the parent setter to ensure the value change is triggered in the FormControlMixin. [NL]
    }
    get value() {
        return this.selection.length > 0 ? this.selection.join(',') : undefined;
    }
    /**
     * Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content.
     * @type {boolean}
     * @attr
     * @default
     */
    get readonly() {
        return this.#readonly;
    }
    set readonly(value) {
        this.#readonly = value;
        if (this.#readonly) {
            this.#sorter.disable();
        }
        else {
            this.#sorter.enable();
        }
    }
    #readonly;
    get interactionMemories() {
        return this.#pickerInputContext.interactionMemory.getAllMemories();
    }
    set interactionMemories(value) {
        this.#interactionMemories = value;
        value?.forEach((memory) => this.#pickerInputContext.interactionMemory.setMemory(memory));
    }
    #interactionMemories;
    #pickerInputContext;
    constructor() {
        super();
        this.#sorter = new UmbSorterController(this, {
            getUniqueOfElement: (element) => {
                return element.id;
            },
            getUniqueOfModel: (modelEntry) => {
                return modelEntry;
            },
            identifier: 'Umb.SorterIdentifier.InputDocument',
            itemSelector: 'umb-entity-item-ref',
            containerSelector: 'uui-ref-list',
            onChange: ({ model }) => {
                this.selection = model;
                this.dispatchEvent(new UmbChangeEvent());
            },
        });
        /**
         * Min validation message.
         * @type {boolean}
         * @attr
         * @default
         */
        this.minMessage = 'This field needs more items';
        /**
         * Max validation message.
         * @type {boolean}
         * @attr
         * @default
         */
        this.maxMessage = 'This field exceeds the allowed amount of items';
        this.includeTrashed = false;
        this.#readonly = false;
        this.required = false;
        this.requiredMessage = UMB_VALIDATION_EMPTY_LOCALIZATION_KEY;
        this.#interactionMemories = [];
        this.#pickerInputContext = new UmbDocumentPickerInputContext(this);
        this.addValidator('valueMissing', () => this.requiredMessage, () => !this.readonly && this.required && this.selection.length === 0);
        this.addValidator('rangeUnderflow', () => this.minMessage, () => !this.readonly && !!this.min && this.selection.length < this.min);
        this.addValidator('rangeOverflow', () => this.maxMessage, () => !this.readonly && !!this.max && this.selection.length > this.max);
        this.observe(this.#pickerInputContext.selection, (selection) => (this.value = selection.join(',')), '_observeSelection');
        this.observe(this.#pickerInputContext.selectedItems, (selectedItems) => (this._items = selectedItems), '_observerItems');
        this.observe(this.#pickerInputContext.statuses, (statuses) => (this._statuses = statuses), '_observerStatuses');
        this.observe(this.#pickerInputContext.interactionMemory.memories, (memories) => {
            // only dispatch the event if the interaction memories have actually changed
            const isIdentical = jsonStringComparison(memories, this.#interactionMemories);
            if (!isIdentical) {
                this.#interactionMemories = memories;
                this.dispatchEvent(new UmbInteractionMemoriesChangeEvent());
            }
        }, '_observeMemories');
    }
    #openPicker() {
        this.#pickerInputContext.openPicker({
            hideTreeRoot: true,
            startNode: this.startNode,
        }, {
            allowedContentTypes: this.allowedContentTypeIds?.map((id) => ({
                unique: id,
                entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE,
            })),
            includeTrashed: this.includeTrashed,
        });
    }
    #onRemove(unique) {
        this.#pickerInputContext.requestRemoveItem(unique);
    }
    render() {
        return html `${this.#renderItems()} ${this.#renderAddButton()}`;
    }
    #renderAddButton() {
        if (this.selection.length > 0 && this.max === 1)
            return nothing;
        if (this.readonly && this.selection.length > 0) {
            return nothing;
        }
        else {
            return html `
				<uui-button
					id="btn-add"
					look="placeholder"
					@click=${this.#openPicker}
					label=${this.localize.term('general_choose')}
					?disabled=${this.readonly}></uui-button>
			`;
        }
    }
    #renderItems() {
        if (!this._statuses)
            return;
        return html `
			<uui-ref-list>
				${repeat(this._statuses, (status) => status.unique, (status) => {
            const unique = status.unique;
            const item = this._items?.find((x) => x.unique === unique);
            const isError = status.state.type === 'error';
            return html `
							<umb-entity-item-ref
								id=${unique}
								.item=${item}
								?error=${isError}
								.errorMessage=${status.state.error}
								.errorDetail=${isError ? unique : undefined}
								?readonly=${this.readonly}
								?standalone=${this.max === 1}>
								${when(!this.readonly, () => html `
										<uui-action-bar slot="actions">
											<uui-button
												label=${this.localize.term('general_remove')}
												@click=${() => this.#onRemove(unique)}></uui-button>
										</uui-action-bar>
									`)}
							</umb-entity-item-ref>
						`;
        })}
			</uui-ref-list>
		`;
    }
    static { this.styles = [
        css `
			uui-ref-list:not(:has(:nth-child(1))) {
				margin-top: -20px;
				padding-top: 20px;
			}

			#btn-add {
				display: block;
			}
		`,
    ]; }
};
__decorate([
    property({ type: Number })
], UmbInputDocumentElement.prototype, "min", null);
__decorate([
    property({ type: String, attribute: 'min-message' })
], UmbInputDocumentElement.prototype, "minMessage", void 0);
__decorate([
    property({ type: Number })
], UmbInputDocumentElement.prototype, "max", null);
__decorate([
    property({ type: String, attribute: 'max-message' })
], UmbInputDocumentElement.prototype, "maxMessage", void 0);
__decorate([
    property({ type: Object, attribute: false })
], UmbInputDocumentElement.prototype, "startNode", void 0);
__decorate([
    property({ type: Array })
], UmbInputDocumentElement.prototype, "allowedContentTypeIds", void 0);
__decorate([
    property({ type: Boolean, attribute: 'include-trashed' })
], UmbInputDocumentElement.prototype, "includeTrashed", void 0);
__decorate([
    property({ type: String })
], UmbInputDocumentElement.prototype, "value", null);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbInputDocumentElement.prototype, "readonly", null);
__decorate([
    property({ type: Boolean })
], UmbInputDocumentElement.prototype, "required", void 0);
__decorate([
    property({ type: String })
], UmbInputDocumentElement.prototype, "requiredMessage", void 0);
__decorate([
    property({ type: Array, attribute: false })
], UmbInputDocumentElement.prototype, "interactionMemories", null);
__decorate([
    state()
], UmbInputDocumentElement.prototype, "_items", void 0);
__decorate([
    state()
], UmbInputDocumentElement.prototype, "_statuses", void 0);
UmbInputDocumentElement = __decorate([
    customElement('umb-input-document')
], UmbInputDocumentElement);
export { UmbInputDocumentElement };
export { UmbInputDocumentElement as element };
