/*
 * Axelor Business Solutions
 *
 * Copyright (C) 2005-2017 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
(function() {

"use strict";

var ui = angular.module("axelor.ui");

CustomViewCtrl.$inject = ['$scope', '$http', 'DataSource', 'ViewService'];
function CustomViewCtrl($scope, $http, DataSource, ViewService) {

	ui.ViewCtrl.call(this, $scope, DataSource, ViewService);

	var view = $scope._views.custom || {};
	var viewPromise = null;

	$scope.show = function() {
		if (!viewPromise) {
			viewPromise = $scope.loadView('custom', view.name);
			viewPromise.then(function(meta) {
				var schema = meta.view;
				$scope.schema = schema;
				$scope.schema.loaded = true;
			});
		}
		$scope.onShow(viewPromise);
	};

	$scope.onShow = function(viewPromise) {
		// it will be refreshed by dashlet
		if ($scope.dashlet) {
			return;
		}
		viewPromise.then(function () {
			$scope.onRefresh();
		});
	};

	$scope.getRouteOptions = function() {
		return {
			mode: 'custom'
		};
	};

	$scope.setRouteOptions = function(options) {
		var opts = options || {};
		if (opts.mode === "custom") {
			return $scope.updateRoute();
		}
		var params = $scope._viewParams;
		if (params.viewType !== "custom") {
			return $scope.show();
		}
	};

	$scope.getContext = function () {
		var context = $scope._context || {};
		if ($scope.$parent.getContext) {
			context = _.extend({}, $scope.$parent.getContext(), context);
		}
		return context;
	};

	$scope.onRefresh = function() {
		var context = $scope.getContext();
		var params = {
			data: context
		};
		return $http.post('ws/meta/custom/' + view.name, params).then(function(response) {
			var res = response.data;
			$scope.data = (res.data||{}).dataset;
		});
	};
}

var customDirective = ["$compile", function ($compile) {
	return {
		controller: CustomViewCtrl,
		link: function (scope, element, attrs, ctrl) {

			var evalScope = axelor.$evalScope(scope);

			function render(template) {
				var elem = $('<span>' + template.trim() + '</span>');
				if (elem.children().size() === 1) {
					elem = elem.children().first();
				}
				if (scope.schema && scope.schema.css) {
					element.parents(".dashlet:first").addClass(scope.schema.css);
				}

				elem = $compile(elem)(evalScope);
				element.append(elem);
			}

			var unwatch = scope.$watch('schema.template', function (template) {
				if (template) {
					unwatch();
					render(template);
				}
			});
			
			scope.showToggle = false;

			scope.$watch('data', function (data) {
				evalScope.data = data;
				evalScope.first = _.first(data);
			});
		}
	};
}];

ui.directive('uiCustomView', customDirective);
ui.directive('uiPortletCustom', customDirective);

// helper directives
ui.directive('reportBox', function() {
	return {
		scope: {
			value: '=',
			label: '@',
			percent: '=',
			up: '=',
			tag: '=',
			tagCss: '='
		},
		link: function (scope, element, attrs) {
			setTimeout(function () {
				element.parents('.dashlet:first')
					.addClass("report-box");
			});
		},
		replace: true,
		template:
			"<div class='report-box'>" +
				"<h1>{{value}}</h1>" +
				"<small>{{label}}</small>" +
				"<div class='font-bold text-info pull-right' ng-show='percent'>" +
					"<span>{{percent}}</span> <i class='fa fa-level-up'></i>" +
				"</div>" +
				"<div class='report-tags' ng-if='tag'><span class='label' ng-class='tagCss'>{{tag}}</span></div>" +
			"</div>"
	};
});

ui.directive('reportTable',  function() {
	return {
		scope: {
			data: '=',
			columns: '@',
			sums: '@'
		},
		link: function (scope, element, attrs) {

			var cols = [];
			var sums = (scope.sums||'').split(',');
			var fields = {};
			var schema = scope.$parent.$parent.schema;

			(scope.columns||'').split(',').forEach(function (name) {
				var field = _.findWhere(schema.items, { name: name }) || {};
				var col = _.extend({}, field, field.widgetAttrs, {
					name: name,
					title: _.humanize(name)
				});
				fields[name] = col;
				cols.push(col);
			});

			scope.cols = cols;
			scope.sums = sums;

			scope.format = function(value, name) {
				if (value === null || value === undefined) {
					return "";
				}
				var field = fields[name];
				if (field && field.scale) {
					var val = +(value);
					if (_.isNumber(val)) {
						return val.toFixed(field.scale);
					}
				}
				return value;
			};

			scope.sum = function (name) {
				if (sums.indexOf(name) === -1) {
					return "";
				}
				var res = 0.0;
				_.each(scope.data, function (row) {
					var val = +(row[name]) || 0;
					res += val;
				});
				return scope.format(res, name);
			};

			setTimeout(function () {
				element.parents('.dashlet:first')
					.addClass("report-table");
			});
		},
		replace: true,
		template:
			"<table class='table table-striped'>" +
				"<thead>" +
					"<tr>" +
						"<th ng-repeat='col in cols'>{{col.title}}</th>" +
					"</tr>" +
				"</thead>" +
				"<tbody>" +
					"<tr ng-repeat='row in data'>" +
						"<td ng-repeat='col in cols'>{{format(row[col.name], col.name)}}</td>" +
					"</tr>" +
				"</tbody>" +
				"<tfoot ng-if='sums.length'>" +
					"<tr>" +
						"<td ng-repeat='col in cols'>{{sum(col.name)}}</td>" +
					"</tr>" +
				"</tfoot>" +
			"</table>"
	};
});

})();
