const SweetToast = Swal.mixin({
	backdrop: false,
	allowOutsideClick: true,
	position: "bottom-end",
	timer: 8000,
	timerProgressBar: true,
	onOpen: toast => {
		toast.addEventListener("mouseenter", Swal.stopTimer);
		``;
		toast.addEventListener("mouseleave", Swal.resumeTimer);
	}
});

const SweetToaster = Swal.mixin({
	toast: true,
	position: "bottom-end",
	timer: 8000,
	timerProgressBar: true,
	showConfirmButton: false,
	onOpen: toast => {
		toast.addEventListener("mouseenter", Swal.stopTimer);
		toast.addEventListener("mouseleave", Swal.resumeTimer);
	}
});
function Scheduler() {
	this.str_leadId = "-1";
	this.int_status = 0;
	this.bln_anyone = false;
	this.arr_notifications = [];
	this.prm_swal = new Promise((solve, reject) => {
		solve();
	});
	// Status:
	// 1 para PAUSED
	// 0 para READY o CLOSER
	// <0 para CUALQUIER OTRO

	this._fn_swalMixin = function(html, confirm, cancel) {
		if (typeof confirm === "undefined") {
			confirm = "Llamar ahora";
		}

		if (typeof cancel === "undefined") {
			cancel = "Recordarmelo mas tarde";
		}

		return {
			confirmButtonText: confirm,
			cancelButtonText: cancel,
			html: html,
			showConfirmButton: true,
			showCancelButton: true,
			backdrop: false,
			allowOutsideClick: true,
			position: "bottom-end",
			timerProgressBar: true
		};
	};

	this.fn_schedule = function(
		str_year,
		str_month,
		str_date,
		str_hours,
		str_minutes,
		str_comments,
		str_phoneNumber,
		bln_recipientAnyOne
	) {
		let str_strdate = this._fn_strdateFormatter(
			str_year,
			str_month,
			str_date,
			str_hours,
			str_minutes
		);
		let obj_self = this;
		let str_leadId = this.str_leadId;
		this.bln_anyone = bln_recipientAnyOne;
		this._fn_saveCallback(
			str_strdate,
			str_comments,
			bln_recipientAnyOne,
			res => {
				if (!bln_recipientAnyOne) {
					obj_self._fn_notify(
						obj_self._fn_milliRemaining(str_strdate),
						str_comments,
						str_phoneNumber,
						res.CallbackId,
						str_leadId
					);
				}
			},
			str_leadId
		);
	};

	// Convierte la fecha por separador en un formato de fecha
	// aceptado por el constructor de Date
	this._fn_strdateFormatter = function(
		str_year,
		str_month,
		str_date,
		str_hours,
		str_minutes
	) {
		return `${str_year}-${str_month}-${str_date} ${str_hours}:${str_minutes}:00`;
	};

	// Recide una fecha en formato correcto
	// y devuelve un objecto Date
	this._fn_strToDate = function(str_date, bln_fix) {
		let dte_tmpDate = new Date(str_date);
		if (
			typeof bln_fix !== "boolean" ||
			(typeof bln_fix === "boolean" && bln_fix)
		) {
			// Arreglar la fecha por zonas horarias
			// de ser necesario
		}
		return dte_tmpDate;
	};

	// Calcula los milisegundos restante entre
	// una fecha de inicio y una de final
	this._fn_milliRemaining = function(var_endDate, var_startDate) {
		if (typeof var_startDate === "undefined") {
			var_startDate = new Date();
		} else if (typeof var_startDate === "string") {
			var_startDate = this._fn_strToDate(var_endDate);
		}

		if (typeof var_endDate === "undefined") {
			var_endDate = new Date();
		} else if (typeof var_endDate === "string") {
			var_endDate = this._fn_strToDate(var_endDate);
		}

		return var_endDate.getTime() - var_startDate.getTime();
	};

	// Guarda el callback en la tabla
	// vicidial_callbacks como 'INACTIVE'
	this._fn_saveCallback = function(
		str_date,
		str_comments,
		bln_recipientAnyOne,
		fn_handler,
		str_leadId
	) {
		let str_recipient = "USERONLY";

		if (typeof bln_recipientAnyOne === "boolean" && bln_recipientAnyOne) {
			str_recipient = "ANYONE";
		}

		$.post(`/${RUTA_MAESTRA}/index.php/homeAgente/saveCallback`, {
			callback_time: str_date,
			comments: str_comments,
			recipient: str_recipient,
			lead_id: str_leadId || this.str_leadId
		})
			.then(res => {
				if (res.Estado !== "ok") {
					console.error(res);
				} else if (typeof fn_handler === "function") {
					console.log(res);
					fn_handler(res);
				}
			})
			.catch(err => {
				console.error(err);
			});
	};

	// Elimina el callback de la tabla
	// vicidial_callbacks
	this._fn_deleteCallback = function(str_callbackId, fn_handler) {
		$.post(`/${RUTA_MAESTRA}/index.php/homeAgente/deleteCallback`, {
			id: str_callbackId
		})
			.then(res => {
				if (res.Estado !== "ok") {
					console.error(res);
				} else if (typeof fn_handler === "function") {
					console.log(res);
					fn_handler(res);
				}
			})
			.catch(err => {
				console.error(err);
			});
	};

	// Obtiene un callback, si existen. Globales.
	this._fn_getCallback = function(fn_handler) {
		$.post(`/${RUTA_MAESTRA}/index.php/homeAgente/assignCallback`)
			.then(res => {
				if (res.Estado !== "ok") {
					console.error(res);
				} else if (typeof fn_handler === "function") {
					console.log(res);
					fn_handler(res);
				}
			})
			.catch(err => {
				console.error(err);
			});
	};

	this._fn_getOwnCallbacks = function(fn_handler) {
		$.post(`/${RUTA_MAESTRA}/index.php/homeAgente/getCallbacks`)
			.then(res => {
				if (res.Estado !== "ok") {
					console.error(res);
				} else if (typeof fn_handler === "function") {
					console.log(res);
					fn_handler(res);
				}
			})
			.catch(err => {
				console.error(err);
			});
	};

	// Genera el Timeout para notificar al agente
	// del callback
	this._fn_notify = function(
		int_milliRem,
		str_comments,
		str_phoneNumber,
		str_callbackId,
		str_leadId
	) {
		let obj_self = this;
		let int_timeoutId = setTimeout(function() {
			obj_self.prm_swal = obj_self.prm_swal.then(slv => {
				return new Promise((solve, reject) => {
					setTimeout(function() {
						solve(
							obj_self._fn_askCallback(
								str_comments,
								str_phoneNumber,
								str_callbackId,
								str_leadId
							)
						);
						console.log("Timeout promise ejecuted")
					}, 30000);
				});
			});
		}, int_milliRem);
		console.log(int_milliRem);
		this.arr_notifications.push({
			phone: str_phoneNumber,
			timeoutId: int_timeoutId
		});
		return int_timeoutId;
	};

	// Genera un callback para dentro de tres
	// minutos. Sirve si el agente no puede
	// o no quiere volver a llamar en este momento
	this._fn_remindLater = function(str_comments, str_phoneNumber, str_leadId) {
		let int_newTime = 2 * 60 * 1000;
		let date_tmp = new Date(Date.now() + int_newTime);
		let str_tmpDate = this._fn_strdateFormatter(
			date_tmp.getFullYear(),
			date_tmp.getMonth() + 1,
			date_tmp.getDate(),
			date_tmp.getHours(),
			date_tmp.getMinutes()
		);
		let obj_self = this;
		this._fn_saveCallback(
			str_tmpDate,
			str_comments,
			false,
			res => {
				obj_self._fn_notify(
					obj_self._fn_milliRemaining(str_tmpDate),
					str_comments,
					str_phoneNumber,
					res.CallbackId,
					str_leadId
				);
			},
			str_leadId
		);
	};

	// Preguna si se llamara en este momento
	// el callback. Si no lo quiere o lo quiere
	// para despues se reagendara el callback
	this._fn_askCallback = function(
		str_comments,
		str_phoneNumber,
		str_callbackId,
		str_leadId
	) {
		let obj_self = this;
		obj_self._fn_deleteCallback(str_callbackId);
		return Swal.fire(
			this._fn_swalMixin(`
		<div style="min-height: 8rem; min-width: 15rem;text-align: left;padding: 0.8rem;">
			<span style='font-weight: bold;'>${traducirFrase("Recuerda llamar a")} ${str_phoneNumber}</span><br>
			<span>${str_comments}</span><br><br>
			<p style="font-size: 0.8rem;font-variant: petite-caps;">
				${traducirFrase("Nota: Selecciona una opcion para eliminar este recordatorio.Si hay mas recordatorios, estos se mostraran despues de seleccionar la accion de este recordatorio.Si seleccionas 'Recordar mas tarde', se reagendara el recordatorio para despues.")}
			</p>
		</div>`)
		).then(res => {
			if (res.value) {
				if (obj_self.int_status === 1) {
					// Si esta pausado llama
					$("#pantalla").val(str_phoneNumber);
					$("#btnllama").click();
				} else if (obj_self.int_status === 0) {
					// Si esta en ready, pero no esta
					// en llamada pone al agente en pausa
					// y llama
					enviaPausa("PAUSA", 1);
					setTimeout(function() {
						$("#pantalla").val(str_phoneNumber);
						$("#btnllama").click();
					}, 3000);
				} else {
					// Si esta en llamada genera un callback
					// para dentro de tres minutos
					SweetToaster.fire({
						icon: "success",
						text: traducirFrase("No puedes llamar en este momento, se te recordara mas tarde")
					});
					obj_self._fn_remindLater(str_comments, str_phoneNumber, str_leadId);
				}
			} else if (res.dismiss === "cancel") {
				obj_self._fn_remindLater(str_comments, str_phoneNumber, str_leadId);
			}
			return res;
		});
	};

	// Revisa si on hay callbacks globales
	// para agendar una notificacion
	this.fn_checkCallback = function() {
		let obj_self = this;
		this._fn_getCallback(res => {
			if (res.CallbackId !== "none") {
				if (obj_self._fn_milliRemaining(res.CallbackTime) <= 0) {
					obj_self._fn_notify(
						10,
						res.CallbackComments,
						res.CallbackPhoneNumber,
						res.CallbackId,
						res.CallbackLead
					);
				} else {
					obj_self._fn_notify(
						obj_self._fn_milliRemaining(res.CallbackTime),
						res.CallbackComments,
						res.CallbackPhoneNumber,
						res.CallbackId,
						res.CallbackLead
					);
				}
			}
		});
	};

	// Consulta todos los callbacks que tiene el agente
	// y les agenda una notificacion
	this.fn_getCallbacks = function() {
		let obj_self = this;
		this._fn_getOwnCallbacks(res => {
			res.Callbacks.forEach(elem => {
				if (obj_self._fn_milliRemaining(elem.Time) <= 0) {
					obj_self._fn_notify(
						10,
						elem.Comments,
						elem.PhoneNumber,
						elem.Id,
						elem.Lead
					);
				} else {
					obj_self._fn_notify(
						obj_self._fn_milliRemaining(elem.Time),
						elem.Comments,
						elem.PhoneNumber,
						elem.Id,
						elem.Lead
					);
				}
			});
		});
	};
}
