var optionsValuesDefault = {};

var isSelectedValue = function(valSelected, itemId){
	if(valSelected instanceof Array){
		if($jq.inArray( itemId, valSelected ) >= 0){
			return true;
		}
		return false;
	}
	return valSelected === itemId;
};

var loadOptionsToChild = function($child, options, isInitialize){
	var valSelected = optionsValuesDefault[$child.attr("id")];
	var existValSelectedInOptions = false;
	$child.find('option[value!=""]').remove().end();
	$jq.each(options, function(i,e){
		$child.append($jq("<option>")
				.text(e.itemText)
				.val(e.itemId)
		);
		if(!existValSelectedInOptions && isSelectedValue(valSelected, e.itemId) ){
			existValSelectedInOptions = true;
		}
		if(e.selected && !(ValueIsBlank(valSelected) && isInitialize==true)){
			$child.val(e.itemId);	
		}
	});
	if(existValSelectedInOptions){
		$child.val(valSelected);
	}
};

var $rowByCF = function($cf){
	return $cf.closest("tr.cssRowContainerCF").parent().find("tr[id="+ $cf.closest("tr.cssRowContainerCF").attr('id') +"]");
};

var isValidForClean = function($tr, childCfId){
	return $tr.find('input[id^=cfield_clazz_'+childCfId+']').val() === "1";
};

var hasParentEditable = function($tr, parentId){
	var $parentRow = $tr.siblings("tr[id=row_"+parentId+"]");
	return $parentRow.find("select[id^=cfield_"+parentId+"]").length > 0;
};

var cleanValueHiden = function($tr, childCfId){
    
	if(!isValidForClean($tr, childCfId)){
		return false;
	}
	var $inputsToHide = $tr.find("input[type=text][id^=cfield_"+childCfId+"]");
	if(!hasParentEditable($tr, $inputsToHide.attr("cfparentlist"))){
		return false;
	}
	$inputsToHide.val("");
	setTimeout(function(){$inputsToHide.trigger("keyup");},800);
    cfActions_validateRule($inputsToHide);
};

var getCFInputValue = function($tr, cfChildId){
	var $inputReadOnly = $jq("#hidenRowsDependentsReadOnly_"+cfChildId);
	if($inputReadOnly.length > 0){
		var suffix = $inputReadOnly.attr("suffix");
		return $jq("input[type=hidden][id=cfield_"+(cfChildId+suffix)+"]");
	}
	return $tr.find('input[type=text][id^=cfield_'+cfChildId+']');
};

var inputsComponentsToApplyChange = {};

var applyKeyupToComponents = function(){
	$jq.each(inputsComponentsToApplyChange, function(k,v){
		$jq(v).trigger("keyup");
	});
};

var setValueDefault = function($tr, childCfId){
	if(!isValidForClean($tr, childCfId)){
		return false;
	}
	var $input = getCFInputValue($tr, childCfId);
	var defaultValue = optionsValuesDefault[$input.attr("id")];
	inputsComponentsToApplyChange[$input.attr("id")] = $input;
	if(ValueIsBlank(defaultValue)){
		$input.trigger("keyup");
		return false;
	}
	$input.val(defaultValue);
	$input.trigger("keyup");
    cfActions_validateRule($input);
};

var hideChildsRow = function($childsSelector){
	$childsSelector.each(function(){
		var $tr = $rowByCF($jq(this));
		// Ocultar la fila sin afectar los anchos
		$tr.addClass('hidden');
		cleanValueHiden($tr, this.id.split("_")[1]);
	});
};

var getCFIdSuffix = function($parent){
	var cfId = $parent.attr("id").split("_")[1];
	
	if(!$parent.attr("suffix") || ValueIsBlank($parent.attr("suffix"))){
		return cfId.replace(/\D/ig, '');
	}
	if ($parent.attr("suffix").includes('readOnly')) {
		let subSuffix = $parent.attr("suffix").split('readOnly')[1];
		return cfId.split(subSuffix)[0];
	}
	return cfId.split($parent.attr("suffix"))[0];
};

var reviewDependentsParentValue = function($parent){	
	var cfId = getCFIdSuffix($parent);
	var qsObject = {};
	qsObject['cfId'] = cfId;
	qsObject['optionId'] = getOptionValueId($parent.val());	
	$jq.getJSON(urlShowDependCustomField+"&_ts="+new Date().getTime(), qsObject, function(data) {
		$jq.each(data, function(i,e){
			var $tr = $parent.closest("tr[id=row_"+cfId+"]").siblings("tr[id=row_" + e.childCfId+"]");
			if (e.show){
				setValueDefault($tr,e.childCfId);
				$tr.removeClass('hidden');
			}else{
				cleanValueHiden($tr,e.childCfId);
				$tr.addClass('hidden');
			}
		});
		setTimeout(function(){applyKeyupToComponents();}, 800);
	});
};

var whenChildrensAreNotList = function(){
	var $parent = $jq(this);
	var cfId = $parent.attr("id").split("_")[1].replace(/\D/ig, '');
	var $otherChilds = getOtherChildrens($parent, cfId);
	if($otherChilds.length === 0){
		return false;
	}

	if(ValueIsBlank($parent.val())){
		hideChildsRow($otherChilds);
		return false;
	}	
	reviewDependentsParentValue($parent);
};

const cfActions_validateRule = ($otherChilds) => {
    console.log('Validando cajas de texto');
    $otherChilds.each( function( index) {
        const cfActionsId = $jq(this).attr('cfActionParentId');
        if( !cfActionsId ){
            return;
        }
        validateShowActionTable(`${cfActionsId}`);  
    });
}

var whenChangeOptionList = function(event, isInitialize){
	var $parent = $jq(this);
	var cfId = $parent.attr("id").split("_")[1].replace(/\D/ig, '');
	var $childs = getChildrens($parent, cfId);
	if($childs.length === 0){
		return false;
	}
	$childs.val("");
	$childs.find('option[value!=""]').remove().end();
	if(ValueIsBlank($parent.val())){
		$childs.trigger("change",[isInitialize]);
		return false;
	}	
	var qsObject = {};
	qsObject['cfId'] = cfId;
	qsObject['optionId'] = getOptionValueId($parent.val());	
	$jq.getJSON(urlLoadOptionsListValue+"&_ts="+new Date().getTime(), qsObject, function(data) {
		$jq.each(data, function(i,e){
			var $child = getChild($parent, cfId, e.childId);
			loadOptionsToChild($child, e.options, isInitialize);
			$child.trigger("change",[isInitialize]);
		});
		return false;
	});
}

/*
* Aplica cuando los identificadores son compuestos por mas de 1 id. Ej. en controles
*/
function getChildrens($parent, cfParentId){
	var parentId = $parent.attr("id");
	if(parentId.split("_").length > 2){
		var posParentId = parentId.indexOfEnd(cfParentId+'');
		var endParentId = parentId.substring(posParentId);
		return $jq("select[cfparentlist="+cfParentId+"][id$="+endParentId+"]");
	}
	return $jq("select[cfparentlist="+cfParentId+"]");
}

function getOtherChildrens($parent, cfParentId){
	var parentId = $parent.attr("id");
	if(parentId.split("_").length > 2){
		var posParentId = parentId.indexOfEnd(cfParentId+'');
		var endParentId = parentId.substring(posParentId);
		return $jq("input[cfparentlist="+cfParentId+"][id$="+endParentId+"], input[cfparentlist="+cfParentId+"][id$="+endParentId+"_lab], textarea[cfparentlist="+cfParentId+"][id$="+endParentId+"_txt], span[cfparentlist="+cfParentId+"][id$="+endParentId+"_spanValue]");
	}
	return $jq("input[cfparentlist="+cfParentId+"], textarea[cfparentlist="+cfParentId+"], span[cfparentlist="+cfParentId+"]");
}

function getChild($parent, cfParentId, cfChildId){
	var parentId = $parent.attr("id");
	var childId = parentId.replaceAll(cfParentId, cfChildId);
	return $jq("#"+childId);
}

function getOptionValueId(valueId){
	if(ValueIsBlank(valueId)){
		return "";
	}
	return valueId.split("|")[0];
}

var childsParentForMsgJson = {};

var loadChildForMsg = function($cf, cfParentId){
	if(isFromPreview){
		var cfId = $cf.attr("id").split("_")[1];
		var pName = $rowByCF($cf).find("label[id$="+cfId+"]").attr("pname");
		if(cfParentId != null && cfParentId != "null" && cfParentId !== undefined && !ValueIsBlank(cfParentId)){
			childsParentForMsgJson[escape(pName)] = cfParentId;
		}
	}
};

var existCFInView = function($child, cfParentId){
	return ($child.closest("tr[id^=row_]").siblings(`tr[id^=row_${cfParentId}]`).length > 0) && 
	($jq(`input[id^=cfield_clazz_${cfParentId}][value=5]`).closest("td").find(`input[id^=cfield_${cfParentId}][type=hidden],select[id^=cfield_${cfParentId}]`).length > 0);
};

var reviewDependentsForListNotPaintInit = function($childs){
	$childs.each(function(){
		var cfParentId = $jq(this).attr("cfparentlist");
		if(!existCFInView($jq(this),cfParentId)){
			hideChildsRow($jq(this));
			loadChildForMsg($jq(this), cfParentId);
		}
	});
};

var getChildNameForMsg = function(parentId){
	var childNames = [];
	$jq.each(childsParentForMsgJson, function(k,v){
		if(v === parentId){
			childNames.push(unescape(k));
		}
	});
	return childNames.join(", ");
};

var getComponentsHideNameForMsg = function(){
	var parentId = "";
	var parentsComponentsHide = {};
	$jq.each(childsParentForMsgJson, function(k,v){
		if(v !== parentId){
			parentsComponentsHide[v] = getChildNameForMsg(v);
		}
		parentId = v;
	});
	return parentsComponentsHide;
};

var getParentsIds = function(parentsComponentsHide){
	var parents = [];
	$jq.each(parentsComponentsHide, function(k,v){
		parents.push(k);
	});
	return parents.join(",");
};

var buildMsgComponentsHide = function(parentsComponentsHide, parentsName){
	var msg = "";
	$jq.each(parentsComponentsHide, function(k,v){
		msg += "Los atributos ["+v+"]" + " no se muestran porque dependen de la lista ["+parentsName[k]+"]<br/><br/>";
	});
	return msg;
};

var showMsgDependents = function(){
	if($jq.isEmptyObject(childsParentForMsgJson)){
		return;
	}
	var parentsComponentsHide = getComponentsHideNameForMsg();
	var qsObject = {};
	qsObject['cfIds'] = getParentsIds(parentsComponentsHide);
	$jq.getJSON(urlGetCFName+"&_ts="+new Date().getTime(), qsObject, function(data) {
		pnotify_warning(buildMsgComponentsHide(parentsComponentsHide, data));
		return false;
	});
};

var getParentsReadOnly = function($selectorForParents){
	var parentsReadOnly = {};
	$selectorForParents.each(function(){ 
		var suffix = $jq(this).attr("suffix");
		var key = $jq(this).attr("cfparentlist") + suffix;
		parentsReadOnly[key] = suffix;
	});
	return parentsReadOnly;
};

var reviewDependentsReadOnlyInit = function(parentsReadOnly){
	$jq.each(parentsReadOnly, function(k,suffix){
		var $parent = $jq("input[type=hidden][id=cfield_"+ k +"]");
		if($parent.length <= 0){
			return true;
		}
		if(!ValueIsBlank(suffix)){
			$parent.attr("suffix", suffix);
		}
		reviewDependentsParentValue($parent);
	});
};

var reviewDependentsReadOnlyInitCommon = function(){
	var parentsReadOnly = getParentsReadOnly($jq("input[id^=hidenRowsDependentsReadOnly_]"));
	reviewDependentsReadOnlyInit(parentsReadOnly);
};

var reviewDependentsReadOnlyInitStep = function(step){
	$jq.pnotify_remove_all();
	var $stepTable = $jq(`div#div${step}`);
	var $selectorForParents = $stepTable.find("input[id^=hidenRowsDependentsReadOnly_]");
	var parentsReadOnly = getParentsReadOnly($selectorForParents);
	var $childs = $stepTable.find("input[cfparentlist][cfparentlist!=0], textarea[cfparentlist][cfparentlist!=0], span[cfparentlist][cfparentlist!=0]");
	reviewDependentsForListNotPaintInit($childs);
	reviewDependentsReadOnlyInit(parentsReadOnly);
};

var getCFValueFromCFClazz = function($cfClazz){
	var cfId = $cfClazz.attr("id").split("_")[2]; 
	var posIndex = $cfClazz.attr("id").indexOfEnd(cfId+'');
	var posId = $cfClazz.attr("id").substring(posIndex);
	return $cfClazz.parent("div").siblings("div").find("input[type=hidden][id=cfield_"+(cfId+posId)+"]");
};

var loadValuesDefaultForInputReadOnly = function(){
	$jq("input[id^=cfield_clazz_][value=1]").each(function(){
		var $cfListTextEditOrReadOnly = getCFValueFromCFClazz($jq(this));
		if($cfListTextEditOrReadOnly.length <= 0){
			return true;
		}
		optionsValuesDefault[$cfListTextEditOrReadOnly.attr("id")] = $cfListTextEditOrReadOnly.val();
	});
};

var loadValuesDefaultForInputText = function(){
	$jq("input[type=text][cfparentlist]").each(function(){
		optionsValuesDefault[this.id] = $jq(this).val();
	});
	loadValuesDefaultForInputReadOnly();
};

var loadValuesDefaultSelect = function(){
	$jq("select[cfparentlist]").each(function(){
		if(!optionsValuesDefault[this.id]){
			optionsValuesDefault[this.id] = $jq(this).val();
		}
	});
};

var loadAllValuesDefault = function(){
	loadValuesDefaultSelect();
	loadValuesDefaultForInputText();
};

var initializeDependentsCommons = function(whenChange){
	var $selectList = $jq("select[cfparentlist]");
	$selectList.each(function(){
		$jq(this).unbind("change", whenChange);
		$jq(this).change(whenChange);
	});
};

/**
 * Aplica para el caso de mejoras que en edición puede tener la lista de solo lectura
 * pero que igual debe revisar el valor de la lista para ocultar o mostrar los AP
 */
var initializeDependentsReadOnlyListValueInit = function(){
	$jq("input[id^=cfield_clazz_][value=5]").each(function(){
		var $cfListHidden = getCFValueFromCFClazz($jq(this));
		if($cfListHidden.length <= 0){
			return true;
		}
		$cfListHidden.change(whenChildrensAreNotList);
		$cfListHidden.change(whenChangeOptionList);
		$cfListHidden.trigger("change",[true]);
	});
};

var initializeDependentCFInput = function(){
	var $childs = $jq("input[cfparentlist][cfparentlist!=0], textarea[cfparentlist][cfparentlist!=0], span[cfparentlist][cfparentlist!=0], select[cfparentlist][cfparentlist!=0]");
	reviewDependentsForListNotPaintInit($childs);
	reviewDependentsReadOnlyInitCommon();
	initializeDependentsCommons(whenChildrensAreNotList);
	initializeDependentsReadOnlyListValueInit();
	showMsgDependents();
	configureWebServiceAttributeTriggers();
	configureApiRestAttributeTriggers();
	//configureActionAttributeTriggers();
};

const getEventName=(input)=> {
	if(input.type=='text'){
		return 'blur';
	}
	if(input.type=='select-one'){
		return 'change';
	}	
};	

var configureWebServiceAttributeTriggers=()=> {
	let suffix = "";	
	for (var customWs in webServiceAttributeDependencies){   
		let configStr=webServiceAttributeDependencies[customWs];
		let config=JSON.parse(unescape(configStr));	
		let inputParams=config.params;		 
		for (var param in inputParams){
			let paramValue=inputParams[param];	
			let input=document.getElementById(`cfield_${paramValue}${suffix}`);
			if(!ValueIsNumber(paramValue) || !input){
				continue;
			}	
			let eventName=getEventName(input);
			document.getElementById(`row_${customWs}${suffix}`).style.display = "none";
			let cfWs=customWs;
			let configWS=configStr;
			input.addEventListener(eventName, function () {
		        consumeWebService(this,cfWs,configWS,suffix);			        
		    });
		}	
  	}	
};

var configureApiRestAttributeTriggers=()=> {
	let suffix = "";	
	for (var customApi in apiRestAttributeDependencies){   
		let configStr=apiRestAttributeDependencies[customApi];
		let config=JSON.parse(unescape(configStr));					
		let bodyParams=config.bodyParams;		 
		for (var param in bodyParams){
			let cfId=bodyParams[param].cf;	
			let input=document.getElementById(`cfield_${cfId}${suffix}`);
			if(!ValueIsNumber(cfId) || !input){
				continue;
			}	
			let eventName=getEventName(input);
			document.getElementById(`row_${customApi}${suffix}`).style.display = "none";
			let cfWs=customApi;
			let configWS=configStr;
			input.addEventListener(eventName, function () {
		        consumeAPIRest($jq(`#btnAPI_cfield_${cfId}${suffix}`),cfWs,configWS,suffix);			        
		    });
		}	
  	}	
};

var configureActionAttributeTriggers=()=> {	
	let suffix = "";	
	for (var actionCustom in actionAttributeDependencies){   
		let configStr=actionAttributeDependencies[actionCustom];
		let config=JSON.parse(unescape(configStr));					
		let components= JSON.parse(config.components); 
		let rule=config.rule;
		if(ValueIsBlank(components)){
			continue;
		}	
			rule = escape(cleanFormuleAsterisk(rule));			 
			for (var component in components){
					let iComponent =  escape(cleanFormuleAsterisk(components[component]));		
					let cfComponentId=component;
					let input=document.getElementById(`cfield_${cfComponentId}${suffix}`);
					if(!ValueIsNumber(cfComponentId) || !input){
						continue;
					}	
					let eventName=getEventName(input);
					document.getElementById(`row_${actionCustom}${suffix}`).style.display = "none";
					let customField=actionCustom;		
					input.addEventListener(eventName, function () {
				     	let qsObject = {};
					    let componentValue=getComponentValue($jq(`#cfield_${cfComponentId}${suffix}`));
					    let componentReplace = ValueIsBlank(componentValue)?null:componentValue;
				        rule = rule.replaceAll(iComponent,componentReplace);
					   	qsObject['formuleToCalculate'] = rule;
				       	$jq.getJSON(urlCalculateFormuleAP, qsObject, function(data) {						
							return false;
						});
				    });
			}
		}
};	

var execInitializationSelects = function(){
	if($jq("select[cfparentlist=0]").length > 0){
		$jq("select[cfparentlist=0]").trigger("change",[true]);
		return;
	}
	$jq("select[cfparentlist]").trigger("change",[true]);
};

var initializeOptionsCFList = function(){
	loadAllValuesDefault();
	initializeDependentsCommons(whenChangeOptionList);
	initializeDependentCFInput();
	execInitializationSelects();
};
