var w = (window || top.window);
var $j = w.jQuery;

console.log("KrotonUtils loading!");

$j.fn.isBound = function(fn) {
	return $j._data($j(this)[0], "events")[fn] != undefined
};

$j.extend({
	kf : {
		toString : function(j) {
			return JSON.stringify(j);
		},
		view : function() {
			if(location.href.indexOf("/pdc") > -1)
				return "pdc";
			else if(location.href.indexOf("/pda") > -1)
				return "pda";
			else
				return "";
		},
		blockUI : function(show) {
			console.log("blockUI : " + show);
			if(show) {
				$j('#blockUI').modal({backdrop: 'static', escapeClose: false, clickClose: false, showClose: false});
				$j('.modal-backdrop.in').css('opacity', '0.1');
			} else {
				$j('#blockUI').modal('hide');
				$j('body').removeClass('modal-open');
				$j('.modal-backdrop').remove();
			}
		},
		attachs : function(g_form, ...a) {
			a = a || [];
			var i = angular.element("#sc_cat_item").scope().attachments.length;
			if(i < a.length) {
				g_form.addErrorMessage('É necessário anexar todos os arquivos. Favor incluir os ' + 
									   (a.length - i)  + ' arquivo(s) restantes. ( ' + a.join(", ") + ' )');
			}
			return i >= a.length;
		},
	}
});

$j.extend({
	k : function(c) {
		var g_form = c.$scope.page.g_form || c.spUtil;

		var jk = {
			//*** Utils ****
			allVisibleFields : function() {
				var j = {};
				$j.each(g_form.getFieldNames(), function(k, v) {
					if(g_form.isVisible(v) && g_form.getValue(v).trim() != "" && g_form.getLabelOf(v))
						j[v] = g_form.getValue(v);
				});
				return j;
			},
			varToJson : function(...a) {
				var j = {};
				$j.each(a, function(k, v) {
					var s = v.split("=");
					j[s[0]] = g_form.getValue((s.length == 1 ? s[0] : s[1]));
				});
				return j;
			},
			filter : function(type, value) {
				return c.$filter(type)(value);				
			},
			selected : function(f, p) {
				f = f || "items";
				p = p || { Selected: true };
								
				return c.$filter('filter')(c[f], p) || [];
			},
			
			selectRadio : function(items, itemSelected){
				items.forEach(element => {
					element.Selected = false;
				});
				itemSelected.Selected = true;
			},

			isSelected : function(f, p) {
				return jk.selected(f, p).length > 0;
			},
			
			comboModel : function(name) {
				return c.$filter('filter')(c.$scope.$root.DataModel[name], { Value : g_form.getValue(name) })[0];				
			},
			
			dataModel : function(name) {
				return c.$scope.$root.DataModel[name] || [];				
			},

			//*** Service ****
			get : function(step, params, showMessage) {
				return this.service(step, 'get', params);
			},
			getCombo : function(step, params, objKey, name, valueKey, textKey, cascade) {
				var combo = this.combo;
				combo([], name);
				return this.service(step, 'get', params).then(function(r) {
					combo((r.Dados || r.Data)[objKey], name, valueKey, textKey, cascade);
				});
			},
			getComboCascade : function(step, params, objKey, name, valueKey, textKey) {
				return this.getCombo(step, params, objKey, name, valueKey, textKey, true);
			},
			post : function(step, params) {
				return this.service(step, 'post', params);
			},
			service : function(step, method, params) {
				$j.kf.blockUI(true);
				return new Promise(function(resolve, reject) {
					if(c.route == undefined) {
						c.$scope.server.get({ Method: method, Step : step, Params : params}).then(function(r) {
							//alert($j.kf.toString(r));
							if(r.data.Service.Error == false) {
								//if(r.data.Service.Message) 
								//	g_form.addInfoMessage(r.data.Service.Message);
								resolve(r.data.Service);
							} else {
								reject(r.data.Service);
								console.log("Erro ao invocar a API: " + $j.kf.toString(r));
								g_form.addErrorMessage(r.data.Service.Message || "Erro ao invocar a API.");
							}

							$j.kf.blockUI(false);
						})						
					} else {
						console.log("Rota : " + (c.route + step));
						c.$http($j.extend({ method: method, url: c.route + step }, params)).then(
							function successCallback(response) {
								//console.log("Rota : " + (c.route + step) + "Result" + JSON.stringify(response.data.result));
								resolve(response.data.result);
								//c.$scope.$apply();
								$j.kf.blockUI(false);
							}, function errorCallback(response) {
								reject(response);
								$j.kf.blockUI(false);
								errorCallbackAPI(c.$scope.page, response);
							}
						);
					}
				});
			},

			//*** Form ****
			submit : function(r, json) {
				json = (json || {});
				json.Submit = r.Data;
				g_form.setValue("json", JSON.stringify(json || {}));
				w.document.mensagem = r.Mensagem || r.Message; w.document.submit = true; g_form.submit(); 
			},
			trigger : function(name, fn, type) {
				$j(w.document).off(name).on(name, function(ev, p1) { fn(type, p1); });
			},
			attachs : function(...a) {
				a = a || [];
				var i = angular.element("#sc_cat_item").scope().attachments.length;
				if(i < a.length) {
					g_form.addErrorMessage('É necessário anexar todos os arquivos. Favor incluir os ' + 
											(a.length - i)  + ' arquivo(s) restantes. ( ' + a.join(", ") + ' )');
				}
				return i >= a.length;
			},
			errorMessage : function(msg, bln) {
				if(bln) g_form.addErrorMessage(msg);
				return bln;
			},

			//*** Field ****
			combo : function(obj, name, valueKey, textKey, cascade) {
				
				valueKey = valueKey || "Value";
				textKey = textKey || "Text";
				//console.log(c.$scope);
				c.$scope.$root.DataModel = c.$scope.$root.DataModel || {};
				c.$scope.$root.DataModel[name] = obj || [];

				jk.field(name, "clear=1", "disabled=0");
				obj.forEach(function(item) {
					g_form.addOption(name, item[valueKey].toString(), item[textKey].toString());
				});

				var el =  $j("[id$='" + name + "'] .select2-container");
				
				el.removeClass("select2-container-disabled").css("pointer-events", "auto").find(".select2-search, .select2-results").show();

				if(obj.length == 1) {
					jk.field(name, "mandatory=0", "disabled=1", "value="+ obj[0][valueKey]);
				} else if(obj.length == 0){
					el.addClass("select2-container-disabled").css("pointer-events", "none").find(".select2-search, .select2-results").hide();
				}
				
				if(cascade)
					jk.field(name, "mandatory=" + (obj.length > 0), "visible=" + (obj.length > 0));
					
			},
			comboAddOptions : function(name, ...o) {
				var obj = [];
				jk.field(name, "clear=1");
				o.forEach(function(item) {
					var a = item.split('=');
					obj.push({ Text: a[0], Value : (a.length == 1 ? a[0] : a[1])});
				});
				jk.combo(obj, name);
			},

			readOnly : function(...a) {
				$j.each(a, function(k, v) { g_form.setReadOnly(v, true); });	
			},
			editable : function(...a) {
				$j.each(a, function(k, v) { g_form.setReadOnly(v, false); });	
			},
			hide : function(...a) {
				$j.each(a, function(k, v) { g_form.setVisible(v, false); });	
			},
			show : function(...a) {
				$j.each(a, function(k, v) { g_form.setVisible(v, true); });	
			},
			field: function(f, ...a) {
				$j.each(f.split(','), function(fk, fv) {
					$j.each(a, function(k, v) {
						var s = v.split('=');
						var b = s[1] == 'true'|| s[ 1] == '1';
						switch(s[0].toLowerCase().trim()) {
							case "visible": g_form.setVisible(fv, b); break;
							case "mandatory": g_form.setMandatory(fv, b); break;
							case "disabled": g_form.setDisabled(fv, b); break;
							case "readonly": g_form.setReadOnly(fv, b); break;
							case "value": g_form.setValue(fv, s[1]); break;
							case "clear": g_form.clearOptions(fv); g_form.clearValue(f);break;
							case "clearvalue": g_form.clearValue(fv);break;
							case "label": g_form.setLabelOf(fv, s[1]); break;
							default : s[1] = ""; break;
						}
					});
				});
			},
			
			//*** Table ****
			titles : function(titles, skip) {
				var j = {};

				(!skip ? '=,' + titles : titles).split(',').forEach(function(item) {
					var s = item.split('=');
					switch(s[1]) {
						case "l": s[1] = "left"; break;
						case "r": s[1] = "right"; break;
						case "c": s[1] = "center"; break;
						default : s[1] = ""; break;
					}
					j[s[0]] = s[1];
				});

				c["titles"] = j;

				return j;
			},

		}
		
		return jk;
	}
});


$j.readOnly = function(g_form, el) {
	$j.each(el, function(k, v) { g_form.setReadOnly(v, true); });	
}

$j.blockUI = function(show) {
	console.log("blockUI : " + show);
	
	if(show) {
		$j('#blockUI').modal({backdrop: 'static'});
	} else {
		$j('#blockUI').modal('hide');
		$j('body').removeClass('modal-open');
		$j('.modal-backdrop').remove();
	}
};

$j.view = function() {
	if(location.href.indexOf("/pdc") > -1)
		return "pdc";
	else if(location.href.indexOf("/pda") > -1)
		return "pda";
	else
		return "";
};

$j.validateAttachs = function(g_form, size, files) {
	files = files || [];
	//Para a plataforma.
	//try {
	//	var attachments = top.document.getElementById('header_attachment_list_label');
	//	if (attachments.style.visibility == 'hidden' || attachments.style.display == 'none' ) {
	//		g_form.addErrorMessage('Você deve adicionar um arquivo CSR para continuar.');
	//		return false;
	//	}
	//} 
	
	//Para o Service Portal
	//catch(e) {
		var i = angular.element("#sc_cat_item").scope().attachments.length;
		if(i < size) {
			g_form.addErrorMessage('É necessário incluir anexar todos os arquivos. Favor incluir os ' + (size - i)  + ' arquivo(s) restantes. ( ' + 
								   files.join(", ") + ')');
		}
	//}
	
	return i >= size;
};

$j.service = function(c, url, method, params, fn, alertStringify) {
	//c.$scope.async = true;

	return new Promise(function(resolve, reject) {
		$j.blockUI(true);
		c.$http($j.extend({ method: method, url: url }, params)).then(
			function successCallback(response) {
				r = response.data.result;
				if(alertStringify) alert(JSON.stringify(r));
				resolve(r);
				$j.blockUI(false);
				//c.$scope.async = undefined;
				//if(fn) fn(false);
			}, function errorCallback(response) {
				reject(response);
				//c.$scope.async = undefined;
				$j.blockUI(false);
				//if(fn) fn(false);
				errorCallbackAPI(c.$scope.page, response);
			}
		);
	});
};

function errorCallbackAPI(page, response) {
	console.log("Erro ao invocar a API: " + JSON.stringify(response));
	page.g_form.addErrorMessage(response.data.error ? response.data.error.message : "Erro ao invocar a API.");
}

function generatePDF(data) {
	w.open(URL.createObjectURL(b64toBlob(data, 'application/pdf')));
}

function downloadPDF(data) {
	var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

	//alert(isSafari);
	
	if(isSafari) {
		generatePDF(data);
	} else {
		jQuery("body").append('<a href="data:application/pdf;base64,' + data + '" download="download.pdf" id="file-download-pdf" style="display:none"></a>');
		document.getElementById("file-download-pdf").click();
		jQuery("#file-download-pdf").remove();
	}
}

function b64toBlob(b64Data, contentType, sliceSize) {
	contentType = contentType || '';
	sliceSize = sliceSize || 512;

	var byteCharacters = atob(b64Data);
	var byteArrays = [];

	for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
		var slice = byteCharacters.slice(offset, offset + sliceSize);
		var byteNumbers = new Array(slice.length);
		for (var i = 0; i < slice.length; i++) {
			byteNumbers[i] = slice.charCodeAt(i);
		}
		var byteArray = new Uint8Array(byteNumbers);
		byteArrays.push(byteArray);
	}

	return new Blob(byteArrays, {type: contentType});
}	

console.log("KrotonUtils loaded!");