let SinonimosController = {
	user: null,
	idDictionary: '',
	idLine: '',
	synonymsData: [],
	synonymsDelete: [],
	noMatchData: [],
	noMatchDataSynonim: [],
	loaders: {},
	allDictionarySynonym: [],

	reset() {
		let self = this;

		self.user = null;
		self.idDictionary = atob(sessionStorage.getItem('idDictionary'));
		self.idLine = atob(sessionStorage.getItem('idLine'));
		self.synonymsData = [];
		self.synonymsDelete = [];
		self.noMatchData = [];
		self.noMatchDataSynonim = [];
		self.loaders = {
			getAllVoiceassistantDictionarySynonym: false,
			getAllVoiceassistantDictionarySynonymAll: false,
			getAllVoiceassistantDictionaryRegisters: false
		};
		self.allDictionarySynonym = [];
	},

	setEvents() {
		let self = this;
		self.reset();

		let JSONuser = sessionStorage['STCMBackEnd:user'];
		let user = JSON.parse(JSONuser);
		let userMail = user.email;
		let user_split = userMail.split('@');
		self.user = user_split[0].replace('.', '_');

		// Reducción de Header
		headerSectionHeight(0);

		// Añadir titulo
		$('#page-title').text(pf.const.language.RSC2400);

		// Opciones de header
		let jsonsubopt = {
			back: 'back',
			generateLayout: 'exportLayout',
			importLayout: 'importLayout',
			save: 'save'
		};

		let nav = `
			<div class="row mx-0">
				${createSubOptionGenerateLayout(jsonsubopt.generateLayout)}
				${createSubOptionImportLayout(jsonsubopt.importLayout)}
				${createSubOptionSave(jsonsubopt.save)}
			</div>

			${createSubOptionBack(jsonsubopt.back)}
		`;

		// Acciones de página (flex-row-reverse)s
		$('#page-actions').html(nav);

		// Botón principal
		$('#save').addClass('main-button');

		// Botones secundarios
		$('#back').addClass('secondary-button');
		$('#exportLayout').addClass('secondary-button');
		$('#importLayout').addClass('secondary-button');

		// Sinónimos de entrada
		let parameters = {
			idDictionary: self.idDictionary,
			idLine: self.idLine
		};
		ajaxComunCallWithCallback('getAllVoiceassistantDictionarySynonym', parameters, function(ajaxReturn) {
			if(ajaxReturn) {
				let size = ajaxReturn.result.length;
				for(let i = 0; i < size; i++) {
					let obj = {
						idSynonymous: ajaxReturn.result[i].idSynonymous,
						text: ajaxReturn.result[i].text,
						noMatch: '0',
						idNoMatch: '',
						status: 'old'
					};
					self.synonymsData.push(obj);
				}

				self.renderSynonym();

				// Control de spinner
				self.loaders.getAllVoiceassistantDictionarySynonym = true;
				spinnerControl(self.loaders);
			}
		}, false);

		// Todos los sinónimos del diccionario
		let parametersAll = {
			idDictionary: self.idDictionary
		};
		ajaxComunCallWithCallback('getAllVoiceassistantDictionarySynonymAll', parametersAll, function(ajaxReturn) {
			if(ajaxReturn) {
				let size = ajaxReturn.result.length;
				for(let i = 0; i < size; i++) {
					self.allDictionarySynonym.push(ajaxReturn.result[i].text);
				}

				// Control de spinner
				self.loaders.getAllVoiceassistantDictionarySynonymAll = true;
				spinnerControl(self.loaders);
			}
		}, false);

		ajaxComunCallWithCallback('getAllVoiceassistantNoMatch', {}, function(ajaxReturn) {
			if(ajaxReturn) {
				let size = ajaxReturn.result.length;
				for(let i = 0; i < size; i++) {
					let obj = {
						idNoMatch: ajaxReturn.result[i].idNoMatch,
						text: ajaxReturn.result[i].text,
						noMatchDataSynonim: '0'
					};
					self.noMatchData.push(obj);
				}

				self.renderNoMatch();

				// Control de spinner
				self.loaders.getAllVoiceassistantNoMatch = true;
				spinnerControl(self.loaders);
			}
		}, false);

		self.loadLang();
		self.applyEvents();

		// Collapse
		addEventArrowTableHeader();
	},

	loadLang() {
		pf.rsc.translateByTag('text');
	},

	applyEvents() {
		let self = this;

		// Exportar excel
		$('#exportLayout').click(function() {
			window.location = stcm.const.downloads + 'layout_matches.xlsx';
		});

		// Importar excel
		$('#importLayout').click(function() {
			$('#inputFile').trigger('click');
		});

		// Detectar fichero subido
		$('#inputFile').change(function(evt) {
			self.uploadFile(evt);
		});

		// Añadir registro
		$('#newSynonyms').off().on('click', function() {
			let obj = {
				idSynonymous: '',
				text: '',
				noMatch: '0',
				idNoMatch: '',
				status: 'new'
			};
			self.synonymsData.unshift(obj);

			self.renderSynonym();
		});

		// Volver a diccionarios
		$('#back').off().on('click', function() {
			window.location.href = '#!voiceAssistant_edit';
		});

		// Guardar sinónimos / no match
		$('#save').off().on('click', function() {
			let objInfo = {
				accept: {
					text: pf.const.language.RSC78
				},
				cancel: {
					text: pf.const.language.RSC57
				}
			};

			let alertTitle = pf.const.language.RSC2400;
			let alertText = pf.const.language.RSC2403;
			pf.utils.showInfoDialogAcceptCancel(alertTitle, alertText, objInfo, function() {
				self.updateSynonymsNoMatch();
			}, function() {});
		});
	},

	renderSynonym() {
		let self = this;

		let table = `
			<table id="tableSynonym" class="table table-hover tRegs">
				<thead>
					<tr>
						<th scope="col" title="${pf.const.language.RSC1210}">${pf.const.language.RSC1210}</th>
						<th scope="col" title=""></th>
					</tr>
				</thead>

				<thead class="filtersSynonym">
					<tr>
						<td>synonym</td>
						<td>delete</td>
					</tr>
				</thead>

				<tbody>
		`;

		let size = self.synonymsData.length;
		if(size < 1) {
			let obj = {
				idSynonymous: '',
				text: '',
				noMatch: '0',
				idNoMatch: '',
				status: 'new'
			};
			self.synonymsData.push(obj);
			size = 1;
		}

		for(let i = 0; i < size; i++) {
			let disabled = '';
			if(self.synonymsData[i].noMatch === '1') {
				disabled = ' disabled';
			}

			table += `
				<tr>
					<td class="text-truncate p-1" title="${self.synonymsData[i].text}">
						<span id="synonymSpan${i}" class="d-none">${self.synonymsData[i].text}</span>
						<input id="synonymInput${i}" type="text" class="form-control controlHash synonymInput" value="${self.synonymsData[i].text}" title="${self.synonymsData[i].text}" data-index="${i}"${disabled}>
					</td>
					<td class="text-truncate text-center" title="${pf.const.language.RSC226}">
						<span class="c-pointer circle-container delete" data-index="${i}">
							${stcmbackend.svg.trash}
						</span>
					</td>
				</tr>
			`;
		}

		table += `
				</tbody>
			</table>
		`;

		$('#synonymsTable').html(table);

		// Setup - add a text input to each footer cell
		$('#tableSynonym .filtersSynonym td').each(function() {
			let title = $(this).text();
			let value = `<input type="text" class="form-control form-control-sm">`;

			if(title == 'delete') {
				value = `<input type="text" class="form-control form-control-sm" disabled>`;
			}

			$(this).html(value);
		});

		let tableSynonym = $('#tableSynonym').DataTable({
			retrieve: true,
			language: pf.const.language_table,
			pageLength: 25,
			autoWidth: false,
			columnDefs: [
				{width: '30px', targets: 1}
			],
			ordering: false,
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				text: pf.const.language.RSC2401,
				className: 'd-none',
				title: pf.const.language.RSC2401,
				customize(xlsx) {
					dataTablesExcelCustomize(xlsx);
				}
			}],
			aaSorting: []
		});

		// Apply the search
		applyTheSearch(tableSynonym, 'filtersSynonym');

		// Ocultar botones de tabla
		hideTableButtons('tableSynonym');

		// Exportar tabla
		$('#exportSynonyms').off().on('click', function() {
			$('#synonymsTable .buttons-excel').trigger('click');
		});

		self.synonymEvents();
		$('#synonymsTable').on('draw.dt', function() {
			self.synonymEvents();
		});
	},

	synonymEvents() {
		let self = this;

		// Input de texto
		$('.synonymInput').off().on('blur', function() {
			let index = $(this).data('index');
			let value = $(this).val().trim();

			// Control para evitar repeticiones
			let size = self.synonymsData.length;
			for(let i = 0; i < size; i++) {
				if(value == self.synonymsData[i].text.trim() && index != i) {
					$(this).val('');
					let successTitle = pf.const.language.RSC2401;
					let successContent = pf.const.language.RSC2469;
					pf.utils.showInfoDialog(successTitle, successContent);
					return false;
				}
			}

			// Control para evitar repeticiones en todo el diccionario
			if(self.allDictionarySynonym.includes(value)) {
				$(this).val('');
				let successTitle = pf.const.language.RSC2401;
				let successContent = pf.const.language.RSC2469;
				pf.utils.showInfoDialog(successTitle, successContent);
				return false;
			}

			if(self.synonymsData[index].status === 'old') {
				self.synonymsData[index].status = 'update';
			}
			self.synonymsData[index].text = value;
			
			$(this).val(value);
			$(this).attr('title', value);
			$('#synonymSpan' + index).text(value);

			self.renderSynonym();
		});

		// Eliminar registro de sinónimos
		$('.delete').off().on('click', function() {
			let index = $(this).data('index');
			if(self.synonymsData[index].noMatch === '1') {
				let indexNoMatch = self.noMatchDataSynonim.indexOf(self.synonymsData[index].idNoMatch);
				self.noMatchDataSynonim.splice(indexNoMatch, 1);

				let size = self.noMatchData.length;
				for(let i = 0; i < size; i++) {
					if(self.noMatchData[i].idNoMatch == self.synonymsData[index].idNoMatch) {
						self.noMatchData[i].noMatchDataSynonim = '0';
						self.renderNoMatch();
						break;
					}
				}
			} else if(self.synonymsData[index].idLine !== '') {
				self.synonymsDelete.push(self.synonymsData[index].idSynonymous);
			}

			self.synonymsData.splice(index, 1);
			self.renderSynonym();
		});

		// Restricciones de carácter # por tecla para el Texto inicio de misión
		$('.controlHash').on('keypress', function(e) {
			// Parámetros: tecla, warningTitle, warningContent y pattern si no es el general
			let result = characterRestrictionsPerKey(e.keyCode, pf.const.language.RSC375, pf.const.language.RSC1999, /[^#]/i);

			return result;
		});

		// Restricciones del carácter # por pegado para el Texto inicio de misión
		$('.controlHash').on('paste', function() {
			// Parámetros: elemento, warningTitle, warningContent y pattern si no es el general
			characterRestrictionsPerPaste($(this), pf.const.language.RSC375, pf.const.language.RSC1999, /[#]/gi);
		});
	},

	renderNoMatch() {
		let self = this;

		let table = `
			<table id="tableNoMatch" class="table table-hover tRegs">
				<thead>
					<tr>
						<th scope="col" title="${pf.const.language.RSC1210}">${pf.const.language.RSC1210}</th>
					</tr>
				</thead>

				<thead class="filtersNoMatch">
					<tr>
						<td>noMatch</td>
					</tr>
				</thead>

				<tbody>
		`;

		let size = self.noMatchData.length;
		for(let i = 0; i < size; i++) {
			if(self.noMatchData[i].noMatchDataSynonim === '1') {
				continue;
			}

			table += `
				<tr class="c-pointer takeNoMatch" data-index="${i}">
					<td class="text-truncate" title="${self.noMatchData[i].text}">
						${self.noMatchData[i].text}
						<div class="btn table-button main-color-text p-1 float-right">
							${stcmbackend.svg.arrowUpInCircle}
						</div>
					</td>
				</tr>
			`;
		}

		table += `
				</tbody>
			</table>
		`;

		$('#noMatchTable').html(table);

		// Setup - add a text input to each footer cell
		$('#tableNoMatch .filtersNoMatch td').each(function() {
			let value = `<input type="text" class="form-control form-control-sm">`;

			$(this).html(value);
		});

		let tableNoMatch = $('#tableNoMatch').DataTable({
			retrieve: true,
			language: pf.const.language_table,
			pageLength: 25,
			autoWidth: false,
			ordering: false,
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				text: pf.const.language.RSC2402,
				className: 'd-none',
				title: pf.const.language.RSC2402,
				customize(xlsx) {
					dataTablesExcelCustomize(xlsx);
				}
			}],
			aaSorting: []
		});

		// Apply the search
		applyTheSearch(tableNoMatch, 'filtersNoMatch');

		// Ocultar botones de tabla
		hideTableButtons('tableNoMatch');

		// Exportar tabla
		$('#exportNoMatch').off().on('click', function() {
			$('#noMatchTable .buttons-excel').trigger('click');
		});

		self.noMatchEvents();
		$('#noMatchTable').on('draw.dt', function() {
			self.noMatchEvents();
		});
	},

	noMatchEvents() {
		let self = this;

		// Coger registro de no match y pasarlo a sinónimo
		$('.takeNoMatch').off().on('click', function() {
			// Valor del filtro de la tabla
			let filterValue = $('#tableNoMatch .filtersNoMatch td input').val();

			let index = $(this).data('index');

			self.noMatchDataSynonim.push(self.noMatchData[index].idNoMatch);

			self.noMatchData[index].noMatchDataSynonim = '1';
			self.renderNoMatch();

			// Mantener el filtro tras la recarga de la tabla
			$('#tableNoMatch .filtersNoMatch td input').val(filterValue);
			$('#tableNoMatch .filtersNoMatch td input').trigger('change');

			if(self.synonymsData.length === 1 && self.synonymsData[0].text == '') {
				self.synonymsData = [];
			}

			let obj = {
				idSynonymous: '',
				text: self.noMatchData[index].text,
				noMatch: '1',
				idNoMatch: self.noMatchData[index].idNoMatch,
				status: 'new'
			};
			self.synonymsData.push(obj);

			self.renderSynonym();
		});
	},

	uploadFile(evt) {
		let self = this;

		// Limpieza de array si no hay registros
		if(self.synonymsData.length == 1 && self.synonymsData[0].text == '') {
			self.synonymsData = [];
		}

		addLoader();
		// Convertir excel a JSON
		let selectedFile = evt.target.files[0];
		let reader = new FileReader();
		reader.onload = function(event) {
			let data = event.target.result;
			let workbook = XLSX.read(data, {
				type: 'binary'
			});

			workbook.SheetNames.forEach(function(sheetName) {
				let importMatches = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);

				importMatches.forEach(element => {
					element.Texto = element.Texto.trim();

					// Control de elementos repetidos
					let notRepeated = true;
					let size = self.synonymsData.length;
					for(let i = 0; i < size; i++) {
						if(element.Texto == self.synonymsData[i].text.trim()) {
							notRepeated = false;
							break;
						}
					}

					// Control para evitar repeticiones en todo el diccionario
					if(self.allDictionarySynonym.includes(element.Texto)) {
						notRepeated = false;
					}

					if(element.Texto != '' && notRepeated) {
						let obj = {
							idSynonymous: '',
							text: element.Texto,
							noMatch: '0',
							idNoMatch: '',
							status: 'new'
						};

						self.synonymsData.unshift(obj);
					}
				});

				self.renderSynonym();
				removeLoader();
				$('#inputFile').val(null);
			})
		};

		/* reader.onerror = function(event) {
			console.error('File could not be read! Code ' + event.target.error.code);
		}; */

		reader.readAsBinaryString(selectedFile);
	},

	updateSynonymsNoMatch() {
		let self = this;

		let parameters = {
			idDictionary: self.idDictionary,
			idLine: self.idLine,
			synonymsData: JSON.stringify(self.synonymsData),
			synonymsDelete: JSON.stringify(self.synonymsDelete),
			noMatchDataSynonim: JSON.stringify(self.noMatchDataSynonim)
		};
		ajaxComunCallWithCallback('updateSynonymsNoMatch', parameters, function(ajaxReturn) {
			if(ajaxReturn) {
				let successTitle = pf.const.language.RSC2400;
				let successContent = pf.const.language.RSC2404;
				pf.utils.showInfoDialog(successTitle, successContent);
				window.location.href = '#!voiceAssistant_edit';
			}
		});
	}
};