import { UMB_PROPERTY_CONTEXT } from '../../../../../core/property/index.js';
import { UmbSubmittableWorkspaceContextBase, UmbInvariantWorkspacePropertyDatasetContext, umbObjectToPropertyValueArray, } from '../../../../../core/workspace/index.js';
import { UmbArrayState, UmbObjectState, appendToFrozenArray } from '../../../../../../libs/observable-api/index.js';
import { UmbContextToken } from '../../../../../../libs/context-api/index.js';
import { UmbId } from '../../../../../core/id/index.js';
import { firstValueFrom } from '../../../../../../external/rxjs/index.js';
export class UmbBlockGridAreaTypeWorkspaceContext extends UmbSubmittableWorkspaceContextBase {
    #entityType;
    #data;
    async getValues() {
        return umbObjectToPropertyValueArray(await firstValueFrom(this.data));
    }
    #properties;
    constructor(host, workspaceArgs) {
        super(host, workspaceArgs.manifest.alias);
        // Just for context token safety:
        this.IS_BLOCK_GRID_AREA_TYPE_WORKSPACE_CONTEXT = true;
        this.#data = new UmbObjectState(undefined);
        this.data = this.#data.asObservable();
        this.values = this.#data.asObservablePart((data) => {
            return umbObjectToPropertyValueArray(data);
        });
        // TODO: Get the name of the contentElementType..
        this.name = this.#data.asObservablePart((data) => data?.alias);
        this.unique = this.#data.asObservablePart((data) => data?.key);
        this.#properties = new UmbArrayState([], (x) => x.alias);
        this.properties = this.#properties.asObservable();
        this.#entityType = workspaceArgs.manifest.meta?.entityType;
    }
    set manifest(manifest) {
        this.routes.setRoutes([
            {
                path: 'edit/:id',
                component: () => import('./block-grid-area-type-workspace-editor.element.js'),
                setup: (component, info) => {
                    const id = info.match.params.id;
                    this.load(id);
                },
            },
            {
                path: 'create',
                component: () => import('./block-grid-area-type-workspace-editor.element.js'),
                setup: () => {
                    this.create();
                },
            },
        ]);
    }
    resetState() {
        super.resetState();
        this.#data.setValue(undefined);
    }
    createPropertyDatasetContext(host) {
        return new UmbInvariantWorkspacePropertyDatasetContext(host, this);
    }
    async load(unique) {
        this.resetState();
        this.consumeContext(UMB_PROPERTY_CONTEXT, (context) => {
            this.observe(context?.value, (value) => {
                if (value) {
                    const blockTypeData = value.find((x) => x.key === unique);
                    if (blockTypeData) {
                        this.#data.setValue(blockTypeData);
                        return;
                    }
                }
                // Fallback to undefined:
                this.#data.setValue(undefined);
            }, 'observePropertyValue');
        });
    }
    async create() {
        this.resetState();
        let data = {
            key: UmbId.new(),
            alias: '',
            columnSpan: 12,
            rowSpan: 1,
            minAllowed: 0,
            maxAllowed: undefined,
            specifiedAllowance: [],
        };
        // If we have a modal context, we blend in the modal preset data: [NL]
        if (this.modalContext) {
            data = { ...data, ...this.modalContext.data.preset };
        }
        this.setIsNew(true);
        this.#data.setValue(data);
    }
    getData() {
        return this.#data.getValue();
    }
    getUnique() {
        return this.getData().key;
    }
    getEntityType() {
        return this.#entityType;
    }
    getName() {
        return this.#data.getValue()?.alias;
    }
    setName(name) {
        throw new Error(`You cannot set a name of an area-type to "${name}".`);
    }
    /**
     * @function propertyValueByAlias
     * @param {string} propertyAlias
     * @returns {Promise<Observable<ReturnType | undefined> | undefined>}
     * @description Get an Observable for the value of this property.
     */
    async propertyValueByAlias(propertyAlias) {
        return this.#data.asObservablePart((data) => data?.[propertyAlias]);
    }
    getPropertyValue(propertyAlias) {
        return this.#data.getValue()?.[propertyAlias];
    }
    /**
     * @function setPropertyValue
     * @param {string} alias
     * @param {unknown} value - value can be a promise resolving into the actual value or the raw value it self.
     * @returns {Promise<void>}
     * @description Set the value of this property.
     */
    async setPropertyValue(alias, value) {
        const currentData = this.#data.value;
        if (currentData) {
            this.#data.update({ ...currentData, [alias]: value });
        }
    }
    async submit() {
        if (!this.#data.value) {
            throw new Error('No data to submit.');
        }
        const context = await this.getContext(UMB_PROPERTY_CONTEXT);
        if (!context) {
            throw new Error('Property context not found.');
        }
        // TODO: We should most likely consume already, in this way I avoid having the reset this consumption.
        context.setValue(appendToFrozenArray(context.getValue() ?? [], this.#data.getValue(), (x) => x?.key));
        this.setIsNew(false);
    }
    destroy() {
        this.#data.destroy();
        super.destroy();
    }
}
export default UmbBlockGridAreaTypeWorkspaceContext;
export const UMB_BLOCK_GRID_AREA_TYPE_WORKSPACE_CONTEXT = new UmbContextToken('UmbWorkspaceContext', undefined, (context) => context.IS_BLOCK_GRID_AREA_TYPE_WORKSPACE_CONTEXT);
