/**
 * widgetPartsCtrl Controller
 * Extracted from bookings module
 */

Bookings.controller('widgetPartsCtrl', ['$scope', 'PartsService', 'Part', 'ErrorsHandler', '$timeout', '$q', 'Messenger', '$uibModal', function ($scope, PartsService, Part, ErrorsHandler, $timeout, $q, Messenger, $uibModal) {

	/**
	 * Repair parts
	 *
	 * @array
	 */
	$scope.parts = PartsService.parts;

	$scope.$watch('related', function (related) {
		if (related)
			PartsService.setParts(related.parts);
	}, true);

	$scope.$watch('parts', function () {
		$scope.partTotal();
		PartsService.setSubtotal($scope.subtotal());
		PartsService.setTax($scope.tax());
		PartsService.setTotal(PartsService.getSubtotal() + PartsService.getTax());
	}, true);

	/**
	 * Stores a new part.
	 *
	 * @param  ev $event
	 * @param  object data - part data
	 * @return void
	 */
	$scope.addPart = function (ev, data) {

		var part = _.find($scope.parts, function (el) {
			if (el.stock)
				return el.stock.id == data.id;
			return false;
		});

		$scope.$apply(function () {


			if (part) {
				part.quantity++;
				Part.update(part, function (response) {
					part.saved = true;
					angular.extend(part, response || {});
				}, function (a, b) {
					part.failed = true;
					ErrorsHandler(a, b);
					part.quantity--;
				});

			} else {

				Part.save({
					related_id: $scope.related.id,
					related_type: $scope.related_type,
					stock_id: data.id,
					quantity: 1,
					price: data.price_excluding_vat
				}, function (res) {

					$scope.parts.push(res);
					if ($scope.related_type == 'user')
						$scope.related.parts.push(res);

				}, function (a, b) {
					ErrorsHandler(a, b);
					return false;
				});
			}
		});

	};

	/**
	 * Removes a part from the part list.
	 *
	 * @param  object  the part to be removed
	 * @return void
	 */
	$scope.removePart = function (part) {
		// console.log('part', part);
		Part.remove({ partId: part.id }, function () {
			var index = _.findIndex($scope.parts, function (el) {
				return el.id === part.id;
			});

			$scope.parts.splice(index, 1);

			if ($scope.related_type == 'user')
				$scope.related.parts.splice(index, 1);

		}, ErrorsHandler);
	};

	/**
	 * Updates an existing part.
	 *
	 * @return void
	 */
	$scope.updatePart = function (part) {

		Part.update(part, function (response) {
			part.saved = true;
			// part.updated_at = response.updated_at;
			angular.extend(part, response || {});
		}, function (a, b) {
			part.failed = true;
			ErrorsHandler(a, b);
		});

		$timeout(function () {
			part.saved = false;
			part.failed = false;
		}, 1500);
	};

	/**
	 * Update a single property of a part
	 *
	 * @param  object part
	 * @param  string property
	 * @param  mixed value
	 * @return null
	 */
	$scope.updatePartProperty = function (part, property, value) {
		var deferred = $q.defer();
		var data = {
			id: part.id,
			updated_at: part.updated_at,
		};

		// Build the data object
		data[property] = value;

		Part.update(data, function (response) {
			// Check to see if the part was on order before
			// and now it's not anymore and let the user know
			if (part.on_order == '1' && response.on_order == '0') {
				Messenger('Your part was removed from the order because the quantity requested is currently available.');
			}

			angular.extend(part, response || {});
			deferred.resolve(true);
		}, function (a, b) {
			ErrorsHandler(a, b);
			deferred.reject(false);
		});

		return deferred.promise;
	};

	/**
	 * Updates the total price for a part and it automatically
	 * updates the ex vat price.
	 *
	 * @return void
	 */
	$scope.updateTotalPrice = function (part) {
		part.price = (part.total_price / part.quantity / (part.vat / 100 + 1)).toFixed(2);
		$scope.updatePart(part);
	};

	/**
	 * Calcualate the total price for each individual part
	 * @return {[type]} [description]
	 */
	$scope.partTotal = function () {
		_.each($scope.parts, function (part) {
			if (part.price && part.quantity && part.vat) {
				part.total_price = part.price * part.quantity * (part.vat / 100 + 1);
			}
		});
	};

	/**
	 * Calculates the total price for parts.
	 *
	 * @return float
	 */
	$scope.total = function () {
		return $scope.subtotal() + $scope.tax();
	};

	/**
	 * Calculates the total tax for parts.
	 *
	 * @return float
	 */
	$scope.tax = function () {
		var tax = 0;

		_.each($scope.parts, function (el) { 
			if (el.price && el.quantity && el.vat) {
				tax += el.price * el.quantity * el.vat / 100; 
			}
		});

		return tax;
	};

	/**
	 * Calculates the total for the parts, excluding tax.
	 *
	 * @return float
	 */
	$scope.subtotal = function () {
		var total = 0;

		_.each($scope.parts, function (el) { 
			if (el.price && el.quantity) {
				total += el.price * el.quantity; 
			}
		});

		return total;
	};


	/**
	 * Calculates the total for the parts, excluding tax.
	 *
	 * @return float
	 */
	$scope.cost = function () {
		var cost = 0;

		_.each($scope.parts, function (el) {
			if (el.stock && el.stock.cost && el.stock.cost !== 'NA') {
				cost += el.stock.cost * el.quantity;
			}
		});

		return cost;
	};

	$scope.updateCompositeItems = function (part) {
		var modalInstance = $uibModal.open({
			controller: 'PartCompositeItemsCtrl',
			templateUrl: 'bookings/modals/part-composite-items.html',
			resolve: {
				part: function () {
					return part;
				}
			}
		});

		modalInstance.result.then(function (data) {
			angular.extend(part, data || {});
		});
	};


}])
