(function () {
	'use strict';
	angular
		.module('RestPkiSite')
		.controller('EventsController', EventsController);

	EventsController.$inject = ['$scope', '$http', '$modal', '$location', '$translate', 'blockUI', 'lib', '$filter', '$routeParams', '$timeout'];
	function EventsController($scope, $http, $modal, $location, $translate, blockUI, lib, $filter, $routeParams, $timeout) {
		var vm = this;

		vm.data = [];
		vm.editBeginDate = editBeginDate;
		vm.editEndDate = editEndDate;
		vm.editingBeginDate = false;
		vm.editingEndDate = false;
		vm.filters = { userId: null, operations: null, success: null, desiredPage: 1, pageSize: 10 };
		vm.searchByFilters = searchByFilters;
		vm.setOp = setOperation;
		vm.showDetails = showDetails;
		vm.titleKey = 'evTitle';
		vm.targetUser = null;
		vm.updateDates = updateDates;
		vm.operationTypes = [
			'AccessTokenGenerated',
			'AccessTokensRevoked',
			'CertAuthStarted',
			'CertAuthCompleted',
			'PadesSignatureStarted',
			'PadesSignatureCompleted',
			'CadesSignatureStarted',
			'CadesSignatureCompleted',
			'XmlSignatureStarted',
			'XmlSignatureCompleted',
			'OpenSignature',
			'IssueTimestamp',
			'AddPdfMarks',
			'GetPendingSignature',
			'SetPendingSignature'
		];
		vm.today = new Date();

		$('#begin-datepicker')[0].focus = function () { };
		$('#end-datepicker')[0].focus = function () { };

		$scope.dateSortField = 'DateUtc';
		$scope.defaultSortDirection = 0; // Descending

		function showDetails(e) {
			blockUI.start();
			$http.get('/Api/Events/' + e.id).then(function (response) {
				blockUI.stop();
				lib.showAlert($translate.instant('evDetails'), response.data.details.replace(/\n/g, '<br/>'));
			}, function (response) {
				lib.showRestError(response, function () {
					$modalInstance.close();
				});
			});
		};

		function setOperation(operation) {
			vm.filters.operations[operation]
		};

		function editBeginDate($event) {
			$event.preventDefault();
			$event.stopPropagation();
			$timeout(function () { vm.editingBeginDate = true; });
		};

		function editEndDate($event) {
			$event.preventDefault();
			$event.stopPropagation();
			$timeout(function () { vm.editingEndDate = true; });
		};

		function getRequestModel() {

			var endDate = null;
			if (vm.dateParameters.endDate) {
				endDate = new Date(vm.dateParameters.endDate);
				endDate.setDate(endDate.getDate() + 1);
			}

			return {
				startDate: vm.dateParameters.beginDate,
				endDate: endDate,
				operations: getSelectedTypesList(),
				success: vm.filters.success,
				pageIndex: vm.filters.desiredPage,
				pageSize: vm.filters.pageSize,
				userId: vm.filters.userId,
				sortDirection: vm.filters.sortDirection || $scope.defaultSortDirection,
				sortField: vm.filters.sortField || $scope.dateSortField
			};
		};

		function getSelectedTypesList() {
			var types = [];
			angular.forEach(vm.filters.operations, function (value, key) {
				if (value) { types.push(key); }
			});
			return types;
		};

		function searchByFilters() {
			var url = ($routeParams.userId != null ? '/Api/Users/' + $routeParams.userId + '/Events' : '/Api/Events');
			return $http.get(url, { params: getRequestModel() })
				.then(function (response) {
					vm.data = response.data;
					blockUI.stop();
				}, lib.handleRestError);
		};

		function activate() {
			if (!lib.checkIsAuthenticated()) {
				return;
			}

			blockUI.start();

			vm.dateParameters = { beginDate: null, endDate: null };

			vm.filters.sortDirection = $scope.defaultSortDirection;
			vm.filters.sortField = $scope.dateSortField;

			parseUrl();
			handleQuery(true);

			$scope.$on('$routeUpdate', handleQuery);

			blockUI.stop();
		};

		// update url query
		function onParametersChanged(shouldUpdateDates) {
			$location.search('type', getSelectedTypesList());
			$location.search('count', vm.filters.pageSize);
			$location.search('page', vm.filters.desiredPage);
			$location.search('success', (vm.filters.success != null ? String(vm.filters.success) : null));
			$location.search('sortField', vm.filters.sortField || $scope.dateSortField);
			$location.search('sortDirection', vm.filters.sortDirection || $scope.defaultSortDirection);
			if (shouldUpdateDates) {
				$location.search('from', $filter('date')(vm.dateParameters.beginDate, 'yyyy-MM-dd'));
				$location.search('to', $filter('date')(vm.dateParameters.endDate, 'yyyy-MM-dd'));
			}
		};

		function updateDates() {
			onParametersChanged(true);
		};

		function handleQuery(initializing) {
			if (parseUrl()) {
				searchByFilters();
			} else {
				updateDates();
			}
			if (initializing) {
				$scope.$watch('vm.filters', function (newVal, oldVal, scope) {
					if (!angular.equals(newVal, oldVal)) {
						onParametersChanged();
					}
				}, true);
			}
		};

		var parseDate = function (date) {
			if (date) {
				var match = date.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/);
				if (match != null) {
					date = new Date(match[1], parseInt(match[2]) - 1, match[3]);
				} else {
					date = null;
				}
			}
			return date;
		};

		function parseUrl() {
			var params = $location.search();
			var hasParams = !angular.equals({}, params);
			var beginParsed = parseDate(params.from);
			var endParsed = parseDate(params.to);

			parseSelectedTypesFromUrl(params);
			parseTargetUser(params);
			vm.filters.pageSize = params.count || 10;
			vm.filters.desiredPage = params.page || 1;
			vm.dateParameters.beginDate = beginParsed || null;
			vm.dateParameters.endDate = endParsed || null;
			vm.filters.success = params.success === undefined ? null : (params.success === "true");
			vm.filters.sortField = params.sortField || $scope.dateSortField;
			vm.filters.sortDirection = params.sortDirection || $scope.defaultSortDirection;

			return hasParams;
		};

		function parseSelectedTypesFromUrl(params) {
			var types = [].concat(params.type || []);
			vm.filters.operations = {};
			angular.forEach(types, function (type) {
				vm.filters.operations[type] = true;
			});
		};

		function parseTargetUser(params) {
			if (vm.filters.userId !== params.userId) {
				vm.targetUser = null;
				vm.filters.userId = params.userId;
				if (params.userId) {
					$http.get('/Api/Users/' + params.userId)
						.then(function (response) {
							vm.targetUser = {
								name: response.data.username,
								id: response.data.id
							};
						}, lib.handleRestError);
				}
			}
		};

		$scope.gotoUser = function () {
			$location.search('page', null);
			$location.search('count', null);
			$location.search('userId', null);
			$location.path('/user-account').search('userId', vm.targetUser.id);
		};

		activate();
	}
})();
