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 { property, state } from '../../../../external/lit/index.js';
import { UmbLitElement } from '../../lit-element/index.js';
import { UmbExtensionsElementInitializer } from '../../../../libs/extension-api/index.js';
import { umbExtensionsRegistry } from '../../extension-registry/index.js';
import { UmbDeselectedEvent, UmbSelectedEvent } from '../../event/index.js';
import { UmbRoutePathAddendumContext } from '../../router/index.js';
import { UMB_MARK_ATTRIBUTE_NAME } from '../../const/index.js';
import { UmbEntityContext, UMB_ENTITY_CONTEXT } from '../../entity/index.js';
import { UmbContextBoundaryController } from '../../../../libs/context-api/index.js';
export class UmbEntityCollectionItemElementBase extends UmbLitElement {
    constructor() {
        super();
        // Prevent any outer/ancestor UMB_ENTITY_CONTEXT from leaking into this collection item.
        // Each item provides its own entity context, and consumers inside should never
        // accidentally receive a context from an ancestor or sibling before this item supplies its own.
        new UmbContextBoundaryController(this, UMB_ENTITY_CONTEXT);
    }
    #extensionsController;
    #entityContext;
    #item;
    set item(value) {
        const oldValue = this.#item;
        this.#item = value;
        if (value === oldValue)
            return;
        if (!value)
            return;
        // If the component is already created and the entity type is the same, we can just update the item.
        if (this._component && value.entityType === oldValue?.entityType) {
            this._component.item = value;
            this.#entityContext?.setUnique(value.unique ?? null);
            this.#pathAddendum.setAddendum(this.getPathAddendum(value.entityType, value.unique));
            return;
        }
        this.#pathAddendum.setAddendum(this.getPathAddendum(value.entityType, value.unique));
        // If the component is already created, but the entity type is different, we need to destroy the component.
        this.#createController(value.entityType);
    }
    get item() {
        return this.#item;
    }
    #selectable = false;
    get selectable() {
        return this.#selectable;
    }
    set selectable(value) {
        this.#selectable = value;
        if (this._component) {
            this._component.selectable = this.#selectable;
        }
    }
    #selectOnly = false;
    get selectOnly() {
        return this.#selectOnly;
    }
    set selectOnly(value) {
        this.#selectOnly = value;
        if (this._component) {
            this._component.selectOnly = this.#selectOnly;
        }
    }
    #selected = false;
    get selected() {
        return this.#selected;
    }
    set selected(value) {
        this.#selected = value;
        if (this._component) {
            this._component.selected = this.#selected;
        }
    }
    #disabled = false;
    get disabled() {
        return this.#disabled;
    }
    set disabled(value) {
        this.#disabled = value;
        if (this._component) {
            this._component.disabled = this.#disabled;
        }
    }
    #href;
    get href() {
        return this.#href;
    }
    set href(value) {
        this.#href = value;
        if (this._component) {
            this._component.href = this.#href;
        }
    }
    #detailProperties;
    get detailProperties() {
        return this.#detailProperties;
    }
    set detailProperties(value) {
        this.#detailProperties = value;
        if (this._component) {
            this._component.detailProperties = this.#detailProperties;
        }
    }
    #pathAddendum = new UmbRoutePathAddendumContext(this);
    #onSelected(event) {
        event.stopPropagation();
        const unique = this.item?.unique;
        if (!unique)
            throw new Error('No unique id found for item');
        this.dispatchEvent(new UmbSelectedEvent(unique));
    }
    #onDeselected(event) {
        event.stopPropagation();
        const unique = this.item?.unique;
        if (!unique)
            throw new Error('No unique id found for item');
        this.dispatchEvent(new UmbDeselectedEvent(unique));
    }
    firstUpdated(_changedProperties) {
        super.firstUpdated(_changedProperties);
        this.setAttribute(UMB_MARK_ATTRIBUTE_NAME, this.getMarkAttributeName());
    }
    #boundOnSelected = this.#onSelected.bind(this);
    #boundOnDeselected = this.#onDeselected.bind(this);
    #createController(entityType) {
        if (this.#extensionsController) {
            this.#extensionsController.destroy();
        }
        this.#entityContext?.destroy();
        this.#entityContext = undefined;
        this.#extensionsController = new UmbExtensionsElementInitializer(this, umbExtensionsRegistry, this.getExtensionType(), (manifest) => manifest.forEntityTypes.includes(entityType), (extensionControllers) => {
            this._component?.remove();
            const component = extensionControllers[0]?.component || this.createFallbackElement();
            this.#entityContext = new UmbEntityContext(component);
            this.#entityContext.setEntityType(entityType);
            this.#entityContext.setUnique(this.item?.unique ?? null);
            // TODO: I would say this code can use feature of the UmbExtensionsElementInitializer, to set properties and get a fallback element. [NL]
            // assign the properties to the component
            component.item = this.item;
            component.selectable = this.selectable;
            component.selectOnly = this.selectOnly;
            component.selected = this.selected;
            component.disabled = this.disabled;
            component.href = this.href;
            component.detailProperties = this.detailProperties;
            component.addEventListener(UmbSelectedEvent.TYPE, this.#boundOnSelected);
            component.addEventListener(UmbDeselectedEvent.TYPE, this.#boundOnDeselected);
            // Proxy the actions slot to the component
            const slotElement = document.createElement('slot');
            slotElement.name = 'actions';
            slotElement.setAttribute('slot', 'actions');
            component.appendChild(slotElement);
            this._component = component;
        }, undefined, // We can leave the alias to undefined, as we destroy this ourselves.
        undefined, { single: true });
    }
    destroy() {
        this._component?.removeEventListener(UmbSelectedEvent.TYPE, this.#boundOnSelected);
        this._component?.removeEventListener(UmbDeselectedEvent.TYPE, this.#boundOnDeselected);
        this.#entityContext?.destroy();
        this.#entityContext = undefined;
        super.destroy();
    }
}
__decorate([
    state()
], UmbEntityCollectionItemElementBase.prototype, "_component", void 0);
__decorate([
    property({ type: Object, attribute: false })
], UmbEntityCollectionItemElementBase.prototype, "item", null);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbEntityCollectionItemElementBase.prototype, "selectable", null);
__decorate([
    property({ type: Boolean, attribute: 'select-only', reflect: true })
], UmbEntityCollectionItemElementBase.prototype, "selectOnly", null);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbEntityCollectionItemElementBase.prototype, "selected", null);
__decorate([
    property({ type: Boolean, reflect: true })
], UmbEntityCollectionItemElementBase.prototype, "disabled", null);
__decorate([
    property({ type: String, reflect: true })
], UmbEntityCollectionItemElementBase.prototype, "href", null);
__decorate([
    property({ type: Array, attribute: false })
], UmbEntityCollectionItemElementBase.prototype, "detailProperties", null);
