import { UmbControllerBase } from '../../../../libs/class-api/index.js';
import { extractJsonQueryProps } from '../../../core/validation/index.js';
import { UmbVariantId } from '../../../core/variant/index.js';
/*
 * @internal
 * @module UmbContentValidationToHintsManager
 * @description
 * This manager observes the content type structure and validation messages, converting them into hints.
 * It is designed to be used in a content workspace to provide real-time feedback on content validation.
 */
export class UmbContentValidationToHintsManager extends UmbControllerBase {
    /*workspace.hints.addOne({
        unique: 'exampleHintFromToggleAction',
        path: ['Umb.WorkspaceView.Document.Edit'],
        text: 'Hi',
        color: 'invalid',
        weight: 100,
    });

    TODO:
    * Maintaine structural awareness of all Properties.
    * Observe validation messages for all Properties, and turn them into Hints as fitting.
    */
    #hintedMsgs = new Set();
    #containers = [];
    constructor(host, structure, validation, hints, hintsPathPrefix = ['Umb.WorkspaceView.Document.Edit']) {
        super(host);
        this.observe(structure.contentTypeMergedContainers, (merged) => {
            this.#containers = merged;
        });
        this.observe(validation.messages.messagesOfPathAndDescendant('$.values'), (messages) => {
            messages.forEach((message) => {
                if (this.#hintedMsgs.has(message.key))
                    return;
                // Get the value between [ and ] of message.path:
                const query = getValueBetweenBrackets(message.path);
                if (!query)
                    return;
                const queryProps = extractJsonQueryProps(query);
                const alias = queryProps.alias;
                const variantId = UmbVariantId.CreateFromPartial(queryProps);
                structure.getPropertyStructureByAlias(alias).then((property) => {
                    if (!property)
                        return;
                    let path = [];
                    if (property.container) {
                        const container = this.#containers.find((c) => c.ids.includes(property.container.id));
                        if (container) {
                            path = container.path;
                        }
                        else {
                            throw new Error(`Could not find the declared container of id "${property.container.id}" for property with alias: "${property.alias}"`);
                        }
                    }
                    hints.addOne({
                        unique: message.key,
                        path: [...hintsPathPrefix, ...path],
                        text: '!',
                        /*label: message.body,*/
                        color: 'invalid',
                        weight: 1000,
                        variantId,
                    });
                    this.#hintedMsgs.add(message.key);
                });
            });
            this.#hintedMsgs.forEach((key) => {
                if (!messages.some((msg) => msg.key === key)) {
                    this.#hintedMsgs.delete(key);
                    hints.removeOne(key);
                }
            });
        });
    }
}
/**
 *
 * @param path {string} The path string to extract the value from.
 */
function getValueBetweenBrackets(path) {
    const start = path.indexOf('[');
    if (start === -1)
        return null;
    const end = path.indexOf(']', start + 1);
    if (end === -1)
        return null;
    return path.substring(start + 1, end);
}
