"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fdc3InternalApi = void 0;
const ApiBase_1 = require("../Implementation/ApiBase");
const fdc3_1 = require("@finos/fdc3");
const Fdc3Options_1 = require("../../AdaptableOptions/Fdc3Options");
const GeneralConstants_1 = require("../../Utilities/Constants/GeneralConstants");
const ActionColumnRenderer_1 = require("../../agGrid/ActionColumnRenderer");
class Fdc3InternalApi extends ApiBase_1.ApiBase {
    mapRowToContextData(contextType, rowNode) {
        var _a, _b, _c;
        if (contextType === 'fdc3.nothing') {
            return { type: contextType };
        }
        const mappedContextData = this.mapRowValueToContextData(rowNode, this.isStandardContextType(contextType) && contextType !== 'fdc3.nothing'
            ? (_a = this.getFdc3Options().gridDataContextMapping) === null || _a === void 0 ? void 0 : _a[contextType]
            : (_c = (_b = this.getFdc3Options().gridDataContextMapping) === null || _b === void 0 ? void 0 : _b.custom) === null || _c === void 0 ? void 0 : _c[contextType]);
        const contextMappedFromGridData = Object.assign({ type: contextType }, mappedContextData);
        const resolveContextDataFn = this.getFdc3Options().resolveContextData;
        if (typeof resolveContextDataFn === 'function') {
            return resolveContextDataFn(Object.assign(Object.assign({}, this.getAdaptableInternalApi().buildBaseContext()), { contextType,
                contextMappedFromGridData,
                rowNode, rowData: rowNode.data, primaryKeyValue: this.getGridApi().getPrimaryKeyValueForRowNode(rowNode) }));
        }
        else {
            return contextMappedFromGridData;
        }
    }
    getFdc3ActionColDefs() {
        const actionColDefs = [];
        if (this.isAtLeastOneActionButtonConfigured()) {
            const actionColumnConfig = this.getFdc3Options().actionColumnDefaultConfiguration;
            actionColDefs.push({
                colId: actionColumnConfig.columnId,
                headerName: actionColumnConfig.headerName,
                hide: false,
                lockVisible: true,
                suppressColumnsToolPanel: true,
                suppressFiltersToolPanel: true,
                editable: false,
                width: actionColumnConfig.width,
                resizable: actionColumnConfig.resizable,
                suppressHeaderMenuButton: true,
                suppressMovable: !actionColumnConfig.movable,
                filter: false,
                sortable: false,
                enableRowGroup: false,
                cellRenderer: this.getAdaptableVariant() === 'react' ? ActionColumnRenderer_1.ReactActionColumnRenderer : ActionColumnRenderer_1.ActionColumnRenderer,
                type: [GeneralConstants_1.AB_SPECIAL_COLUMN, GeneralConstants_1.AB_FDC3_COLUMN, 'abColDefObject'],
            });
        }
        const buildColDef = (actionColumnConfig) => {
            return {
                colId: actionColumnConfig.columnId,
                headerName: actionColumnConfig.friendlyName,
                hide: false,
                lockVisible: true,
                suppressColumnsToolPanel: true,
                suppressFiltersToolPanel: true,
                editable: false,
                width: actionColumnConfig.defaultWidth,
                resizable: true,
                suppressHeaderMenuButton: true,
                suppressMovable: false,
                filter: false,
                sortable: false,
                enableRowGroup: false,
                cellRenderer: this.getAdaptableVariant() === 'react' ? ActionColumnRenderer_1.ReactActionColumnRenderer : ActionColumnRenderer_1.ActionColumnRenderer,
                type: [GeneralConstants_1.AB_SPECIAL_COLUMN, GeneralConstants_1.AB_FDC3_COLUMN, 'abColDefObject'],
            };
        };
        this.getAllRaiseIntentConfigs().forEach((intentConfig) => {
            if (!intentConfig.actionColumn) {
                return;
            }
            const intendActionColumnConfig = intentConfig.actionColumn;
            actionColDefs.push(buildColDef(intendActionColumnConfig));
        });
        this.getAllBroadcastContextConfigs().forEach((contextConfig) => {
            if (!contextConfig.actionColumn) {
                return;
            }
            const contextActionColumnConfig = contextConfig.actionColumn;
            actionColDefs.push(buildColDef(contextActionColumnConfig));
        });
        return actionColDefs;
    }
    getButtonsForFdc3MainActionColumn() {
        const buttons = [];
        const intentButtonConfigs = this.getIntentConfigsWithActionButtons();
        intentButtonConfigs.forEach((intentConfig) => {
            if (!intentConfig.actionButton) {
                return;
            }
            const intendActionButtonConfig = intentConfig.actionButton;
            buttons.push(this.mapFdc3ButtonConfigToAdaptableButton(intendActionButtonConfig, {
                action: 'raiseIntent',
                intent: intentConfig.intentType,
                contextType: intentConfig.contextType,
            }));
        });
        const broadcastButtonConfigs = this.getContextConfigsWithActionButtons();
        broadcastButtonConfigs.forEach((contextConfig) => {
            if (!contextConfig.actionButton) {
                return;
            }
            const contextActionButtonConfig = contextConfig.actionButton;
            buttons.push(this.mapFdc3ButtonConfigToAdaptableButton(contextActionButtonConfig, {
                action: 'broadcastContext',
                contextType: contextConfig.contextType,
            }));
        });
        return buttons;
    }
    getButtonsForFdc3StandaloneActionColumn(columnId) {
        const buttons = [];
        this.getAllRaiseIntentConfigs().forEach((intentConfig) => {
            var _a;
            if (((_a = intentConfig.actionColumn) === null || _a === void 0 ? void 0 : _a.columnId) === columnId) {
                buttons.push(this.mapFdc3ButtonConfigToAdaptableButton(intentConfig.actionColumn.button, {
                    action: 'raiseIntent',
                    intent: intentConfig.intentType,
                    contextType: intentConfig.contextType,
                }));
            }
        });
        this.getAllBroadcastContextConfigs().forEach((contextConfig) => {
            var _a;
            if (((_a = contextConfig.actionColumn) === null || _a === void 0 ? void 0 : _a.columnId) === columnId) {
                buttons.push(this.mapFdc3ButtonConfigToAdaptableButton(contextConfig.actionColumn.button, {
                    action: 'broadcastContext',
                    contextType: contextConfig.contextType,
                }));
            }
        });
        return buttons;
    }
    isFdc3MainActionColumn(columnId) {
        return columnId === this.getFdc3Options().actionColumnDefaultConfiguration.columnId;
    }
    isFdc3StandaloneActionColumn(columnId, columnType) {
        const types = typeof columnType === 'string' ? [columnType] : columnType;
        return types.includes(GeneralConstants_1.AB_FDC3_COLUMN) && !this.isFdc3MainActionColumn(columnId);
    }
    handleIntentResolution(intentResolution, context, raisedIntent, app) {
        var _a, _b;
        const relevantRaiseIntentConfig = this.getAllRaiseIntentConfigs().find((config) => config.intentType === raisedIntent && config.contextType === context.type);
        if (typeof (relevantRaiseIntentConfig === null || relevantRaiseIntentConfig === void 0 ? void 0 : relevantRaiseIntentConfig.handleIntentResolution) === 'function') {
            // call intent specific resolution handler
            relevantRaiseIntentConfig.handleIntentResolution(Object.assign(Object.assign({}, this.getAdaptableInternalApi().buildBaseContext()), { intentResolution }));
        }
        else {
            // call global resolution handler (if any)
            (_b = (_a = this.getFdc3Options().intents) === null || _a === void 0 ? void 0 : _a.handleIntentResolution) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.getAdaptableInternalApi().buildBaseContext()), { intentResolution }));
        }
    }
    isStandardContextType(contextType) {
        return (0, fdc3_1.isStandardContextType)(contextType);
    }
    isStandardIntentType(intentType) {
        return (0, fdc3_1.isStandardIntent)(intentType);
    }
    getAllRaiseIntentConfigs() {
        var _a;
        const result = [];
        const mapConfig = (intentType, intentConfigs) => intentConfigs.map((intentConfig) => (Object.assign(Object.assign({}, intentConfig), { intentType })));
        const raiseIntentConfiguration = ((_a = this.getFdc3Options().intents) === null || _a === void 0 ? void 0 : _a.raises) || {};
        Object.keys(raiseIntentConfiguration).forEach((intentType) => {
            if (intentType === 'custom') {
                const customIntentConfigs = raiseIntentConfiguration[intentType];
                Object.keys(customIntentConfigs).forEach((customIntentType) => {
                    result.push(...mapConfig(customIntentType, customIntentConfigs[customIntentType]));
                });
            }
            else {
                const intentConfigs = raiseIntentConfiguration[intentType];
                result.push(...mapConfig(intentType, intentConfigs));
            }
        });
        return result;
    }
    getAllBroadcastContextConfigs() {
        var _a;
        const result = [];
        const mapConfig = (contextType, contextConfig) => (Object.assign(Object.assign({}, contextConfig), { contextType }));
        const broadcastContextConfiguration = ((_a = this.getFdc3Options().contexts) === null || _a === void 0 ? void 0 : _a.broadcasts) || {};
        Object.keys(broadcastContextConfiguration).forEach((contextType) => {
            if (contextType === 'custom') {
                const customContextConfigs = broadcastContextConfiguration[contextType];
                Object.keys(customContextConfigs).forEach((customContextType) => {
                    result.push(mapConfig(customContextType, customContextConfigs[customContextType]));
                });
            }
            else {
                const contextConfigs = broadcastContextConfiguration[contextType];
                result.push(mapConfig(contextType, contextConfigs));
            }
        });
        return result;
    }
    getDefaultIconForIntent(intentType) {
        var _a, _b;
        const defaultConfig = this.getAdaptableInternalApi().getFdc3Service().getUiControlsDefaultConfiguration();
        // @ts-ignore
        const intentIcon = (_b = (_a = defaultConfig === null || defaultConfig === void 0 ? void 0 : defaultConfig.intents[intentType]) === null || _a === void 0 ? void 0 : _a.icon) !== null && _b !== void 0 ? _b : {
            name: 'fdc3',
        };
        return intentIcon;
    }
    getDefaultIconForContext(contextType) {
        var _a, _b;
        const defaultConfig = this.getAdaptableInternalApi().getFdc3Service().getUiControlsDefaultConfiguration();
        // @ts-ignore
        const contextIcon = (_b = (_a = defaultConfig === null || defaultConfig === void 0 ? void 0 : defaultConfig.contexts[contextType]) === null || _a === void 0 ? void 0 : _a.icon) !== null && _b !== void 0 ? _b : {
            name: 'fdc3',
        };
        return contextIcon;
    }
    mapRowValueToContextData(rowNode, contextMapping = {}) {
        // recursively map the row node values to the context data
        const mapContext = (obj) => {
            return Object.keys(obj).reduce((mappedData, contextKey) => {
                const valueReference = obj[contextKey];
                if (Array.isArray(valueReference)) {
                    mappedData[contextKey] = valueReference.map((item) => mapContext(item));
                }
                else if (typeof valueReference === 'object') {
                    mappedData[contextKey] = mapContext(valueReference);
                }
                else {
                    // map value from row node
                    // first validate refs
                    if (typeof valueReference !== 'string' ||
                        (!valueReference.startsWith(Fdc3Options_1.ColumnRefTypePrefix) &&
                            !valueReference.startsWith(Fdc3Options_1.FieldRefTypePrefix))) {
                        this.logError(`Invalid FDC3 value reference for '${contextKey}': ${valueReference}`);
                        return mappedData;
                    }
                    // '_coldId.columnId'
                    if (valueReference.startsWith(Fdc3Options_1.ColumnRefTypePrefix)) {
                        const columnId = valueReference.replace(Fdc3Options_1.ColumnRefTypePrefix, '');
                        mappedData[contextKey] = this.getGridApi().getRawValueFromRowNode(rowNode, columnId);
                    }
                    // '_field.fieldName'
                    if (valueReference.startsWith(Fdc3Options_1.FieldRefTypePrefix)) {
                        const fieldId = valueReference.replace(Fdc3Options_1.FieldRefTypePrefix, '');
                        mappedData[contextKey] = this.getAdaptableInternalApi().getValueUsingField(rowNode.data, fieldId);
                    }
                }
                return mappedData;
            }, {});
        };
        return mapContext(contextMapping);
    }
    isAtLeastOneActionButtonConfigured() {
        return (this.getIntentConfigsWithActionButtons().length ||
            this.getContextConfigsWithActionButtons().length);
    }
    getIntentConfigsWithActionButtons() {
        return this.getAllRaiseIntentConfigs().filter((intentConfig) => !!intentConfig.actionButton);
    }
    getContextConfigsWithActionButtons() {
        return this.getAllBroadcastContextConfigs().filter((contextConfig) => !!contextConfig.actionButton);
    }
    mapFdc3ButtonConfigToAdaptableButton(fdc3AdaptableButton, fdcInfo) {
        const buildFdc3Context = (context) => {
            return Object.assign({ context: this.mapRowToContextData(fdcInfo.contextType, context.rowNode), intent: fdcInfo.action === 'raiseIntent' ? fdcInfo.intent : null, rowNode: context.rowNode, rowData: context.data, primaryKeyValue: context.primaryKeyValue }, this.getAdaptableInternalApi().buildBaseContext());
        };
        return {
            onClick: (_button, context) => {
                if (fdcInfo.action === 'raiseIntent') {
                    this.getFdc3Api().raiseIntentFromRow(context.rowNode, fdcInfo.intent, fdcInfo.contextType);
                }
                if (fdcInfo.action === 'broadcastContext') {
                    this.getFdc3Api().broadcastFromRow(context.rowNode, fdcInfo.contextType);
                }
            },
            label: (_button, context) => {
                const fdc3Label = fdc3AdaptableButton.label;
                if (typeof fdc3Label === 'function') {
                    return fdc3Label(fdc3AdaptableButton, buildFdc3Context(context));
                }
                if (fdc3Label === '_defaultFdc3') {
                    return this.getDefaultFdc3ButtonLabel(fdcInfo);
                }
                return fdc3Label;
            },
            icon: (_button, context) => {
                const fdc3Icon = fdc3AdaptableButton.icon;
                if (typeof fdc3Icon === 'function') {
                    return fdc3Icon(fdc3AdaptableButton, buildFdc3Context(context));
                }
                if (fdc3Icon === '_defaultFdc3') {
                    return this.getDefaultFdc3ButtonIcon(fdcInfo);
                }
                return fdc3Icon;
            },
            buttonStyle: (_button, context) => {
                const fdc3ButtonStyle = fdc3AdaptableButton.buttonStyle;
                if (fdc3ButtonStyle == undefined) {
                    return this.getDefaultFdc3ButtonStyle(fdcInfo);
                }
                if (typeof fdc3ButtonStyle === 'function') {
                    return fdc3ButtonStyle(fdc3AdaptableButton, buildFdc3Context(context));
                }
                return fdc3ButtonStyle;
            },
            tooltip: (_button, context) => {
                const fdc3Tooltip = fdc3AdaptableButton.tooltip;
                if (typeof fdc3Tooltip === 'function') {
                    return fdc3Tooltip(fdc3AdaptableButton, buildFdc3Context(context));
                }
                if (fdc3Tooltip === '_defaultFdc3') {
                    return this.getDefaultFdc3ButtonLabel(fdcInfo);
                }
                return fdc3Tooltip;
            },
            disabled: (_button, context) => {
                const fdc3Disabled = fdc3AdaptableButton.disabled;
                if (typeof fdc3Disabled === 'function') {
                    return fdc3Disabled(fdc3AdaptableButton, buildFdc3Context(context));
                }
                return fdc3Disabled;
            },
            hidden: (_button, context) => {
                const fdc3Hidden = fdc3AdaptableButton.hidden;
                if (typeof fdc3Hidden === 'function') {
                    return fdc3Hidden(fdc3AdaptableButton, buildFdc3Context(context));
                }
                return fdc3Hidden;
            },
        };
    }
    getDefaultFdc3ButtonLabel(fdc3Info) {
        if (fdc3Info.action === 'raiseIntent') {
            return `Raise ${fdc3Info.intent}`;
        }
        if (fdc3Info.action === 'broadcastContext') {
            return `Broadcast ${this.getFdc3Api().getContextLabel(fdc3Info.contextType)}`;
        }
        return '';
    }
    getDefaultFdc3ButtonIcon(fdc3Info) {
        if (fdc3Info.action === 'raiseIntent') {
            return this.getDefaultIconForIntent(fdc3Info.intent);
        }
        else {
            return this.getDefaultIconForContext(fdc3Info.contextType);
        }
    }
    getDefaultFdc3ButtonStyle(fdcInfo) {
        return {
            variant: 'outlined',
            tone: 'neutral',
        };
    }
}
exports.Fdc3InternalApi = Fdc3InternalApi;
