import { State as CoreState } from "@intelligentgraphics/ig.gfx.core";
import * as MultiArticle from "@intelligentgraphics/ig.gfx.multiarticle";
import { Associates, NeighborType, WorldLocalConverter, } from "@intelligentgraphics/ig.gfx.planning";
export const findMultiArticleConfiguration = (session, comId) => {
    const article = session.getArticleByComId(comId);
    const multiArticles = session.getMultiArticlesForComId(comId);
    if (!multiArticles) {
        return;
    }
    return getMultiArticleConfiguration(multiArticles, article.articleId, article.articleNumber === undefined
        ? undefined
        : article.articleNumber.baseArticleNumber);
};
export const getMultiArticleConfiguration = (multiArticles, ...articleIds) => {
    for (const articleId of articleIds) {
        if (articleId === undefined) {
            continue;
        }
        const configuration = multiArticles.getConfiguration(articleId);
        if (configuration !== undefined &&
            Object.getOwnPropertyNames(configuration).length > 0) {
            return configuration;
        }
    }
    return {};
};
export const getMultiArticleActions = (multiArticles, ...articleIds) => {
    for (const articleId of articleIds) {
        if (articleId === undefined) {
            continue;
        }
        const actions = multiArticles.getActions(articleId);
        if (actions !== undefined && actions.length > 0) {
            return actions;
        }
    }
    return [];
};
export const getMultiArticleCategories = (multiArticles, ...articleIds) => {
    for (const articleId of articleIds) {
        if (articleId === undefined) {
            continue;
        }
        const categories = multiArticles.getCategories(articleId);
        if (categories !== undefined &&
            Object.getOwnPropertyNames(categories).length > 0) {
            return categories;
        }
    }
    return {};
};
export const getMultiArticleAttachPoints = (multiArticles, ...articleIds) => {
    for (const articleId of articleIds) {
        if (articleId === undefined) {
            continue;
        }
        const attachPoints = multiArticles.getAttachPoints(articleId);
        if (attachPoints !== undefined && attachPoints.length > 0) {
            return attachPoints;
        }
    }
    return [];
};
export const createMultiArticleHooks = (session) => {
    const generateActionConfiguration = (actions, comId, context) => {
        const multiArticles = session.getMultiArticlesForComId(comId);
        if (!multiArticles) {
            return;
        }
        const { configuration, gfxId, articleId } = session.getArticleByComId(comId);
        const hasLeftNeighbor = Boolean(Associates.neighbor(gfxId, NeighborType.Left));
        const hasRightNeighbor = Boolean(Associates.neighbor(gfxId, NeighborType.Right));
        const hasTopNeighbor = Boolean(Associates.neighbor(gfxId, NeighborType.Top));
        const hasBottomNeighbor = Boolean(Associates.neighbor(gfxId, NeighborType.Bottom));
        const converter = new WorldLocalConverter(context);
        const relativeSnapPosition = converter.toLocal(CoreState.API.GetPosition(gfxId));
        const additionalRuleParameters = MultiArticle.Rule.createAdditionalRuleParameters({
            context,
            hasLeftNeighbor,
            hasRightNeighbor,
            hasBottomNeighbor,
            hasTopNeighbor,
            relativeSnapPosition,
        });
        const maConfig = findMultiArticleConfiguration(session, comId);
        const properties = {
            ...configuration,
            ...maConfig,
            ...additionalRuleParameters,
        };
        const propertyValuePairs = actions.reduce((pairs, action) => {
            const evaluatedAction = MultiArticle.Rule.evalActionRule(action, properties);
            if (evaluatedAction.isActive &&
                evaluatedAction.property !== undefined &&
                configuration[evaluatedAction.property] !==
                    evaluatedAction.value) {
                pairs[evaluatedAction.property] = evaluatedAction.value;
            }
            return pairs;
        }, {});
        return propertyValuePairs;
    };
    const executeAction = (action, id, context) => executeActions([action], id, context);
    const executeActions = async (actions, gfxId, context) => {
        const item = session.getArticleByGfxId(gfxId);
        if (item === undefined) {
            throw new Error(`Could not find article instance for gfxId ${gfxId}. Not executing actions`);
        }
        const propertyValuePairs = generateActionConfiguration(actions, item.comId, context);
        if (propertyValuePairs !== undefined &&
            Object.getOwnPropertyNames(propertyValuePairs).length > 0) {
            await session.changeArticleProperties(item.comId, propertyValuePairs);
            return true;
        }
        return false;
    };
    return {
        generateActionConfiguration,
        executeAction,
        executeActions,
    };
};
