'use strict';

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Licensed Materials - Property of IBM
 * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2018, 2020
 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 */
define(['underscore', '../../lib/@waca/dashboard-common/dist/core/APIFactory', './DataItemAPISpec', '../DataItemAPI', '../../widgets/livewidget/nls/StringResources', './Union'], function (_, APIFactory, DataItemAPISpec, DataItemAPI, StringResources, Union) {
	var UP = 'up';
	var DOWN = 'down';

	var DataItem = function (_DataItemAPISpec) {
		_inherits(DataItem, _DataItemAPISpec);

		function DataItem(dataItemModel, dataSourceAPI, transaction, locale) {
			_classCallCheck(this, DataItem);

			var _this = _possibleConstructorReturn(this, _DataItemAPISpec.call(this));

			_this.locale = locale;
			_this.dataItemModel = dataItemModel;
			_this.dataSourceAPI = dataSourceAPI;
			_this.transaction = transaction;
			_this._api = APIFactory.createAPI(_this, [DataItemAPI]);

			// set a default item label from the metadata
			if (!_this.dataItemModel.itemLabel) {
				var metadata = _this.getMetadataColumn();
				_this.dataItemModel.itemLabel = metadata ? metadata.getLabel() : undefined;
			}
			return _this;
		}

		DataItem.prototype.isRootDataItem = function isRootDataItem() {
			return !(this instanceof UnionDataItem);
		};

		DataItem.prototype.destroy = function destroy() {
			this.locale = null;
			this.dataItemModel = null;
			this.dataSourceAPI = null;
			this.transaction = null;
			this._api = null;
			if (this.unionImpl) {
				this.unionImpl.destroy();
			}
		};

		DataItem.prototype.getAPI = function getAPI() {
			return this._api;
		};

		DataItem.prototype.getId = function getId() {
			return this.dataItemModel.id;
		};

		DataItem.prototype.setLabel = function setLabel(label) {
			this.dataItemModel.itemLabel = label;
		};

		DataItem.prototype.getLabel = function getLabel() {
			var binning = this.getBinning();
			var label = binning && binning.label;
			if (!label) {
				var metadata = this.getMetadataColumn();
				label = metadata && metadata.getLabel() ? metadata.getLabel() : this.dataItemModel.itemLabel;
			}
			return label;
		};

		DataItem.prototype.getColumnId = function getColumnId() {
			return this.dataItemModel.itemId;
		};

		DataItem.prototype.getNavigationPathId = function getNavigationPathId() {
			return this.dataItemModel.navigationPathId;
		};

		DataItem.prototype.setNavigationPathId = function setNavigationPathId(id) {
			this.dataItemModel.navigationPathId = id;
		};

		DataItem.prototype.getDataType = function getDataType() {
			var mdColumn = this.getMetadataColumn();
			return mdColumn ? mdColumn.getDataType() : null;
		};

		DataItem.prototype.isDateOrTimeType = function isDateOrTimeType() {
			var dataType = this.getDataType();
			return dataType === 'date' || dataType === 'datetime' || dataType === 'time' || dataType === 'year' ? true : false;
		};

		DataItem.prototype.getType = function getType() {
			var mdColumn = this.getMetadataColumn();
			return mdColumn ? mdColumn.getType() : null;
		};

		DataItem.prototype.getAggregation = function getAggregation() {
			var aggregation = this.dataItemModel.aggregate;
			if (!aggregation) {
				var mdColumn = this.getMetadataColumn();
				aggregation = mdColumn ? mdColumn.getDefaultAggregation() : null;
			}
			return aggregation;
		};

		DataItem.prototype.setAggregation = function setAggregation(aggregation) {
			this.dataItemModel.aggregate = aggregation;
		};

		DataItem.prototype.hasDefaultAggregation = function hasDefaultAggregation() {
			return !this.dataItemModel.aggregate;
		};

		DataItem.prototype.getMetadataColumn = function getMetadataColumn() {
			return this.dataSourceAPI ? this.dataSourceAPI.getMetadataColumn(this.getColumnId()) : null;
		};

		DataItem.prototype.hasDefaultFormat = function hasDefaultFormat() {
			return !this.dataItemModel.format || !this.dataItemModel.format.formatSpec || _.isEmpty(this.dataItemModel.format.formatSpec);
		};

		DataItem.prototype.getFormat = function getFormat() {
			var format = this.dataItemModel.format && this.dataItemModel.format.formatSpec;
			// Should not be in the spec.. should weconsider an upgrade to clean it ?
			if (format) {
				delete format.local;
			}

			if (_.isEmpty(format)) {
				format = null;
			}

			if (format) {
				format = _.extend({}, format, { locale: this.locale });
				//adding this condition here, to remove abbreviation when Auto-Grouping is turned on
				var binningDefinition = this.dataItemModel.binningDefinition;
				if (binningDefinition) {
					if (format.decimalFormatLength && format.decimalFormatLength === 'short') {
						delete format.decimalFormatLength;
					}
				}
			}

			if (!format) {
				var mdColumn = this.getMetadataColumn();
				format = mdColumn ? mdColumn.getFormat() : null;
			}

			if (format && !format.locale) {
				format.locale = this.locale;
			}

			return format;
		};

		DataItem.prototype.setFormat = function setFormat(formatSpec) {
			this.dataItemModel.format = { formatSpec: formatSpec };
		};

		DataItem.prototype._getSortSelection = function _getSortSelection(selections) {
			return selections.find(function (selection) {
				if (selection.operation !== 'order') {
					return false;
				}
				return !selection.sort ? false : true;
			});
		};

		DataItem.prototype.hasModelSort = function hasModelSort() {
			throw 'Need to implement hasModelSort for DataItem';
		};

		DataItem.prototype._getUserSort = function _getUserSort() {
			var selections = this.dataItemModel.selection;
			if (!selections) {
				return null;
			}
			var selection = this._getSortSelection(selections);

			var result = null;
			if (selection) {
				var sortSelection = selection.sort;
				result = {
					type: sortSelection.type,
					priority: sortSelection.priority,
					by: sortSelection.by
				};

				if (sortSelection.rankSort) {
					result.rankSort = true;
				}

				if (sortSelection.custom) {
					result.custom = sortSelection.custom;
				}

				var contextArray = selection.context;
				if (contextArray) {
					var context = contextArray.length && contextArray[0];
					if (context) {
						result.context = context.itemId;
					}
				}
			}

			return result;
		};

		DataItem.prototype.hasDefaultSort = function hasDefaultSort() {
			return !this._getUserSort();
		};

		DataItem.prototype.getSort = function getSort() {
			var sort = this._getUserSort();
			if (sort) {
				return sort;
			}
		};

		DataItem.prototype._getTopBottomSelection = function _getTopBottomSelection(selections) {
			return !selections ? null : selections.find(function (selection) {
				return !!selection.topBottom;
			});
		};

		DataItem.prototype.getTopBottom = function getTopBottom() {
			var selections = this.dataItemModel.selection;
			if (!selections) {
				return null;
			}

			var selection = this._getTopBottomSelection(selections);

			if (!selection) {
				return null;
			}
			var topBottom = selection.topBottom;
			if (!topBottom) {
				return null;
			}

			var result = {
				type: topBottom.type,
				value: topBottom.value
			};

			// use != to check for both null and undefined
			if (topBottom.rank != null) {
				result.rank = topBottom.rank;
			}

			var contextArray = selection.context;
			if (contextArray) {
				var context = contextArray.length && contextArray[0];
				if (context) {
					result.context = {
						itemId: context.itemId
					};
					if (context.aggregate) {
						result.context.aggregate = context.aggregate;
					}
				}
			}

			return result;
		};

		DataItem.prototype._removeSelection = function _removeSelection(getter) {
			var selections = this.dataItemModel.selection;
			if (selections) {
				var selection = getter(selections);
				if (selection) {
					var index = selections.indexOf(selection);
					if (index > -1) {
						selections.splice(index, 1);
					}
				}
			} //else nothing to do
		};

		DataItem.prototype._initSelections = function _initSelections(getter) {
			var selections = this.dataItemModel.selection;
			if (!selections) {
				selections = [];
				this.dataItemModel.selection = selections;
			}
			this._removeSelection(getter);
			return selections;
		};

		DataItem.prototype.setTopBottom = function setTopBottom(topBottomInfo, transactionToken) {
			// TODO livewidget_cleanup -- test and fix the undo redo here
			if (this.getUnion().getDataItemList().length) {
				this.getUnion().setDataItems([], transactionToken);
			}
			if (!topBottomInfo) {
				this._removeSelection(this._getTopBottomSelection);
			} else {
				var selections = this._initSelections(this._getTopBottomSelection);

				var action = {
					operation: 'keep',
					topBottom: {
						type: topBottomInfo.type,
						value: topBottomInfo.value
					}
				};

				if (topBottomInfo.context) {
					action.context = [{
						itemId: topBottomInfo.context.itemId,
						aggregate: topBottomInfo.context.aggregate
					}];
				}

				if (topBottomInfo.rank) {
					action.topBottom.rank = true;
				}
				selections.push(action);
			}
		};

		DataItem.prototype._isolate = function _isolate(drillSpec, selections) {
			selections.push({
				'operation': 'keep',
				'set': [drillSpec.mun],
				'isolated': true
			});
		};

		DataItem.prototype._deIsolate = function _deIsolate() {
			var selections = this.dataItemModel.selection;
			var isolateNode = selections.find(function (selectionModel) {
				return selectionModel.isolated;
			});
			if (isolateNode) {
				var index = selections.indexOf(isolateNode);
				if (index > -1) {
					selections.splice(index, 1);
				}
			}
		};

		DataItem.prototype._isIsolated = function _isIsolated() {
			var selections = this.dataItemModel.selection;
			if (!selections) {
				return false;
			}

			return selections.find(function (selectionModel) {
				return selectionModel.isolated;
			});
		};

		DataItem.prototype._getDrillSelection = function _getDrillSelection(selections) {
			return !selections ? null : selections.find(function (selection) {
				return !!selection.children || !!selection.drillUp;
			});
		};

		DataItem.prototype._drill = function _drill(drillSpec) {

			var selections = this._initSelections(this._getDrillSelection);
			if (drillSpec.isIsolated) {
				this._deIsolate(drillSpec.dataItemModel);
			}

			var command = drillSpec.op === UP ? 'drillUp' : 'children';

			//The spec dictates that the selection command for drill up is `drillUp`, but drill down is `children`.
			//The [command] sets the variable to be either drillUp or children, thus saving redundant code to create the object.
			var param = {
				operation: 'add'
			};
			param[command] = drillSpec.isLeafMember ? drillSpec.pun : drillSpec.mun;

			selections.push(param);

			if (drillSpec.isLeafMember) {
				this._isolate(drillSpec, selections);
			}
		};

		DataItem.prototype.canDrillDown = function canDrillDown() {
			return !this._isIsolated();
		};

		DataItem.prototype.clearDrill = function clearDrill(transactionToken) {
			if (this.getUnion().getDataItemList().length) {
				this.getUnion().setDataItems([], transactionToken);
			}

			this._removeSelection(this._getDrillSelection);
		};

		DataItem.prototype.drillDown = function drillDown(value, transactionToken, parentValue) {
			var _this2 = this;

			var metadata = this.getMetadataColumn();
			return metadata.isLeafMember(value).then(function (isLeafMemberFlag) {
				//clear union before drilling
				// TODO livewidget_cleanup -- test and fix the undo redo here
				if (_this2.getUnion().getDataItemList().length) {
					_this2.getUnion().setDataItems([], transactionToken);
				}

				// TODO Pass parentValue as a temporary solution to handle drill on leaf member.
				// Hide it from public API until we find a better solution.
				var drillSpec = {
					op: DOWN,
					mun: value,
					pun: parentValue,
					isLeafMember: isLeafMemberFlag,
					isIsolated: _this2._isIsolated()
				};
				_this2._drill(drillSpec);
			});
		};

		DataItem.prototype.getDrillDownValue = function getDrillDownValue() {
			var selection = this._getDrillSelection(this.dataItemModel.selection);
			return selection ? selection.children : null;
		};

		DataItem.prototype.drillUp = function drillUp(itemId, transactionToken) {
			// TODO livewidget_cleanup -- test and fix the undo redo here
			if (this.getUnion().getDataItemList().length) {
				this.getUnion().setDataItems([], transactionToken);
			}
			var drillSpec = {
				op: UP,
				mun: itemId,
				isIsolated: this._isIsolated()
			};
			this._drill(drillSpec);
			return Promise.resolve();
		};

		DataItem.prototype.getDrillUpValue = function getDrillUpValue() {
			var selection = this._getDrillSelection(this.dataItemModel.selection);
			return selection ? selection.drillUp : null;
		};

		DataItem.prototype.setBinning = function setBinning(binningSpec) {
			var binning = void 0;
			if (binningSpec) {
				binning = {
					id: this.id,
					binning: {
						auto: {
							numberOfBins: binningSpec.bins
						}
					},
					label: binningSpec.label || this.dataItemModel.itemLabel + ' ' + StringResources.get('autobinAxisLabel')
				};
			}
			this.dataItemModel.binningDefinition = binning;
		};

		DataItem.prototype.getBinning = function getBinning() {
			var binningDefinition = this.dataItemModel.binningDefinition;
			return binningDefinition ? {
				bins: binningDefinition.binning.auto.numberOfBins,
				label: binningDefinition.label
			} : undefined;
		};

		DataItem.prototype.setSort = function setSort(sortSpec) {
			var selections = this._initSelections(this._getSortSelection);
			if (sortSpec && (sortSpec.type || sortSpec.custom)) {
				// If we have a context, we default to a 'value' sortBy otherwise it is 'caption'
				var defaultSortBy = sortSpec.context ? 'value' : 'caption';
				var sort = {
					operation: 'order',
					sort: {
						type: sortSpec.type,
						by: sortSpec.by || defaultSortBy,
						priority: sortSpec.priority,
						custom: sortSpec.custom
					}
				};

				if (sortSpec.context) {
					sort.context = [{
						itemId: sortSpec.context
					}];
				}

				if (sortSpec.rankSort) {
					sort.sort.rankSort = true;
				}
				selections.push(sort);
			}
		};

		DataItem.prototype.getUnion = function getUnion() {
			if (!this.unionImpl) {
				if (!this.dataItemModel.union) {
					this.dataItemModel.union = {};
				}
				this.unionImpl = new Union(this.dataItemModel.union, UnionDataItem, this, this.dataSourceAPI, this.transaction, this.locale);
				APIFactory.setParentChildRelation(this, this.unionImpl);
			}
			return this.unionImpl.getAPI();
		};

		DataItem.prototype.isColumnUnavailable = function isColumnUnavailable() {
			var md = this.getMetadataColumn();
			return !md || md.isMissing();
		};

		return DataItem;
	}(DataItemAPISpec);

	var UnionDataItem = function (_DataItem) {
		_inherits(UnionDataItem, _DataItem);

		function UnionDataItem() {
			_classCallCheck(this, UnionDataItem);

			return _possibleConstructorReturn(this, _DataItem.apply(this, arguments));
		}

		UnionDataItem.prototype.drillDown = function drillDown(childUseValue) {
			var drillSpec = {
				op: DOWN,
				mun: childUseValue,
				isLeafMember: false,
				isIsolated: this._isIsolated()
			};
			return this._drill(drillSpec);
		};

		return UnionDataItem;
	}(DataItem);

	return DataItem;
});
//# sourceMappingURL=DataItem.js.map