/**
 * TasksCtrl Controller
 * Extracted from bookings module
 */

Bookings.controller('TasksCtrl', ['$scope', '$http', 'Tasks', 'Page', 'ErrorsHandler', '$ClientsManager', 'PartsService', 'CustomerNotificationsService', 'SalesBookingService', 'InvoiceBookingService', '$uibModal', 'Messenger', '$rootScope', 'TaskFeedback', '$AuthUser', 'CommentsService', function ($scope, $http, Tasks, Page, ErrorsHandler, $ClientsManager, PartsService, CustomerNotificationsService, SalesService, InvoiceService, $uibModal, Messenger, $rootScope, TaskFeedback, $AuthUser, CommentsService) {

	/**
	 * Notifies the user if any changes have been made to the original data
	 */
	$scope.modified = false;
	$scope.initialized = false;

	// 3CX Call functionality
	$scope.callInProgress = {};
	$scope.activeCall = null;

	/**
	 * All the boolean options in a dropdown menu
	 */
	$scope.boolean_options = [{ name: 'No', value: 0 }, { name: 'Yes', value: 1 }];
	$scope.payment_options = [{ name: 'not paid', value: 0 }, { name: 'paid', value: 1 }];
	$scope.auth = $AuthUser;


	/**
	 * Task history for cancelled and no price jobs
	 *
	 * @type Array of strings
	 */
	$scope.history = {
		cancelled_reasons: [],
		no_price_reasons: [],
	};


	/**
	 * The total price.
	 *
	 * @type Float
	 */
	$scope.total = 0;

	/**
	 * A reference to the PartsService object that hold
	 * all shared data related to parts.
	 *
	 * @type Object
	 */
	$scope.PartsService = PartsService;
	$scope.SalesService = SalesService;
	$scope.InvoiceService = InvoiceService;
	$scope.CustomerNotificationsService = CustomerNotificationsService;

	/**
	 * Watcher that checks to see when the data gets modified
	 */
	$scope.$watch('data', function (value) {
		if (typeof value != 'undefined' && value.id) {
			if ($scope.initialized) {
				$scope.modified = true;
			}
			$scope.taskType = $scope.data.type;
			$scope.initialized = true;
		}

	}, true);

	$scope.$watch('data.onsite_start', function (value) {
		if (typeof value == 'undefined' || $scope.data.type != 'onsite') return;
		$scope.data.onsite_start = (value == '0000-00-00 00:00:00') ? new Date() : moment(value).valueOf();
	});
	$scope.$watch('data.onsite_end', function (value) {
		if (typeof value == 'undefined' || $scope.data.type != 'onsite') return;
		$scope.data.onsite_end = (value == '0000-00-00 00:00:00') ? new Date() : moment(value).valueOf();
	});
	$rootScope.$on('task-updated', function () {
		$scope.modified = false;
	});

	/**
	 * Watch the labour and update the total price
	 * when this changes.
	 *
	 * @return void
	 */
	$scope.$watch('data.labour', function (value) {
		if (typeof value == 'undefined') return false;

		$scope.total = (parseFloat($scope.data.labour) + parseFloat(PartsService.getTotal())).toFixed(2);
	});

	$scope.$watch('PartsService.total', function () {
		if (typeof $scope.data == 'undefined') return false;
		$scope.total = (parseFloat($scope.data.labour) + parseFloat(PartsService.getTotal())).toFixed(2);
	});

	$scope.$watch('data.revision_history', function (value) {
		$scope.history.no_price_reasons = [];
		$scope.history.cancelled_reasons = [];
		_.each(value, function (revision) {

			if (revision.key == "no_price_reason")
				$scope.history.no_price_reasons.push(revision);
			else if (revision.key == "cancelled_reason")
				$scope.history.cancelled_reasons.push(revision);
		});

	}, true);


	/**
	 * Watch when the taskId becomes active and load the page.
	 *
	 * @return null
	 */
	$scope.$watch('taskId', function (value) {
		if (value) {
			$scope.loadData();
		}
	});

	// set browser tab title prefix
	$scope.$watch('data.type', function (value) {
		var browserTabTitlePrefix = undefined;
		if (typeof value != 'undefined') {
			browserTabTitlePrefix = $scope.getBrowserTabTitlePrefix(value);
			Page.setTitle(browserTabTitlePrefix + $scope.taskId);
		}
	});

	$scope.getBrowserTabTitlePrefix = function (type) {
		switch (type.toLowerCase()) {
			case 'onsite':
				return 'OS ';

				break;

			case 'support':
				return 'S ';

				break;

			case 'repair':
				return 'R ';

				break;

			default:
				return 'T ';
		}
	};

	$scope.registerWatchers = function () {
		$scope.prebook_date = $scope.data.prebook_date;
		$scope.$watch('prebook_date', function (value, oldValue) {
			if ($scope.initialized && value !== oldValue) {
				$scope.updateValue({ prebook_date: $scope.prebook_date, prebook: $scope.prebook_date ? 1 : 0 });
			}
			$('.datepicker').hide();
		});

		$scope.alarm_date = $scope.data.alarm_date;
	};

	$scope.setPrebook = function (value) {
		$scope.prebook_date = value ? moment().format('DD-MM-YYYY') : null;
	};

	$scope.getBooleanDisplay = function (value) {
		return (value == '1') ? 'Yes' : 'No';
	};

	$scope.getPaymentDisplay = function (value) {
		return (value == '1') ? 'paid' : 'not paid';
	};

	$scope.getSeverityDisplay = function (value) {
		return $scope.severities.hasOwnProperty(value) ? $scope.severities[value] : 'not set';
	};

	$scope.getSubtypeDisplay = function (value) {
		if (!$scope.data) return '';
		var subtype = _.find($scope.subtypes, function (el) { return el.id == value; });
		return subtype ? subtype.name : 'Not set';
	};

	$scope.getStandardPriceDisplay = function (value) {
		if (!$scope.data) return '';
		var price = _.find($scope.standard_prices, function (el) { return el.id == value; });
		return price ? price.name : 'Not set';
	};

	$scope.getShelfTypeDisplay = function (value) {
		if (!$scope.data) return '';
		var shelf = _.find($scope.shelf_types, function (el, id) { return id == value; });
		return shelf ? shelf : 'Not set';
	};

	$scope.getUserName = function (id) {
		if (!id) return 'No One';
		var user = _.find($scope.users, function (el) { return el.id == id; });
		return user ? user.name : 'No One';
	};

	$scope.getWorkerNames = function () {
		if (!$scope.data) return '';
		var names = _.pluck($scope.data.workers, 'name');
		return names.join(", ");
	};

	$scope.getTotalDays = function () {
		if (!$scope.data || !$scope.data.completed_at) return 0;
		return moment($scope.data.completed_at).diff($scope.data.created_at, 'days');
	};

	$scope.openLicensesModal = function () {
		$rootScope.$broadcast('open-licenses-modal');
	};

	/**
	 * Loads the repair data, by sending an ajax request.
	 *
	 * @returns void
	 */
	$scope.loadData = function () {
		Tasks.get({ taskId: $scope.taskId }, function (response) {
			$scope.data = response;
			$scope.modified = false;
			CustomerNotificationsService.setNotifications(response.customer_notifications);
			$ClientsManager.setClient(response.client);
			$ClientsManager.setClientType(response.client_type);

			// CRITICAL FIX: Call unify to properly map phone/email data from site_user
			$ClientsManager.unify(response.site, response.site_user);

			$scope.registerWatchers();
		}, ErrorsHandler);
	};

	$scope.updateValue = function (params) {
		angular.extend(params, { id: $scope.data.id, updated_at: $scope.data.updated_at });

		Tasks.update(params, function (response) {
			angular.extend($scope.data, response || {});
			$rootScope.$broadcast('task-updated', response);
			Messenger("I've succesfully saved the job!");
			CommentsService.loadComments({ related_type: 'task', related_id: $scope.data.id });

		}, ErrorsHandler);
	};

	$scope.updateStatus = function (status_id) {

		if (status_id == $scope.data.status_id)
			return;
		// Find the status being changed to
		var status = _.find($scope.statuses, function (el) { return el.id == status_id; });

		if (status && status.id == '9') {
			$scope.markAsQA();
		}
		else if (status && status.id == '8') {
			var modalInstance = $uibModal.open({
				templateUrl: 'bookings/modals/cancelled-reason.html',
				controller: 'ReasonModalCtrl',
			});

			modalInstance.result.then(function (reason) {

				$scope.updateValue({
					cancelled_reason: reason,
					status_id: status_id
				});
			});

		}
		else {
			$scope.updateValue({ status_id: status_id });
		}
	};

	$scope.markAsQA = function () {

		var status_id = '9';

		if ($scope.data.type == 'repair') {

			if (!$scope.data.unattended_time && !$scope.data.attended_time) {
				var modal = $uibModal.open({
					templateUrl: 'bookings/modals/dedicated-time.html',
					controller: 'TaskDedicatedTimeCtrl',
				});

				modal.result.then(function (response) {

					if (parseFloat($scope.data.labour) == 0 && !$scope.data.no_price_reason) {
						var modalInstance = $uibModal.open({
							templateUrl: 'modals/no-price-confirmation.html',
							controller: 'TaskNoPriceCtrl',
						});
						modalInstance.result.then(function (reason) {

							$scope.updateValue({
								attended_time: response.attended_time,
								unattended_time: response.unattended_time,
								no_price_reason: reason,
								status_id: status_id
							});
						});

					}
					else {
						$scope.updateValue({
							attended_time: response.attended_time,
							unattended_time: response.unattended_time,
							status_id: status_id
						});
					}
				});
			}
			else {
				if (parseFloat($scope.data.labour) == 0 && !$scope.data.no_price_reason) {
					var modalInstance = $uibModal.open({
						templateUrl: 'modals/no-price-confirmation.html',
						controller: 'TaskNoPriceCtrl',
					});
					modalInstance.result.then(function (reason) {

						$scope.updateValue({
							no_price_reason: reason,
							status_id: status_id
						});
					});

				}
				else {
					$scope.updateValue({
						status_id: status_id
					});
				}
			}

		}
		else {
			if (parseFloat($scope.data.labour) == 0 && !$scope.data.no_price_reason) {
				var modalInstance = $uibModal.open({
					templateUrl: 'modals/no-price-confirmation.html',
					controller: 'TaskNoPriceCtrl',
				});

				modalInstance.result.then(function (reason) {

					$scope.updateValue({
						no_price_reason: reason,
						status_id: status_id
					});
				});
			}
			else {
				$scope.updateValue({ status_id: status_id });
			}

		}
	};




	$scope.save = function () {
		// Data that will get saved
		var data = angular.copy($scope.data);

		// Remove onsite dates
		delete data.onsite_start;
		delete data.onsite_end;

		// Before saving format the paid_at value accordingly
		if (data.paid_at) data.paid_at = moment(data.paid_at).format("YYYY-MM-DD HH:mm:ss");

		Tasks.update(data, function (response) {
			angular.extend($scope.data, response || {});
			$rootScope.$broadcast('task-updated', response);
			Messenger("I've succesfully saved the job!");
		}, ErrorsHandler);
	};

	$scope.scrollTop = function () {
		$('body,html').animate({
			scrollTop: 0
		}, 800);
	};

	$scope.showLinkTaskModal = function () {
		var modalInstance = $uibModal.open({
			templateUrl: 'bookings/modals/related_tasks.html',
			controller: 'LinkTaskCtrl',
			resolve: {
				related_tasks: function () {
					return $scope.data.related_tasks;
				},
				currentTask: function () {
					return $scope.data;
				}
			}
		});
	};

	$scope.removeRelatedTask = function (task) {
		$scope.data.related_tasks = _.reject($scope.data.related_tasks, function (el) { return el.id == task.id; });
		$scope.save();
	};

	$scope.changeDates = function () {
		var modalInstance = $uibModal.open({
			templateUrl: 'modals/change-dates.html',
			controller: 'ChangeDatesCtrl',
			resolve: {
				data: function () {
					return $scope.data;
				}
			}
		});
	};

	$scope.changeAlarm = function () {
		var modalInstance = $uibModal.open({
			templateUrl: 'modals/change-alarm.html',
			controller: 'ChangeAlarmCtrl',
			resolve: {
				data: function () {
					return $scope.data;
				}
			}
		});

		modalInstance.result.then(function (timestamp) {
			$scope.updateValue({
				alarm_date: timestamp
			});
		});
	};

	$scope.deleteAlarm = function () {
		$scope.data.alarm_date = null;
		$scope.updateValue($scope.data);
	};

	$scope.changeDueDate = function () {
		var modalInstance = $uibModal.open({
			templateUrl: 'modals/change-alarm.html',
			controller: 'ChangeDueDateCtrl',
			resolve: {
				data: function () {
					return $scope.data;
				}
			}
		});

		modalInstance.result.then(function (timestamp) {
			$scope.updateValue({
				due_date: timestamp
			});
		});
	};

	$scope.deleteDueDate = function () {
		$scope.updateValue({
			'due_date': null
		});
	}

	$scope.showSubscribers = function () {
		var modalInstance = $uibModal.open({
			templateUrl: 'modals/subscribers.html',
			controller: 'SubscribersCtrl',
			resolve: {
				task: function () {
					return $scope.data;
				},
				users: function () {
					return $scope.users;
				}
			}
		});
	};

	$scope.cancelFeedback = function () {
		TaskFeedback.delete({ taskFeedbackId: $scope.data.feedback.code }, function (response) {
			Messenger("The feedback request was canceled.");
			$scope.data.feedback = null;
		}, ErrorsHandler);
	};

	$scope.unassign = function () {
		Tasks.update({ id: $scope.data.id, assigned_to: null, updated_at: $scope.data.updated_at }, function (response) {
			angular.extend($scope.data, response || {});
			$rootScope.$broadcast('task-updated', response);
		}, ErrorsHandler);
	};

	$scope.subscribe = function () {
		$scope.data.subscribers.push($AuthUser.data);

		Tasks.update({ id: $scope.data.id, subscribers: $scope.data.subscribers }, function (response) {
			angular.extend($scope.data, response || {});
			$rootScope.$broadcast('task-updated', response);
			Messenger("You have succesfully subscribed to this task.");
		}, ErrorsHandler);
	};

	$scope.unsubscribe = function () {
		$scope.data.subscribers = _.reject($scope.data.subscribers, function (el) { return el.id == $AuthUser.data.id; });

		Tasks.update({ id: $scope.data.id, subscribers: $scope.data.subscribers }, function (response) {
			angular.extend($scope.data, response || {});
			$rootScope.$broadcast('task-updated', response);
			Messenger("You have succesfully un-subscribed from this task.");
		}, ErrorsHandler);
	};

	$scope.createExchangeCalendarEvent = function () {
		$scope.creatingCalendarEvent = true;

		Tasks.createExchangeCalendarEvent({ id: $scope.data.id }, function (response) {
			$scope.creatingCalendarEvent = false;
			angular.extend($scope.data, response || {});
			$rootScope.$broadcast('task-updated', response);
			Messenger("A new calendar entry was succesfully created");
		}, function (a, b) {
			$scope.creatingCalendarEvent = false;
			ErrorsHandler(a, b);
		});
	};

	//
	$scope.showHistory = function (title, historyEntries) {
		var modalInstance = $uibModal.open({
			templateUrl: 'bookings/modals/history.html',
			controller: 'HistoryCtrl',
			resolve: {
				title: function () {
					return title;
				},
				historyEntries: function () {
					return historyEntries;
				},
				users: function () {
					return $scope.users;
				}
			}
		});

	};


	$scope.generateInvoice = function (data) {
		if (data.status_id == 9)
			alert("An invoice can not be create until the job pass the QA.");
		else if (PartsService.hasPartsOnOrder())
			alert("It is not possible to create an invoice for parts on order.");
		else
			InvoiceService.generate(data)
	};


}]);
