import { UmbElementWorkspaceDataManager } from './element-data-manager.js';
import { appendToFrozenArray, jsonStringComparison } from '../../../../libs/observable-api/index.js';
import { UmbVariantId, umbVariantObjectCompare } from '../../../core/variant/index.js';
export class UmbContentWorkspaceDataManager extends UmbElementWorkspaceDataManager {
    //
    //#repository;
    #variantScaffold;
    constructor(host, variantScaffold) {
        super(host);
        this.#variantScaffold = variantScaffold;
    }
    _sortCurrentData(persistedData, currentData) {
        currentData = super._sortCurrentData(persistedData, currentData);
        // Sort the variants in the same order as the persisted data:
        const persistedVariants = persistedData.variants;
        if (persistedVariants && currentData.variants) {
            return {
                ...currentData,
                variants: [...currentData.variants].sort(function (a, b) {
                    return (persistedVariants.findIndex((x) => umbVariantObjectCompare(x, a)) -
                        persistedVariants.findIndex((x) => umbVariantObjectCompare(x, b)));
                }),
            };
        }
        return currentData;
    }
    /**
     * Sets the variant scaffold data
     * @param {ModelVariantType} variantScaffold The variant scaffold data
     * @memberof UmbContentWorkspaceDataManager
     */
    setVariantScaffold(variantScaffold) {
        this.#variantScaffold = variantScaffold;
    }
    ensureVariantData(variantId) {
        this.updateVariantData(variantId);
    }
    ensureVariantsData(variantIds) {
        this.initiatePropertyValueChange();
        for (const variantId of variantIds) {
            this.updateVariantData(variantId);
        }
        this.finishPropertyValueChange();
    }
    updateVariantData(variantId, update) {
        if (!this.#variantScaffold)
            throw new Error('Variant scaffold data is missing');
        if (this._variesByCulture === true) {
            // If variant Id is invariant, we don't to have the variant appended to our data.
            if (variantId.isInvariant()) {
                return;
            }
            this.#updateVariantData(variantId, update);
            return;
        }
        if (this._variesBySegment === true) {
            // When varying by segment we need to handle the "unsegmented" variant as invariant.
            // The rest of the segmented variants will be handled as normal variant data.
            if (variantId.isInvariant()) {
                this.#updateInvariantData(update);
            }
            else {
                this.#updateVariantData(variantId, update);
            }
            return;
        }
        if (this._varies === false) {
            this.#updateInvariantData(update);
            return;
        }
        throw new Error('Varies by culture is missing');
    }
    #updateVariantData(variantId, update) {
        const currentData = this.getCurrent();
        if (!currentData)
            throw new Error('Data is missing');
        // If varies by segment:
        if (!variantId.isSegmentInvariant()) {
            // The server requires a segment name. It doesn't matter what it is as long as it is not empty. The server will overwrite it with the name of the default.
            update = { ...update, name: 'Segment' };
        }
        const variant = currentData.variants.find((x) => variantId.compare(x));
        const newVariants = appendToFrozenArray(currentData.variants, {
            ...this.#variantScaffold,
            ...variantId.toObject(),
            ...variant,
            ...update,
        }, (x) => variantId.compare(x));
        this.updateCurrent({ variants: newVariants });
    }
    #updateInvariantData(update) {
        const currentData = this.getCurrent();
        if (!currentData)
            throw new Error('Data is missing');
        const invariantVariantId = UmbVariantId.CreateInvariant();
        const variant = currentData.variants.find((x) => invariantVariantId.compare(x));
        // Cause we are invariant, we will just overwrite all variants with this one:
        const newVariants = [
            {
                ...this.#variantScaffold,
                ...invariantVariantId.toObject(),
                ...variant,
                ...update,
            },
        ];
        this.updateCurrent({ variants: newVariants });
    }
    getChangedVariants() {
        const persisted = this.getPersisted();
        const current = this.getCurrent();
        if (!current)
            throw new Error('Current data is missing');
        const changedVariants = current?.variants.map((variant) => {
            const persistedVariant = persisted?.variants.find((x) => UmbVariantId.Create(variant).compare(x));
            return {
                culture: variant.culture,
                segment: variant.segment,
                equal: persistedVariant ? jsonStringComparison(variant, persistedVariant) : false,
            };
        });
        const changedProperties = current?.values.map((value) => {
            const persistedValues = persisted?.values.find((x) => UmbVariantId.Create(value).compare(x));
            return {
                culture: value.culture,
                segment: value.segment,
                equal: persistedValues ? jsonStringComparison(value, persistedValues) : false,
            };
        });
        // calculate the variantIds of those who either have a change in properties or in variants:
        return (changedVariants
            ?.concat(changedProperties ?? [])
            .filter((x) => x.equal === false)
            .map((x) => new UmbVariantId(x.culture, x.segment)) ?? []);
    }
}
