"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019-2020 GoodData Corporation
var cloneDeep = require("lodash/cloneDeep");
var get = require("lodash/get");
var merge = require("lodash/merge");
var flatMap = require("lodash/flatMap");
var isNil = require("lodash/isNil");
var isEqual = require("lodash/isEqual");
var isEmpty = require("lodash/isEmpty");
var React = require("react");
var react_measure_1 = require("react-measure");
var react_dom_1 = require("react-dom");
var immer_1 = require("immer");
var bucketConfig_1 = require("../../../utils/bucketConfig");
var UnsupportedConfigurationPanel_1 = require("../../configurationPanels/UnsupportedConfigurationPanel");
var domHelper_1 = require("../../../utils/domHelper");
var BucketNames = require("../../../../constants/bucketNames");
var bucket_1 = require("../../../constants/bucket");
var bucketHelper_1 = require("../../../utils/bucketHelper");
var pivotTableUiConfigHelper_1 = require("../../../utils/uiConfigHelpers/pivotTableUiConfigHelper");
var internalIntlProvider_1 = require("../../../utils/internalIntlProvider");
var uiConfig_1 = require("../../../constants/uiConfig");
var AbstractPluggableVisualization_1 = require("../AbstractPluggableVisualization");
var propertiesHelper_1 = require("../../../utils/propertiesHelper");
var visualizationTypes_1 = require("../../../../constants/visualizationTypes");
var PivotTable_1 = require("../../../../components/core/PivotTable");
var dimensions_1 = require("../../../../helpers/dimensions");
var localization_1 = require("../../../../constants/localization");
var properties_1 = require("../../../constants/properties");
var widthItemsHelpers_1 = require("./widthItemsHelpers");
var supportedProperties_1 = require("../../../constants/supportedProperties");
var featureFlags_1 = require("../../../../helpers/featureFlags");
var sortItemsHelpers_1 = require("./sortItemsHelpers");
exports.getColumnAttributes = function (buckets) {
    return bucketHelper_1.getItemsFromBuckets(buckets, [BucketNames.COLUMNS, BucketNames.STACK, BucketNames.SEGMENT], [bucket_1.ATTRIBUTE, bucket_1.DATE]);
};
exports.getRowAttributes = function (buckets) {
    return bucketHelper_1.getItemsFromBuckets(buckets, [
        BucketNames.ATTRIBUTE,
        BucketNames.ATTRIBUTES,
        BucketNames.VIEW,
        BucketNames.TREND,
        BucketNames.LOCATION,
    ], [bucket_1.ATTRIBUTE, bucket_1.DATE]);
};
var PluggablePivotTable = /** @class */ (function (_super) {
    __extends(PluggablePivotTable, _super);
    function PluggablePivotTable(props) {
        var _this = _super.call(this) || this;
        _this.projectId = props.projectId;
        _this.element = props.element;
        _this.configPanelElement = props.configPanelElement;
        _this.callbacks = props.callbacks;
        _this.references = props.references;
        _this.locale = props.locale || localization_1.DEFAULT_LOCALE;
        _this.intl = internalIntlProvider_1.createInternalIntl(_this.locale);
        _this.onExportReady = props.callbacks.onExportReady && _this.onExportReady.bind(_this);
        _this.environment = props.environment;
        _this.featureFlags = props.featureFlags || {};
        _this.onColumnResized = _this.onColumnResized.bind(_this);
        _this.handlePushData = _this.handlePushData.bind(_this);
        _this.supportedPropertiesList = supportedProperties_1.PIVOT_TABLE_SUPPORTED_PROPERTIES;
        return _this;
    }
    PluggablePivotTable.prototype.unmount = function () {
        domHelper_1.unmountComponentsAtNodes([this.element, this.configPanelElement]);
    };
    PluggablePivotTable.prototype.update = function (options, visualizationProperties, mdObject, references) {
        var propertiesWithOnlySupportedControls = propertiesHelper_1.getSupportedProperties(visualizationProperties, this.supportedPropertiesList);
        var properties = visualizationProperties ? visualizationProperties.properties : {};
        var onlySupportedProperties = {
            properties: __assign({}, properties, propertiesWithOnlySupportedControls),
        };
        this.visualizationProperties = onlySupportedProperties;
        this.references = references;
        this.adaptPropertiesToMdObject(onlySupportedProperties, mdObject);
        this.renderVisualization(options, this.visualizationProperties, mdObject);
        this.renderConfigurationPanel(mdObject);
    };
    PluggablePivotTable.prototype.getExtendedReferencePoint = function (referencePoint, previousReferencePoint) {
        var _this = this;
        return Promise.resolve(immer_1.default(referencePoint, function (referencePointDraft) {
            referencePointDraft.uiConfig = cloneDeep(uiConfig_1.DEFAULT_PIVOT_TABLE_UICONFIG);
            var buckets = referencePointDraft.buckets;
            var measures = bucketHelper_1.getAllItemsByType(buckets, [bucket_1.METRIC]);
            var rowAttributes = exports.getRowAttributes(buckets);
            var previousRowAttributes = previousReferencePoint && exports.getRowAttributes(previousReferencePoint.buckets);
            var columnAttributes = exports.getColumnAttributes(buckets);
            var previousColumnAttributes = previousReferencePoint && exports.getColumnAttributes(previousReferencePoint.buckets);
            var totals = bucketHelper_1.getTotalsFromBucket(buckets, BucketNames.ATTRIBUTE);
            referencePointDraft.buckets = bucketHelper_1.removeDuplicateBucketItems([
                {
                    localIdentifier: BucketNames.MEASURES,
                    items: measures,
                },
                __assign({ localIdentifier: BucketNames.ATTRIBUTE, items: rowAttributes }, (totals.length > 0 ? { totals: totals } : null)),
                {
                    localIdentifier: BucketNames.COLUMNS,
                    items: columnAttributes,
                },
            ]);
            var filters = referencePointDraft.filters
                ? flatMap(referencePointDraft.filters.items, function (item) { return item.filters; })
                : [];
            var originalSortItems = get(referencePointDraft.properties, "sortItems", []);
            var originalColumnWidths = get(referencePointDraft.properties, "controls.columnWidths");
            var columnWidths = widthItemsHelpers_1.adaptReferencePointWidthItemsToPivotTable(originalColumnWidths, measures, rowAttributes, columnAttributes, previousRowAttributes ? previousRowAttributes : [], previousColumnAttributes ? previousColumnAttributes : [], filters);
            var controlsObj = columnWidths
                ? {
                    controls: {
                        columnWidths: columnWidths,
                    },
                }
                : {};
            referencePointDraft.properties = __assign({ sortItems: sortItemsHelpers_1.addDefaultSort(sortItemsHelpers_1.adaptReferencePointSortItemsToPivotTable(originalSortItems, measures, rowAttributes, columnAttributes), filters, rowAttributes, previousRowAttributes) }, controlsObj);
            pivotTableUiConfigHelper_1.setPivotTableUiConfig(referencePointDraft, _this.intl, visualizationTypes_1.VisualizationTypes.TABLE);
            bucketConfig_1.configurePercent(referencePointDraft, false);
            bucketConfig_1.configureOverTimeComparison(referencePointDraft, !!_this.featureFlags.enableWeekFilters);
            Object.assign(referencePointDraft, propertiesHelper_1.getReferencePointWithSupportedProperties(referencePointDraft, _this.supportedPropertiesList));
            referencePointDraft.filters = bucketHelper_1.sanitizeFilters(referencePointDraft).filters;
        }));
    };
    PluggablePivotTable.prototype.getExtendedPivotTableProps = function (pivotTableProps, config) {
        return __assign({}, pivotTableProps, { config: config });
    };
    PluggablePivotTable.prototype.renderVisualization = function (options, visualizationProperties, mdObject) {
        var _this = this;
        var dataSource = options.dataSource;
        if (dataSource) {
            var resultSpec = options.resultSpec, locale = options.locale, custom = options.custom, dimensions = options.dimensions, config = options.config;
            var height = dimensions.height;
            var drillableItems = custom.drillableItems;
            var _a = this.callbacks, afterRender = _a.afterRender, onError = _a.onError, onLoadingChanged = _a.onLoadingChanged, onDrill = _a.onDrill, onFiredDrillEvent = _a.onFiredDrillEvent;
            var resultSpecWithDimensions = __assign({}, resultSpec, { dimensions: this.getDimensions(mdObject) });
            var sorts = get(visualizationProperties, "sortItems", []);
            var resultSpecWithSorts = resultSpecWithDimensions.sorts
                ? resultSpecWithDimensions
                : __assign({}, resultSpecWithDimensions, { sorts: sorts });
            var columnWidths = propertiesHelper_1.getColumnWidthsFromProperties(visualizationProperties);
            var rowsBucket = mdObject.buckets.find(function (bucket) { return bucket.localIdentifier === BucketNames.ATTRIBUTE; });
            var totals = (rowsBucket && rowsBucket.totals) || [];
            var updatedConfig_1 = featureFlags_1.getTableConfigFromFeatureFlags(this.enrichConfigWithMenu(config), this.featureFlags, this.environment === properties_1.DASHBOARDS_ENVIRONMENT, columnWidths);
            var pivotTableProps = {
                projectId: this.projectId,
                drillableItems: drillableItems,
                onDrill: onDrill,
                onFiredDrillEvent: onFiredDrillEvent,
                totals: totals,
                config: updatedConfig_1,
                height: height,
                locale: locale,
                dataSource: dataSource,
                resultSpec: resultSpecWithSorts,
                afterRender: afterRender,
                onLoadingChanged: onLoadingChanged,
                pushData: this.handlePushData,
                onError: onError,
                onExportReady: this.onExportReady,
                LoadingComponent: null,
                ErrorComponent: null,
                intl: this.intl,
            };
            var pivotTablePropsFromFeatureFlags_1 = __assign({}, pivotTableProps, this.getPivotTablePropsFromFeatureFlags());
            if (this.environment === properties_1.DASHBOARDS_ENVIRONMENT) {
                if (isNil(height)) {
                    react_dom_1.render(React.createElement(react_measure_1.default, { client: true }, function (_a) {
                        var measureRef = _a.measureRef, contentRect = _a.contentRect;
                        var clientHeight = contentRect.client.height;
                        var usedHeight = Math.floor(clientHeight || 0);
                        var pivotWrapperStyle = {
                            height: "100%",
                            textAlign: "left",
                        };
                        var extendedPivotTableProps = _this.getExtendedPivotTableProps(pivotTablePropsFromFeatureFlags_1, __assign({}, updatedConfig_1, { maxHeight: clientHeight }));
                        return (React.createElement("div", { ref: measureRef, style: pivotWrapperStyle, className: "gd-table-dashboard-wrapper" }, _this.createTable(__assign({}, extendedPivotTableProps, { height: usedHeight }))));
                    }), document.querySelector(this.element));
                    return;
                }
                react_dom_1.render(React.createElement(react_measure_1.default, { client: true }, function (_a) {
                    var measureRef = _a.measureRef, contentRect = _a.contentRect;
                    var extendedPivotTableProps = _this.getExtendedPivotTableProps(pivotTablePropsFromFeatureFlags_1, __assign({}, updatedConfig_1, { maxHeight: contentRect.client.height }));
                    return (React.createElement("div", { ref: measureRef, style: { height: 328, textAlign: "left" }, className: "gd-table-dashboard-wrapper" }, _this.createTable(extendedPivotTableProps)));
                }), document.querySelector(this.element));
            }
            else {
                react_dom_1.render(this.createTable(pivotTablePropsFromFeatureFlags_1), document.querySelector(this.element));
            }
        }
    };
    PluggablePivotTable.prototype.createTable = function (props) {
        return React.createElement(PivotTable_1.PivotTable, __assign({}, props));
    };
    PluggablePivotTable.prototype.onExportReady = function (exportResult) {
        var onExportReady = this.callbacks.onExportReady;
        if (onExportReady) {
            onExportReady(exportResult);
        }
    };
    PluggablePivotTable.prototype.renderConfigurationPanel = function (mdObject) {
        if (document.querySelector(this.configPanelElement)) {
            var properties = get(this.visualizationProperties, "properties", {});
            // we need to handle cases when attribute previously bearing the default sort is no longer available
            var sanitizedProperties = properties.sortItems
                ? __assign({}, properties, { sortItems: sortItemsHelpers_1.adaptMdObjectSortItemsToPivotTable(properties.sortItems, mdObject.buckets) }) : properties;
            react_dom_1.render(React.createElement(UnsupportedConfigurationPanel_1.default, { locale: this.locale, pushData: this.callbacks.pushData, properties: sanitizedProperties }), document.querySelector(this.configPanelElement));
        }
    };
    PluggablePivotTable.prototype.getDimensions = function (mdObject) {
        return dimensions_1.generateDimensions(mdObject, visualizationTypes_1.VisualizationTypes.TABLE);
    };
    PluggablePivotTable.prototype.adaptPropertiesToMdObject = function (visualizationProperties, mdObject) {
        // This is sanitization of properties from KD vs current mdObject from AD
        var columnWidths = propertiesHelper_1.getColumnWidthsFromProperties(visualizationProperties);
        if (columnWidths) {
            this.sanitizeColumnWidths(columnWidths, mdObject);
        }
    };
    PluggablePivotTable.prototype.sanitizeColumnWidths = function (columnWidths, mdObject) {
        // BUGFIX ONE-4570, buckets have to have at least one item
        if (isEmpty(mdObject.buckets)) {
            return;
        }
        var adaptedColumnWidths = widthItemsHelpers_1.adaptMdObjectWidthItemsToPivotTable(columnWidths, mdObject.buckets);
        if (!isEqual(columnWidths, adaptedColumnWidths)) {
            this.visualizationProperties.properties.controls.columnWidths = adaptedColumnWidths;
            var pushData = this.callbacks.pushData;
            pushData({
                properties: {
                    controls: {
                        columnWidths: adaptedColumnWidths,
                    },
                },
            });
        }
    };
    PluggablePivotTable.prototype.enrichConfigWithMenu = function (config) {
        if (this.environment === properties_1.DASHBOARDS_ENVIRONMENT) {
            // Menu aggregations turned off in KD
            return config;
        }
        var menu = {
            aggregations: true,
            aggregationsSubMenu: true,
        };
        return merge({ menu: menu }, config);
    };
    PluggablePivotTable.prototype.onColumnResized = function (columnWidths) {
        var pushData = this.callbacks.pushData;
        pushData({
            properties: {
                controls: {
                    columnWidths: columnWidths,
                },
            },
        });
    };
    PluggablePivotTable.prototype.handlePushData = function (data) {
        var _a = this, pushData = _a.callbacks.pushData, visualizationProperties = _a.visualizationProperties, references = _a.references;
        var properties = visualizationProperties ? visualizationProperties.properties : null;
        if (data && data.properties && data.properties.sortItems) {
            pushData({
                properties: {
                    sortItems: data.properties.sortItems,
                },
            });
        }
        else if (data && data.result && properties && references) {
            // pushData from VisualizationLoadingHOC
            pushData(__assign({}, data, { references: references,
                properties: properties }));
        }
        else {
            pushData(data);
        }
    };
    PluggablePivotTable.prototype.getPivotTablePropsFromFeatureFlags = function () {
        if (this.featureFlags.enableTableColumnsManualResizing) {
            return {
                onColumnResized: this.onColumnResized,
            };
        }
        return {};
    };
    return PluggablePivotTable;
}(AbstractPluggableVisualization_1.AbstractPluggableVisualization));
exports.PluggablePivotTable = PluggablePivotTable;
//# sourceMappingURL=PluggablePivotTable.js.map