/**
 * @author hector
 * */

/**
 * knockoutjs model&view main object
 */
var cuentaModelView = {
	entityId : ko.observable(),
	cuentas : ko.observableArray(new Array()),
	pagos : ko.observableArray(new Array()),
	pagosWrapper : ko.observable({
		pagos : this.pagos
	}),
	mediosPago : ko.observableArray(new Array()),
	monedas : ko.observableArray(new Array()),
	selectedPaymentValue : ko.observable(0),
	selectedMonedaValue : ko.observable(0),
	selectedCuenta : ko.observable(0),
	nuevoMonto : ko.observable(''),
	concept : ko.observable(''),
	amountAccount : ko.observable(''),
	dueDate : ko.observable(''),
	destinyAccount : ko.observable(''),
	openOnlyOption : ko.observable(true),
	entidades : ko.observableArray(new Array()),
	entidadDescripcion : ko.observable(),
	paymentTotal : ko.observable(0),
	paymentCuentaTotal : ko.observable(0),
	comentarios : ko.observableArray(new Array()),
	comment : ko.observable(''),
	commentCuenta : ko.observable(0),
	attachments : ko.observableArray(new Array()),
	selectedEntidad : ko.observable({
		descripcion : ''
	}),
	accountsTotal : ko.observable(0),
	estatusCuentas : ko.observableArray(new Array()),
	paymentsTotalByEntidad : ko.observable(0),

	loadCuentasFromEntidades : function(entidad) {
		cuentaModelView.selectedEntidad(entidad);
		cuentaModelView.entityId(entidad.id);
		cuentaModelView.loadCuentas();
		
		$('#entidadNameBtn').popover({
			content 	: pluto.getEntityActionsContent(),
			html  		: true,
			placement 	: 'right',
			trigger 	: 'focus',
			title 		: 'Edit/Delete'
		});
	},

	loadCuentas : function() {
		return pluto.getCuentasInformation(cuentaModelView.entityId());
	},

	openPagos : function(cuenta) {
		cuentaModelView.paymentCuentaTotal(0);
		cuentaModelView.paymentCuentaTotal(cuenta.monto);
		pluto.getPagosInformation(cuenta.id);
	},

	clearPagosInformation : function() {
		cuentaModelView.pagos.removeAll();
	},

	addPayment : function(cuenta) {
		pluto.resetFields('p')
		if (cuentaModelView.mediosPago().length == 0) {
			pluto.cargarMedioPago();
		}
		cuentaModelView.selectedPaymentValue('');
		cuentaModelView.selectedCuenta(cuenta.id);
		$("#btnSavePayment").prop('disabled', false);
	},

	savePayment : function() {
		if (pluto.validate(pluto.addPaymentValidation.validate())) {
			pluto.savePaymentData();
		}
	},

	saveAccount : function() {
		if (pluto.validate(pluto.addModifyAccountValidation.validate())) {
			pluto.saveAccountData();
		}
	},

	addAccount : function() {
		pluto.isAccountUpdate = false;
		pluto.resetFields('a');
		$("#btnSaveAccount").prop('disabled', false);
		cuentaModelView.selectedMonedaValue('');
	},

	markAsClosed : function(cuenta) {
		if (window.confirm('Are you sure you want to mark this as complete?')) {
			pluto.modifyCuentaEstatus(cuenta.id);
		}
	},
	removePayment : function(payment) {
		if (window.confirm("Really?")) {
			pluto.removePaymentAction(payment.id, payment.cuentaId);
		}
	},
	addEntity : function() {
		pluto.resetFields('e');
		pluto.isEntityUpdate = false;
		$("#btnSaveEntity").prop('disabled', false);
	},
	saveEntity : function() {
		if (pluto.validate(pluto.entidadValidation.validate())) {
			pluto.saveEntityData();
		}
	},
	loadComentarios : function(cuenta) {
		pluto.loadComentarios(cuenta.id);
	},
	addComment : function(cuenta) {
		pluto.log("addComment...");
		$("#savingCommAlert").hide();
		$("#btnSaveComment").prop('disabled', false);
		cuentaModelView.comment('');
		cuentaModelView.commentCuenta(cuenta.id);
	},
	saveComment : function() {
		pluto.log("saveComment...");
		if (pluto.validate(pluto.addCommentsValidation.validate())) {
			pluto.log("saving.." + cuentaModelView.comment());
			pluto.saveComment(cuentaModelView.comment(), cuentaModelView
					.commentCuenta());
		}
	},
	openNewFile : function(cuenta) {
		if (pluto.fileUploadSend != null)
			pluto.fileUploadSend.finalize();
		$("#uploadingBanner").hide();
		pluto.fileUploadSend = new FileSend({
			formName : 'plutoAccountForm',
			action : '/upload',
			callback : 'pluto.fileUploadCallback',
			fileTypes : [ 'png', 'pdf', 'jpeg','jpg','doc','docx','xls','xlsx' ],
			idUploadButton : 'docUpload',
			additionalParameters : {
				idCuenta : cuenta.id
			}
		});

		pluto.fileUploadSend.observeElement($('#newFile')[0]);
	},
	loadAttachments : function(cuenta) {
		pluto.loadAttachments(cuenta.id);
	},
	removeAttachment : function(attachment) {
		if (window.confirm("Do you want to delete the attachment?")) {
			pluto.removeAttachmentAction(attachment.id);
		}
	},
	updateEntidadAction : function() {
		cuentaModelView.entidadDescripcion(cuentaModelView.selectedEntidad().descripcion);
		pluto.isEntityUpdate = true;
	},
	deleteEntity : function() {
		if(window.confirm("Do you want to disable the entity?")){
			pluto.disableEntity();
		}
	},
	updateAccountAction : function(cuenta){
		pluto.accountUpdate = cuenta;
		cuentaModelView.addAccount();
		pluto.isAccountUpdate = true;
		pluto.setAccountFieldsFromAccObject();
	}
},
/**
 * Common methods for the app
 */
pluto = {
	simpleMode : false,
	openStatus : 1,
	closedStatus : 2,
	logginEnabled : false,
	log : function(message) {
		if (this.logginEnabled) {
			console.log(message);
		}
	},
	contextPath : '',
	fileUploadSend : null,
	isEntityUpdate : false,
	isAccountUpdate :false,
	accountUpdate : {},
	reloadCuentas : function() {
		cuentaModelView.loadCuentas();
	},
	/**
	 * Filter the array given the property and expected value. Accepts
	 * property.innerpropery
	 */
	filterByCriteria : function(array, propertyName, value) {
		if (array == null || array.length == 0)
			return array;

		var propertyNames = propertyName.split(".");
		var multiProp = propertyNames != null && propertyNames.length > 0;

		array.forEach(function(element, index, array) {
			$.each(element, function(key, element) {
				var tmpProp = propertyNames[0];

				if (element != null && tmpProp == key) {
					if (typeof (element) == "object" && multiProp) {
						$.each(element,
								function(keyI, elementI) {
									if (propertyNames[1] == keyI
											&& elementI == value) {
										
									} else if (propertyNames[1] == keyI) {
										array[index] = null;
									}
								});
					} else if (element == value) {
						
					}
				}
			});
		});

		array = jQuery.grep(array, function(n, i) {
			return (n !== "" && n != null);
		});
		return array;
	},
	getCuentasInformation : function(idEntidad) {
		pluto.log("Cuentas by entidad: " + idEntidad);
		if(idEntidad === null || idEntidad ===  undefined)return;

		$("#userValidateMess").hide();
		cuentaModelView.accountsTotal(0);
		pluto.runMeAsync(pluto.getTotalPaymentsByEntidad);
		
		$.getJSON(pluto.contextPath + "/rv1/cuenta/list/" + idEntidad,
				function(data) {

					if (cuentaModelView.openOnlyOption()) {
						data = pluto.filterByCriteria(data, 'estatusCuenta.id',
								pluto.openStatus);
					}

					cuentaModelView.cuentas.removeAll();
					var total = 0;
					data.forEach(function(dat) {
						cuentaModelView.cuentas.push(dat);
						total += dat.monto;
					});
					cuentaModelView.accountsTotal(total);
				}).fail(pluto.requestErrorHandling);
	},
	getPagosInformation : function(idCuenta) {
		pluto.log("idCuenta: " + idCuenta);
		if (idCuenta == undefined || idCuenta == null)
			return;

		$.getJSON(pluto.contextPath + "/rv1/pago/list/" + idCuenta, function(
				data) {
			pluto.log(data);
			cuentaModelView.pagos.removeAll();
			var total = 0;
			cuentaModelView.paymentTotal(total);
			data.forEach(function(dat) {
				cuentaModelView.pagos.push(dat);
				total += dat.monto;
			});
			pluto.log("Pagos: " + cuentaModelView.pagos().length);
			cuentaModelView.paymentTotal(total);
		}).fail(pluto.requestErrorHandling);
	},
	cargarMedioPago : function() {
		$.getJSON(pluto.contextPath + "/rv1/catalogo/medioPago",
				function(data) {
					cuentaModelView.mediosPago.removeAll();

					data.forEach(function(dat) {
						cuentaModelView.mediosPago.push(dat);
					});
				}).fail(pluto.requestErrorHandling);
	},
	cargarMonedas : function() {
		$.getJSON(pluto.contextPath + "/rv1/catalogo/monedas",
				function(data) {
					cuentaModelView.monedas.removeAll();

					data.forEach(function(dat) {
						cuentaModelView.monedas.push(dat);
					});
				}).fail(pluto.requestErrorHandling);
	},
	savePaymentData : function() {
		var jsonPayment = JSON.stringify({
			medioPago : {
				id : cuentaModelView.selectedPaymentValue()
			},
			monto : pluto.formatInputAmmount(cuentaModelView.nuevoMonto()),
			cuentaId : cuentaModelView.selectedCuenta(),
			usuario : {
				id : $('#identU').val()
			}
		/** temporary make it default */
		});

		$("#savingAlert").show();

		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/pago/save",
			data : jsonPayment,
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				$("#savingAlert").hide();
				$('#paymentAddModal').modal('hide');
				$("#btnSavePayment").prop('disabled', true);
				pluto.runMeAsync(pluto.getTotalPaymentsByEntidad);
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});
	},
	saveAccountData : function() {
		var accToSave = pluto.isAccountUpdate ? pluto.accountUpdate : {};
		
		accToSave.concepto = cuentaModelView.concept();
		accToSave.monto = pluto.formatInputAmmount(cuentaModelView.amountAccount());
		accToSave.fechaLimite = cuentaModelView.dueDate();
		accToSave.destino = cuentaModelView.destinyAccount();
		accToSave.moneda = {id : cuentaModelView.selectedMonedaValue()};
		
		if(!pluto.isAccountUpdate){
			accToSave.entidad = {
				id : cuentaModelView.entityId()
			};
			accToSave.usuario = {
				id : $('#identU').val()
			};
		}
		
		var jsonPayment = JSON.stringify(accToSave);

		pluto.log(jsonPayment);
		$("#savingAlertA").show();

		var endpoint = pluto.isAccountUpdate?'update':'save';
		
		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/cuenta/"+endpoint,
			data : jsonPayment,
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				$("#savingAlertA").hide();
				$("#accountAddModal").modal("hide");
				$("#btnSaveAccount").prop('disabled', true);
				cuentaModelView.selectedMonedaValue('');
				pluto.reloadCuentas();
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});
	},
	modifyCuentaEstatus : function(idCuenta) {
		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/cuenta/" + idCuenta
					+ "/estatus/update/" + pluto.closedStatus,
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				pluto.log(data);
				pluto.reloadCuentas();
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});
	},
	resetFields : function(type) {
		if (type == 'p') {
			cuentaModelView.selectedPaymentValue('');
			cuentaModelView.nuevoMonto('');
			$("#savingAlert").hide();
			pluto.addPaymentValidation.reset();

		} else if (type == 'a') {
			cuentaModelView.concept('');
			cuentaModelView.amountAccount('');
			cuentaModelView.dueDate('');
			cuentaModelView.destinyAccount('');

			$("#savingAlertA").hide();
			pluto.addModifyAccountValidation.reset();
		} else if (type == 'e') {
			cuentaModelView.entidadDescripcion('');
			$("#savingAlertEntity").hide();
			$("#savedAlertEntity").hide();
			pluto.entidadValidation.reset();
		}
	},
	cargarListaEntidades : function() {
		$.getJSON(pluto.contextPath + "/rv1/entidad/list/"+$('#identU').val(), function(data) {
			cuentaModelView.entidades.removeAll();

			data.forEach(function(dat) {
				cuentaModelView.entidades.push(dat);
			});
		}).fail(pluto.requestErrorHandling);
	},
	removePaymentAction : function(idPayment, idAccount) {
		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/pago/delete/" + idPayment,
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				pluto.log(data);
				pluto.getPagosInformation(idAccount);
				pluto.runMeAsync(pluto.getTotalPaymentsByEntidad);
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});
	},
	saveEntityData : function() {
		pluto.log('saveEntityData');
		var entidadToSave =  pluto.isEntityUpdate ? cuentaModelView.selectedEntidad() : { idUsuario : $('#identU').val() ,estatusCuenta:{id: pluto.openStatus }};
		entidadToSave.descripcion = cuentaModelView.entidadDescripcion();
		
		var jsonPayment = JSON.stringify(entidadToSave);
		pluto.log(jsonPayment);
		$("#savingAlertEntity").show();
		var endpoint = pluto.isEntityUpdate ? 'update':'save';
		
		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/entidad/"+endpoint,
			data : jsonPayment,
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				$("#savingAlertEntity").hide();
				$("#btnSaveEntity").prop('disabled', false);
				$('#entityAddModal').modal('hide');
				pluto.cargarListaEntidades();
				
				if(pluto.isEntityUpdate){
					cuentaModelView.loadCuentasFromEntidades(entidadToSave);
				}
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});
		
	},
	validate : function(validationObject) {
		return validationObject == true || validationObject.length == 0;
	},
	registerValidations : function() {
		/** Entidades */
		pluto.entidadValidation = $('#descriptionEntity').parsley();
		/** Pago */
		pluto.addPaymentValidation = $('#payment-form').parsley();
		/** Account */
		pluto.addModifyAccountValidation = $('#addmodifyaccount-form')
				.parsley();
		/** Comments */
		pluto.addCommentsValidation = $('#comment-form').parsley();
	},
	loadComentarios : function(idCuenta) {
		if (idCuenta == undefined || idCuenta == null)
			return;

		$.getJSON(pluto.contextPath + "/rv1/comentario/cuenta/"
						+ idCuenta,
						function(data) {
							cuentaModelView.comentarios.removeAll();

							data.forEach(function(dat) {
								cuentaModelView.comentarios.push(dat);
							});
							pluto.log("Comentarios: "
									+ cuentaModelView.comentarios().length);
		}).fail(pluto.requestErrorHandling);
	},
	saveComment : function(comment, idCuenta) {
		if (idCuenta == undefined || idCuenta == null)
			return;
		pluto.log("saveComment");

		var jsonArray = new Array();
		var commentJson = {
			comentario : comment,
			cuenta_id : idCuenta
		};
		jsonArray.push(commentJson);

		$("#savingCommAlert").show();

		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/comentario/cuenta/save",
			data : JSON.stringify(jsonArray),
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				$("#savingCommAlert").hide();
				$("#commentAddModal").modal('hide');
				$("#btnSaveComment").prop('disabled', true);
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});

		cuentaModelView.commentCuenta(0)
	},
	calculateRemainTotal : function(total, paymentTotal) {
		if (isNaN(total) || isNaN(paymentTotal))
			return 'ERR';
		return total - paymentTotal;
	},
	fileUploadCallback : function(statusMessage) {
		pluto.fileUploadSend.reset($('#newFile')[0]);
		$('#fileAddModal').modal('toggle');
	},
	loadAttachments : function(idCuenta) {
		pluto.log("loadAttachments(idCuenta): " + idCuenta);
		if (idCuenta == undefined || idCuenta == null)
			return;

		$.getJSON(pluto.contextPath + "/rv1/adjunto/cuenta/" + idCuenta,
				function(data) {
					cuentaModelView.attachments.removeAll();

					data.forEach(function(dat) {
						cuentaModelView.attachments.push(dat);
					});
					pluto.log("Adjuntos: "
							+ cuentaModelView.attachments().length);
		}).fail(pluto.requestErrorHandling);
	},
	removeAttachmentAction : function(attachmentId) {
		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/adjunto/delete/" + attachmentId,
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				pluto.log(data);
				$('#attachmentsModal').modal("hide");
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});
	},
	cargarCatalogos : function() {
		$.getJSON(pluto.contextPath + "/rv1/catalogo/estatus", function(data) {
			cuentaModelView.estatusCuentas.removeAll();

			data.forEach(function(dat) {
				cuentaModelView.estatusCuentas.push(dat);
			});
			pluto.log("Catalogo Estatus: "
					+ cuentaModelView.estatusCuentas().length);
		}).fail(pluto.requestErrorHandling);
	},
	disableEntity : function(){
		$.ajax({
			type : "POST",
			url : pluto.contextPath + "/rv1/entidad/delete/" + cuentaModelView.entityId(),
			contentType : "application/json; charset=utf-8",
			success : function(data) {
				pluto.log(data);
				cuentaModelView.entityId(0);
				pluto.cargarListaEntidades();
				cuentaModelView.cuentas.removeAll();
				cuentaModelView.selectedEntidad({descripcion:''});
			},
			dataType : 'json',
			error : pluto.requestErrorHandling
		});
	},
	getEntityActionsContent : function(elmt){
		return  "<center><a data-toggle='modal' data-target='#entityAddModal' onclick='cuentaModelView.updateEntidadAction()' class='glyphicon glyphicon-pencil'></a> " +
			" <a onclick='cuentaModelView.deleteEntity()' class='glyphicon glyphicon-remove'></a></center>";
	},
	setAccountFieldsFromAccObject : function(){
		cuentaModelView.concept(pluto.accountUpdate.concepto);
		cuentaModelView.amountAccount(pluto.accountUpdate.monto);
		cuentaModelView.dueDate(formatter.formatDateSave(pluto.accountUpdate.fechaLimite));
		cuentaModelView.destinyAccount(pluto.accountUpdate.destino);
		
		if(pluto.accountUpdate.moneda != null){
			cuentaModelView.selectedMonedaValue(pluto.accountUpdate.moneda.id);
			pluto.log("currency set");
		}
	},
	getTotalPaymentsByEntidad : function() {
		var idEntidad = cuentaModelView.entityId();
		pluto.log("getTotalPaymentsByEntidad(idEntidad): " + idEntidad);
		cuentaModelView.paymentsTotalByEntidad(0);
		var status = cuentaModelView.openOnlyOption() ? 'y':'n';
		
		$.getJSON(pluto.contextPath + "/rv1/pago/cuenta/entidad/" + idEntidad +"?openOnly="+status,
				function(data) {
					cuentaModelView.paymentsTotalByEntidad(data);
		}).fail(pluto.requestErrorHandling);
	},
	runMeAsync : function(func_){
		setTimeout(func_, 0);
	},
	createAndConfigureLogout : function(){
		$('body').append('<div id="logoutBtn"class="fa"><a class="glyphicon glyphicon-off" href="/logout" title="Logout"></a></div>');
	},
	uploadFile : function(){
		$("#uploadingBanner").show();
		$("#docUpload").prop('disabled', true);
		pluto.fileUploadSend.upload();
	},
	requestErrorHandling : function(request, status, error){
		pluto.log(request);
		pluto.log(status);
		pluto.log(error);
		
		if(request && request.status == 401){
			pluto.unauthorizedHandler();
		}
	},
	unauthorizedHandler : function(){
		alert("Your session is expired");
		window.location = "/logout";
	},
	formatInputAmmount : function(ammount){
		return isNaN(ammount) ? ammount.replace(/^(.+?\.\d+).+/g, "$1").replace(/[^\d.]+/g, "") : ammount;
	}
},
/**
 * Formatter name space
 */
formatter = {
	formatDate : function(date) {
		if (date != null) {
			return (new Date(date)).format("dd/mm/yyyy");
		}
		return "";
	},
	formatDateSave : function(date) {
		if (date != null) {
			return (new Date(date)).format("yyyy-mm-dd");
		}
		return "";
	},
	formatCurrency : function(ammount) {
		return isNaN(ammount) ? "" : "$ " + ammount.formatMoney(2, '.', ',');
	}
};

/**
 * Initialization of listeners
 */
$(function() {
	$("#dueDate").datepicker();
	$("#dueDate").datepicker("option", "dateFormat", "yy-mm-dd");

	/** When the value for the open only combo box change it rises this event */
	cuentaModelView.openOnlyOption.subscribe(function(newValue) {
		pluto.reloadCuentas();
	});

	/** Assign actions after modal is opened */
	$('#paymentAddModal').on('shown.bs.modal', function() {
		$("#amount").focus();
	});
	$('#accountAddModal').on('shown.bs.modal', function() {
		$("#concept").focus();
	});
	$('#entityAddModal').on('shown.bs.modal', function() {
		$("#descriptionEntity").focus();
	});
	$('#commentAddModal').on('shown.bs.modal', function() {
		$("#comments").focus();
	});

	/** Register content type for ajax request */
	$.ajaxSetup({
		contentType : "application/json; charset=utf-8",
		headers: { 'atkn': $('#atkn').val() }
	});
	
	pluto.registerValidations();
	pluto.cargarListaEntidades();
	//pluto.cargarCatalogos();
	
	$(document).ready(function(){
		pluto.runMeAsync(pluto.createAndConfigureLogout);
		pluto.runMeAsync(pluto.cargarMonedas);
	});
});