"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 ActionColumnRenderer_1 = require("../../agGrid/cellRenderers/ActionColumnRenderer");
const AdaptableColumn_1 = require("../../AdaptableState/Common/AdaptableColumn");
class Fdc3InternalApi extends ApiBase_1.ApiBase {
    mapRowToContextData(contextType, rowNode) {
        if (contextType === 'fdc3.nothing') {
            return { type: contextType };
        }
        const mappedContextData = this.mapRowValueToContextData(rowNode, this.isStandardContextType(contextType) && contextType !== 'fdc3.nothing'
            ? this.getFdc3Options().gridDataContextMapping?.[contextType]
            : this.getFdc3Options().gridDataContextMapping?.custom?.[contextType]);
        const contextMappedFromGridData = {
            type: contextType,
            ...mappedContextData,
        };
        const resolveContextDataFn = this.getFdc3Options().resolveContextData;
        if (typeof resolveContextDataFn === 'function') {
            return resolveContextDataFn({
                ...this.getAdaptableInternalApi().buildBaseContext(),
                contextType,
                contextMappedFromGridData,
                rowNode,
                rowData: rowNode.data,
                primaryKeyValue: this.getGridApi().getPrimaryKeyValueForRowNode(rowNode),
            });
        }
        else {
            return contextMappedFromGridData;
        }
    }
    getFdc3ColumnIds() {
        const fdc3ColumnIds = [];
        if (this.isAtLeastOneActionButtonConfigured()) {
            fdc3ColumnIds.push(this.getFdc3Options().actionColumnDefaultConfiguration.columnId);
        }
        [...this.getAllRaiseIntentConfigs(), ...this.getAllBroadcastContextConfigs()].forEach((config) => {
            if (config.actionColumn) {
                fdc3ColumnIds.push(config.actionColumn.columnId);
            }
        });
        return fdc3ColumnIds;
    }
    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: [AdaptableColumn_1.FDC3_COLUMN_TYPE],
            });
        }
        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: [AdaptableColumn_1.FDC3_COLUMN_TYPE],
            };
        };
        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) => {
            if (intentConfig.actionColumn?.columnId === columnId) {
                buttons.push(this.mapFdc3ButtonConfigToAdaptableButton(intentConfig.actionColumn.button, {
                    action: 'raiseIntent',
                    intent: intentConfig.intentType,
                    contextType: intentConfig.contextType,
                }));
            }
        });
        this.getAllBroadcastContextConfigs().forEach((contextConfig) => {
            if (contextConfig.actionColumn?.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) {
        const allFdc3ColumnIds = this.getFdc3ColumnIds();
        return allFdc3ColumnIds.includes(columnId) && !this.isFdc3MainActionColumn(columnId);
    }
    handleIntentResolution(intentResolution, context, raisedIntent, app) {
        const relevantRaiseIntentConfig = this.getAllRaiseIntentConfigs().find((config) => config.intentType === raisedIntent && config.contextType === context.type);
        if (typeof relevantRaiseIntentConfig?.handleIntentResolution === 'function') {
            // call intent specific resolution handler
            relevantRaiseIntentConfig.handleIntentResolution({
                ...this.getAdaptableInternalApi().buildBaseContext(),
                intentResolution,
            });
        }
        else {
            // call global resolution handler (if any)
            this.getFdc3Options().intents?.handleIntentResolution?.({
                ...this.getAdaptableInternalApi().buildBaseContext(),
                intentResolution,
            });
        }
    }
    isStandardContextType(contextType) {
        return (0, fdc3_1.isStandardContextType)(contextType);
    }
    isStandardIntentType(intentType) {
        return (0, fdc3_1.isStandardIntent)(intentType);
    }
    getAllRaiseIntentConfigs() {
        const result = [];
        const mapConfig = (intentType, intentConfigs) => intentConfigs.map((intentConfig) => ({
            ...intentConfig,
            intentType,
        }));
        const raiseIntentConfiguration = this.getFdc3Options().intents?.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() {
        const result = [];
        const mapConfig = (contextType, contextConfig) => ({ ...contextConfig, contextType });
        const broadcastContextConfiguration = this.getFdc3Options().contexts?.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) {
        const defaultConfig = this.getAdaptableInternalApi()
            .getFdc3Service()
            .getUiControlsDefaultConfiguration();
        // @ts-ignore
        const intentIcon = defaultConfig?.intents[intentType]?.icon ?? {
            name: 'fdc3',
        };
        return intentIcon;
    }
    getDefaultIconForContext(contextType) {
        const defaultConfig = this.getAdaptableInternalApi()
            .getFdc3Service()
            .getUiControlsDefaultConfiguration();
        // @ts-ignore
        const contextIcon = defaultConfig?.contexts[contextType]?.icon ?? {
            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 {
                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;
