import { UmbExpansionEntryExpandedEvent, UmbExpansionEntryCollapsedEvent, UmbExpansionChangeEvent, } from './events/index.js';
import { UmbControllerBase } from '../../../../libs/class-api/index.js';
import { UmbArrayState } from '../../../../libs/observable-api/index.js';
/**
 * Manages an expansion state
 * @exports
 * @class UmbEntityExpansionManager
 * @augments {UmbControllerBase}
 */
export class UmbEntityExpansionManager extends UmbControllerBase {
    constructor() {
        super(...arguments);
        this._expansion = new UmbArrayState([], (x) => x.entityType + x.unique);
        this.expansion = this._expansion.asObservable();
    }
    /**
     * Checks if an entity is expanded
     * @param {EntryModelType} entity The entity to check
     * @returns {Observable<boolean>} True if the entity is expanded
     * @memberof UmbEntityExpansionManager
     */
    isExpanded(entity) {
        return this._expansion.asObservablePart((entries) => entries?.some((entry) => entry.entityType === entity.entityType && entry.unique === entity.unique));
    }
    /**
     * Observe the expansion entry for a specific entity
     * @param {EntryModelType} entity The entity to observe
     * @returns {Observable<EntryModelType | undefined>} An observable of the expansion entry
     * @memberof UmbEntityExpansionManager
     */
    entry(entity) {
        return this._expansion.asObservablePart((entries) => entries?.find((entry) => entry.entityType === entity.entityType && entry.unique === entity.unique));
    }
    /**
     * Sets the expansion state
     * @param {UmbEntityExpansionModel<EntryModelType> | undefined} expansion The expansion state
     * @memberof UmbEntityExpansionManager
     * @returns {void}
     */
    setExpansion(expansion) {
        this._expansion.setValue(expansion);
        this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent());
    }
    /**
     * Gets the expansion state
     * @memberof UmbEntityExpansionManager
     * @returns {UmbEntityExpansionModel} The expansion state
     */
    getExpansion() {
        return this._expansion.getValue();
    }
    /**
     * Expands an entity
     * @param {EntryModelType} entity The entity to open
     * @memberof UmbEntityExpansionManager
     * @returns {Promise<void>}
     */
    async expandItem(entity) {
        this._expansion.appendOne(entity);
        this.getHostElement()?.dispatchEvent(new UmbExpansionEntryExpandedEvent(entity));
        this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent());
    }
    /**
     * Expands multiple entities
     * @param {UmbEntityExpansionModel<EntryModelType>} entities The entities to open
     * @memberof UmbEntityExpansionManager
     * @returns {void}
     */
    expandItems(entities) {
        if (!entities || entities.length === 0)
            return;
        this._expansion.append(entities);
        entities.forEach((entity) => {
            this.getHostElement()?.dispatchEvent(new UmbExpansionEntryExpandedEvent(entity));
        });
        this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent());
    }
    /**
     * Collapses an entity
     * @param {EntryModelType} entry The entity to open
     * @memberof UmbEntityExpansionManager
     * @returns {Promise<void>}
     */
    async collapseItem(entry) {
        this._expansion.filter((x) => x.entityType !== entry.entityType || x.unique !== entry.unique);
        this.getHostElement()?.dispatchEvent(new UmbExpansionEntryCollapsedEvent(entry));
        this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent());
    }
    /**
     * Collapses multiple entities
     * @param {UmbEntityExpansionModel<EntryModelType>} entries The entities to close
     * @memberof UmbEntityExpansionManager
     * @returns {void}
     */
    collapseItems(entries) {
        if (!entries || entries.length === 0)
            return;
        this._expansion.filter((x) => !entries.some((entry) => entry.entityType === x.entityType && entry.unique === x.unique));
        entries.forEach((entry) => {
            this.getHostElement()?.dispatchEvent(new UmbExpansionEntryCollapsedEvent(entry));
        });
        this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent());
    }
    /**
     * Collapses all expanded entities
     * @memberof UmbEntityExpansionManager
     * @returns {Promise<void>}
     */
    async collapseAll() {
        this._expansion.setValue([]);
        this.getHostElement()?.dispatchEvent(new UmbExpansionChangeEvent());
    }
    /**
     * Gets an item from the expansion state
     * @param {EntryModelType} entity The entity to get
     * @returns {*}  {(Promise<UmbEntityExpansionEntryModel | undefined>)}
     * @memberof UmbEntityExpansionManager
     */
    async getItem(entity) {
        const expansion = this._expansion.getValue();
        return expansion.find((x) => x.entityType === entity.entityType && x.unique === entity.unique);
    }
}
