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 { UMB_DOCUMENT_PROPERTY_VALUE_USER_PERMISSION_FLOW_MODAL } from '../document-property-value-permission-flow-modal/index.js';
import { UMB_DOCUMENT_PROPERTY_VALUE_USER_PERMISSION_TYPE } from '../user-permission.js';
import { UMB_DOCUMENT_PROPERTY_VALUE_ENTITY_TYPE } from '../../../entity.js';
import { css, customElement, html, ifDefined, nothing, property, repeat, state, } from '../../../../../../external/lit/index.js';
import { UmbLitElement } from '../../../../../core/lit-element/index.js';
import { UMB_MODAL_MANAGER_CONTEXT } from '../../../../../core/modal/index.js';
import { umbExtensionsRegistry } from '../../../../../core/extension-registry/index.js';
import { UUIFormControlMixin } from '../../../../../../external/uui/index.js';
import { UMB_ENTITY_USER_PERMISSION_MODAL, } from '../../../../../user/user-permission/index.js';
import { UmbDocumentTypeDetailRepository, } from '../../../../document-types/index.js';
import { UmbChangeEvent } from '../../../../../core/event/index.js';
let UmbInputDocumentPropertyValueUserPermissionElement = class UmbInputDocumentPropertyValueUserPermissionElement extends UUIFormControlMixin(UmbLitElement, '') {
    constructor() {
        super(...arguments);
        this.#permissions = [];
        this.fallbackPermissions = [];
        this.#documentTypeDetailRepository = new UmbDocumentTypeDetailRepository(this);
    }
    #permissions;
    get permissions() {
        return this.#permissions;
    }
    set permissions(value) {
        this.#permissions = value;
        const uniques = value.map((item) => item.documentType.unique);
        this.#observePickedDocumentTypes(uniques);
    }
    #documentTypeDetailRepository;
    getFormElement() {
        return undefined;
    }
    async #observePickedDocumentTypes(uniques) {
        const promises = uniques.map((unique) => this.#documentTypeDetailRepository.requestByUnique(unique));
        const responses = await Promise.allSettled(promises);
        // TODO: handle errors
        this._documentTypes = responses
            .filter((response) => response.status === 'fulfilled')
            .map((response) => response.value.data)
            .filter((item) => item);
    }
    async #addPermission() {
        const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
        if (!modalManager) {
            throw new Error('Could not open modal, no modal manager found');
        }
        const modal = modalManager.open(this, UMB_DOCUMENT_PROPERTY_VALUE_USER_PERMISSION_FLOW_MODAL, {
            data: {
                preset: {
                    verbs: this.#getFallbackPermissionVerbsForEntityType(UMB_DOCUMENT_PROPERTY_VALUE_ENTITY_TYPE),
                },
                pickablePropertyTypeFilter: (propertyType) => !this.#permissions.some((permission) => permission.propertyType.unique === propertyType.unique),
            },
        });
        try {
            const value = await modal?.onSubmit();
            if (!value)
                throw new Error('No result from modal');
            const permissionItem = {
                $type: 'DocumentPropertyValuePermissionPresentationModel',
                userPermissionType: UMB_DOCUMENT_PROPERTY_VALUE_USER_PERMISSION_TYPE,
                documentType: value.documentType,
                propertyType: value.propertyType,
                verbs: value.verbs,
            };
            this.permissions = [...this.#permissions, permissionItem];
            this.dispatchEvent(new UmbChangeEvent());
        }
        catch (error) {
            console.error(error);
        }
    }
    async #editPermission(currentPermission) {
        if (!currentPermission) {
            throw new Error('Could not open permissions modal, no item was provided');
        }
        const documentType = this._documentTypes?.find((item) => item.unique === currentPermission.documentType.unique);
        if (!documentType) {
            throw new Error('Could not open permissions modal, no document type was found');
        }
        // TODO: show document type and property type name
        const headline = `Permissions`;
        const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
        if (!modalManager) {
            throw new Error('Could not open permissions modal, modal manager is not available');
        }
        const modal = modalManager.open(this, UMB_ENTITY_USER_PERMISSION_MODAL, {
            data: {
                entityType: UMB_DOCUMENT_PROPERTY_VALUE_ENTITY_TYPE,
                headline,
                preset: {
                    allowedVerbs: currentPermission.verbs,
                },
            },
        });
        try {
            const value = await modal.onSubmit();
            // don't do anything if the verbs have not been updated
            if (JSON.stringify(value.allowedVerbs) === JSON.stringify(currentPermission.verbs))
                return;
            // update permission with new verbs
            this.permissions = this.#permissions.map((permission) => {
                if (permission.propertyType.unique === currentPermission.propertyType.unique) {
                    return {
                        ...permission,
                        verbs: value.allowedVerbs,
                    };
                }
                return permission;
            });
            this.dispatchEvent(new UmbChangeEvent());
        }
        catch (error) {
            console.error(error);
        }
    }
    #removePermission(permission) {
        this.permissions = this.#permissions.filter((v) => JSON.stringify(v) !== JSON.stringify(permission));
        this.dispatchEvent(new UmbChangeEvent());
    }
    #getVerbNamesForPermission(permission) {
        if (!permission) {
            throw new Error('Could not find permission for property type');
        }
        if (permission.verbs.length === 0) {
            return this.localize.term('user_permissionNoVerbs');
        }
        return umbExtensionsRegistry
            .getByTypeAndFilter('entityUserPermission', (manifest) => manifest.meta.verbs.every((verb) => permission.verbs.includes(verb)))
            .map((m) => {
            const manifest = m;
            return manifest.meta.label ? this.localize.string(manifest.meta.label) : manifest.name;
        })
            .join(', ');
    }
    #getFallbackPermissionVerbsForEntityType(entityType) {
        // get all permissions that are allowed for the entity type and have at least one of the fallback permissions
        // this is used to determine the default permissions for a document
        const verbs = umbExtensionsRegistry
            .getByTypeAndFilter('entityUserPermission', (manifest) => manifest.forEntityTypes.includes(entityType) &&
            this.fallbackPermissions.map((verb) => manifest.meta.verbs.includes(verb)).includes(true))
            .flatMap((permission) => permission.meta.verbs);
        // ensure that the verbs are unique
        return [...new Set([...verbs])];
    }
    render() {
        return html `${this.#renderItems()} ${this.#renderAddButton()}`;
    }
    #renderItems() {
        if (!this.permissions)
            return;
        return html `
			<uui-ref-list>
				${repeat(this.permissions, (item) => item.propertyType.unique, (item) => this.#renderRef(item))}
			</uui-ref-list>
		`;
    }
    #renderAddButton() {
        return html `<uui-button
			id="btn-add"
			look="placeholder"
			@click=${this.#addPermission}
			label=${this.localize.term('general_add')}></uui-button>`;
    }
    #renderRef(permission) {
        if (!permission.propertyType.unique) {
            throw new Error('Property type unique is required');
        }
        const documentType = this._documentTypes?.find((item) => item.unique === permission.documentType.unique);
        const propertyType = documentType?.properties.find((item) => item.unique === permission.propertyType.unique);
        const permissionName = `${this.localize.string(documentType?.name)}: ${this.localize.string(propertyType?.name)} (${propertyType?.alias})`;
        const verbNames = this.#getVerbNamesForPermission(permission);
        return html `
			<uui-ref-node .name=${permissionName} .detail=${verbNames || ''} readonly>
				${documentType?.icon ? html `<uui-icon slot="icon" name=${ifDefined(documentType?.icon)}></uui-icon>` : nothing}
				<uui-action-bar slot="actions"
					>${this.#renderEditButton(permission)} ${this.#renderRemoveButton(permission)}</uui-action-bar
				>
			</uui-ref-node>
		`;
    }
    #renderEditButton(permission) {
        return html `<uui-button
			@click=${() => this.#editPermission(permission)}
			label=${this.localize.term('general_edit')}></uui-button>`;
    }
    #renderRemoveButton(permission) {
        return html `<uui-button
			@click=${() => this.#removePermission(permission)}
			label=${this.localize.term('general_remove')}></uui-button>`;
    }
    static { this.styles = [
        css `
			#btn-add {
				width: 100%;
			}
		`,
    ]; }
};
__decorate([
    property({ type: Array, attribute: false })
], UmbInputDocumentPropertyValueUserPermissionElement.prototype, "fallbackPermissions", void 0);
__decorate([
    state()
], UmbInputDocumentPropertyValueUserPermissionElement.prototype, "_documentTypes", void 0);
UmbInputDocumentPropertyValueUserPermissionElement = __decorate([
    customElement('umb-input-document-property-value-user-permission')
], UmbInputDocumentPropertyValueUserPermissionElement);
export { UmbInputDocumentPropertyValueUserPermissionElement };
export { UmbInputDocumentPropertyValueUserPermissionElement as element };
