
function Common() {

	const self = this;

	this.ajaxUrl = '/';

	this.ajax = (proc, data, callback, completeCallback) => {
		$.ajax({
			type: 'post',
			url: self.ajaxUrl,
			data: { proc: proc, data: data },
			success: (res) => {
				try {
					const resJson = JSON.parse(res);
					if (self.checkJsonErrors(resJson)) {
						if ("undefined" !== typeof grecaptcha) {
							grecaptcha.reset();
						}
						return false;
					}

					if (callback) {
						callback(resJson);
					}

				} catch (e) {
					reportError(res, e);
				}
			},
			complete: () => {
				unshadeLoading();
				loadingOverlayClose();
				$('.button.is-loading').removeClass('is-loading')
				if ("function" === typeof completeCallback) {
					completeCallback();
				}
			}
		});
	}

	this.saveForm = (o, proc, callback) => {
		proc = proc || $(o).data('proc');

		if ($(o).find('.captcha-form').length && !grecaptcha.getResponse().length) {
			modalError($(o).find('.captcha-form').data('message'));
			return false;
		}

		self.shadeLoading();

		self.ajax(proc, $(o).serializeArray(), resJson => {
			self.processResponse(resJson, callback);
		});
	}

	this.submitFormO = (o, callback) => {
		proc = $(o).data('proc') || '';
		if (!proc) {
			modalError('Proc not set');
			return;
		}

		if ($(o).find('.captcha-form').length && !grecaptcha.getResponse().length) {
			modalError($(o).find('.captcha-form').data('message'));
			return false;
		}

		const formData = $(o).serializeForm2Simply(event);
		self.reqSimpleFull(proc, formData, callback);
	}

	this.processResponse = (resJson, callback, options) => {
		const r = resJson['reload']
			? () => { window.location.reload() }
			: (resJson['redirect']
				? () => { window.location.href = resJson['redirect']; }
				: (resJson['modal_close']
					? () => { modalClose(); }
					: null));

		if (resJson['status']) {
			modalSuccessInfo(resJson['status'], '', r);

		} else if (resJson['warning_status']) {
			modalWaring(resJson['warning_status'], r);

		} else if (resJson['status_bottom']) {
			modalInfo(resJson['status_bottom']);

		} else if (r) {
			r();
			return;
		}

		const inModal = (options && options['in_modal'])
			? options['in_modal']
			: false;

		unshadeLoading();
		loadingOverlayClose();

		if (callback) {
			callback(resJson);

		} else {
			self.renderReport(resJson, inModal);
		}
	}

	this.reqSimpleFull = (proc, options, callback) => {
		this.shadeLoading();
		let __options = {};
		if (options) {
			__options = JSON.parse(JSON.stringify(options));
			delete __options['in_modal'];
		}
		self.requestSimply(proc, __options, resJson => {
			self.processResponse(resJson, callback, options);
		});
	}

	this.requestSimply = (proc, options, callback) => {
		// console.log(proc);
		self.ajax(proc, options, resJson => {
			if (resJson['warning']) {
				self.modalWaring(resJson['warning']);
			} else {
				if (callback) {
					callback(resJson);
				} else {
					self.renderReport(resJson);
				}
			}
		});
	}

	this.renderReport = (resJson, inModal, options) => {
		const fsUrl = resJson['url'];
		options = options || {};
		options.footer = resJson.footer;

		if (inModal) {
			if (fsUrl !== undefined) {
				options['url'] = fsUrl;
			}

			modalReport(resJson['caption'], resJson['content'], options);

		} else {
			if (resJson['redirect']) {
				window.location.href = resJson['redirect'];
				return;
			}

			mainContent(resJson['caption'], resJson['content']);

			if (resJson['caption']) {
				document.title = stripTags(resJson['caption']);
			}

			const b = $('body');
			if (b.hasClass('is-loading')) {
				b.removeClass('is-loading');

			} else {
				console.log('is-l');
				if (fsUrl) {
					console.log('set url');
					history.pushState('', '', fsUrl);
				}

				if (typeof(options['no_scroll_top']) != 'boolean' || !options['no_scroll_top']) {
					const headerHeight = $('header').height();
					$('html, body').animate({ scrollTop: headerHeight }, 500);
				}
			}
		}

		unshadeLoading();
	}

	this.getProject = o => {
		const project = $(o).val();
		self.requestSimply('get_project', { project: project });
	}

	this.checkJsonErrors = resJson => {
		if (resJson['debug']) {
			// console.dir(JSON.parse(resJson['debug']));
		}

		if (resJson['error']) {
			// if ($('body').hasClass('is-loading')) {
			$('body').removeClass('is-loading');
			// }

			let errorDescription = (resJson['error_description']) ? resJson['error_description'] : resJson['error'];
			unshadeLoading();

			modalError(errorDescription, '', resJson['dontclose'] ? -1 : 0);

			if ($('.m-loading.loading').length) {
				setTimeout(function() {
					modalClose();
				}, 1000);
			}

			if (resJson['redirect']) {
				document.addEventListener('iziToast-closing', () => {
					window.location.href = resJson['url'];
				});

			} else if (resJson['focus']) {
				$('input[name=' + resJson['focus'] + ']').focus();
			}

			$('.button.is-loading').removeClass('is-loading');

			if (self.loadingBlockClass) {
				$('.' + self.loadingBlockClass).removeClass(self.loadingBlockClass).addClass('is-error');
			}

			return true;
		}

		return false;
	}

	this.headerMenuTrigger = () => {
		$('.header-menu-full').toggleClass('active');
	}

	this.shadeLoading = inModal => {
		inModal = inModal || false;
		// если окно показывается или открывается, то не обновлять отчет на странице, только в окне
		if ($('#modal').css('display') != 'none' && $('#modal').html()) {
			$('#modal .section.report').addClass('loading');

		} else if (inModal) {
			modalLoading();

		} else {
			$('.main-section').addClass('is-loading');
		}
	}

	this.serializeArray = a => {
		const ret = [];
		Object.keys(a).forEach(key => {
			ret.push({ name: key, value: a[key]});
		});
		return ret;
	}

	this.modalConfirm = (content, callback) => {

		iziToast.question({
			timeout: 0,
			overlay: true,
			toastOnce: true,
			overlayClose: true,
			drag: true,
			id: 'question',
			title: '',
			message: content,
			position: 'center',
			buttons: [
				['<button><b>Ok</b></button>', function (instance, toast) { instance.hide({ transitionOut: 'fadeOut' }, toast); callback(); }, true],
				['<button>Cancel</button>', function (instance, toast) { instance.hide({ transitionOut: 'fadeOut' }, toast); }] ],
		});

	}

	this.modalWaring = (content, callback) => {
		callback = callback || '';
		if ($('.iziToast-overlay.fadeIn')) {
			// $('.iziToast-overlay.fadeIn').remove();
		}

		iziToast.warning({
			timeout: 0,
			overlay: true,
			overlayClose: true,
			overlayColor: 'rgba(0, 0, 0, 0.6)',
			message: content,
			position: 'center',
			onClosing: function() {
				if (callback) { callback(); }
			},
		});
	};

}

document.addEventListener("mouseup", e => {
	if (e.button === 2) {
		return;
	}

	const btn = $(".header-menu-btn");
	if ((!btn.is(e.target) && btn.has(e.target).length === 0) || ($(e.target).prop('tagName') === "A" && $(e.target).closest('.header-menu-full'))) {
		$(".header-menu-full").removeClass('active');
	}

	if (e.target.classList.contains('expandable-caption')) {
		e.target.closest('.expandable-block-wrapper').classList.toggle('is-expanded');
	}

	// console.log($(e.target).closest('.is-expandable'));

	if (e.target.classList.contains('is-expandable') || e.target.closest('.is-expandable')) {
		const o = e.target.closest('.is-expandable');
		$(o).toggleClass('is-open');
		const block = $(o).next('.expand-area');
		$(block).slideToggle(500);
	}

});

function stripTags(html) {
	const tmp = document.createElement("div");
	tmp.innerHTML = html;
	return tmp.textContent || tmp.innerText || "";
}


function copyText(el) {
	var $tmp = $("<textarea>");
	$("body").append($tmp);
	$tmp.val($(el).text()).select();
	document.execCommand("copy");
	$tmp.remove();
	modalInfo('Copied to clipboard');
}

function copyTextHL(el) {
	copyText(el);
	$(el).addClass('--is-highlighted');
	setTimeout(() => {
		$(el).removeClass('--is-highlighted');
	}, 400);
}

function modalClose() {
	$('#modal').iziModal('close');
}

function modalLoading() {
	modalReport('Loading..', "<div class='m-loading loading'></div>");
}

function jqReadyGlobal() {

	$.ajaxSetup({
		timeout: 10000,
		error: function(e) {
			if ("timeout" === e.statusText) {
				modalError('Request timeout, please try again later', 'Error');
			}
		},

		beforeSend: (o, e) => {
			if (typeof(event) != "undefined" && typeof(event.type) != "undefined") {

				if (event.type == "submit" && typeof(event.submitter) != "undefined" && $(event.submitter)) {
					$(event.submitter).addClass('is-loading');
				} else if (event.type == "click" && typeof(event.target) != "undefined" && $(event.target).hasClass('button')) {
					$(event.target).addClass('is-loading');
				}
			}
		},

		complete: () => {
			$('.button.is-loading').removeClass('is-loading');
		},

	});

	isJqLoaded = true;

	const e = new CustomEvent('jq_ready');

	$(window).on("popstate", () => {
		location.reload();
	});


	$.fn.serializeForm = function () {
		var o = {};
		var a = this.serializeArray();

		$.each(a, function () {
			if (o[this.name] !== undefined) {
				if (!o[this.name].push) {
					o[this.name] = [o[this.name]];
				}
				o[this.name].push(this.value || '');
			} else {
				o[this.name] = this.value || '';
			}
		});

		$(this).find('input[type=checkbox]:not(:checked)').each((n, el) => {
			o[$(el).prop('name')] = '';
		});

		return o;
	};

	document.dispatchEvent(e);
}


function commonReady() {
	const e = new CustomEvent('common_ready');
	document.dispatchEvent(e);
}


function unshadeLoading() {
	// $('#mr-content').removeClass('loading');
	// $('#mr-caption').removeClass('loading');
	// $('.report.section.loading').removeClass('loading');
	$('.button.is-loading').removeClass('is-loading');

	$('.main-section').removeClass('is-loading');

}

function loadingProgress() {
	loadingOverlay('<progress class="progress-bar" max="100"></progress>');
}

function loadingProgressVal(val) {
	$('.progress-bar').prop('value', val);
}

function loadingOverlay(text) {
	if ($('.izitoast_loader').length > 0) {
		return;
	}

	if ('undefined' !== typeof iziToast) {
		iziToast.show({
			title: "<svg class=\"lds-gear-set\" width=\"50px\" height=\"50px\" style='margin-top: -15px' xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"xMidYMid\"><g transform=\"translate(50 50)\"> <g transform=\"translate(-17 -17) scale(0.5)\"> <g transform=\"rotate(333.234)\">" +
				"<animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0;360\" keyTimes=\"0;1\" dur=\"3.6s\" begin=\"0s\" repeatCount=\"indefinite\"></animateTransform><path d=\"M37.3496987939662 -7 L47.3496987939662 -7 L47.3496987939662 7 L37.3496987939662 7 A38 38 0 0 1 31.359972760794346 21.46047782418268 L31.359972760794346 21.46047782418268 L38.431040572659825 28.531545636048154 L28.531545636048154 38.431040572659825 L21.46047782418268 31.359972760794346 A38 38 0 0 1 7.0000000000000036 37.3496987939662 L7.0000000000000036 37.3496987939662 L7.000000000000004 47.3496987939662 L-6.999999999999999 47.3496987939662 L-7 37.3496987939662 A38 38 0 0 1 -21.46047782418268 31.35997276079435 L-21.46047782418268 31.35997276079435 L-28.531545636048154 38.431040572659825 L-38.43104057265982 28.531545636048158 L-31.359972760794346 21.460477824182682 A38 38 0 0 1 -37.3496987939662 7.000000000000007 L-37.3496987939662 7.000000000000007 L-47.3496987939662 7.000000000000008 L-47.3496987939662 -6.9999999999999964 L-37.3496987939662 -6.999999999999997 A38 38 0 0 1 -31.35997276079435 -21.460477824182675 L-31.35997276079435 -21.460477824182675 L-38.431040572659825 -28.531545636048147 L-28.53154563604818 -38.4310405726598 L-21.4604778241827 -31.35997276079433 A38 38 0 0 1 -6.999999999999992 -37.3496987939662 L-6.999999999999992 -37.3496987939662 L-6.999999999999994 -47.3496987939662 L6.999999999999977 -47.3496987939662 L6.999999999999979 -37.3496987939662 A38 38 0 0 1 21.460477824182686 -31.359972760794342 L21.460477824182686 -31.359972760794342 L28.531545636048158 -38.43104057265982 L38.4310405726598 -28.53154563604818 L31.35997276079433 -21.4604778241827 A38 38 0 0 1 37.3496987939662 -6.999999999999995 M0 -23A23 23 0 1 0 0 23 A23 23 0 1 0 0 -23\" fill=\"#28292f\"></path></g></g> <g transform=\"translate(0 22) scale(0.4)\"> <g transform=\"rotate(4.26642)\">" +
				"<animateTransform attributeName=\"transform\" type=\"rotate\" values=\"360;0\" keyTimes=\"0;1\" dur=\"3.6s\" begin=\"-0.225s\" repeatCount=\"indefinite\"></animateTransform><path d=\"M37.3496987939662 -7 L47.3496987939662 -7 L47.3496987939662 7 L37.3496987939662 7 A38 38 0 0 1 31.359972760794346 21.46047782418268 L31.359972760794346 21.46047782418268 L38.431040572659825 28.531545636048154 L28.531545636048154 38.431040572659825 L21.46047782418268 31.359972760794346 A38 38 0 0 1 7.0000000000000036 37.3496987939662 L7.0000000000000036 37.3496987939662 L7.000000000000004 47.3496987939662 L-6.999999999999999 47.3496987939662 L-7 37.3496987939662 A38 38 0 0 1 -21.46047782418268 31.35997276079435 L-21.46047782418268 31.35997276079435 L-28.531545636048154 38.431040572659825 L-38.43104057265982 28.531545636048158 L-31.359972760794346 21.460477824182682 A38 38 0 0 1 -37.3496987939662 7.000000000000007 L-37.3496987939662 7.000000000000007 L-47.3496987939662 7.000000000000008 L-47.3496987939662 -6.9999999999999964 L-37.3496987939662 -6.999999999999997 A38 38 0 0 1 -31.35997276079435 -21.460477824182675 L-31.35997276079435 -21.460477824182675 L-38.431040572659825 -28.531545636048147 L-28.53154563604818 -38.4310405726598 L-21.4604778241827 -31.35997276079433 A38 38 0 0 1 -6.999999999999992 -37.3496987939662 L-6.999999999999992 -37.3496987939662 L-6.999999999999994 -47.3496987939662 L6.999999999999977 -47.3496987939662 L6.999999999999979 -37.3496987939662 A38 38 0 0 1 21.460477824182686 -31.359972760794342 L21.460477824182686 -31.359972760794342 L28.531545636048158 -38.43104057265982 L38.4310405726598 -28.53154563604818 L31.35997276079433 -21.4604778241827 A38 38 0 0 1 37.3496987939662 -6.999999999999995 M0 -23A23 23 0 1 0 0 23 A23 23 0 1 0 0 -23\" fill=\"#0a0a0a\"></path></g></g> <g transform=\"translate(28 4) scale(0.3)\"> <g transform=\"rotate(355.734)\">" +
				"<animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0;360\" keyTimes=\"0;1\" dur=\"3.6s\" begin=\"-0.225s\" repeatCount=\"indefinite\"></animateTransform><path d=\"M37.3496987939662 -7 L47.3496987939662 -7 L47.3496987939662 7 L37.3496987939662 7 A38 38 0 0 1 31.359972760794346 21.46047782418268 L31.359972760794346 21.46047782418268 L38.431040572659825 28.531545636048154 L28.531545636048154 38.431040572659825 L21.46047782418268 31.359972760794346 A38 38 0 0 1 7.0000000000000036 37.3496987939662 L7.0000000000000036 37.3496987939662 L7.000000000000004 47.3496987939662 L-6.999999999999999 47.3496987939662 L-7 37.3496987939662 A38 38 0 0 1 -21.46047782418268 31.35997276079435 L-21.46047782418268 31.35997276079435 L-28.531545636048154 38.431040572659825 L-38.43104057265982 28.531545636048158 L-31.359972760794346 21.460477824182682 A38 38 0 0 1 -37.3496987939662 7.000000000000007 L-37.3496987939662 7.000000000000007 L-47.3496987939662 7.000000000000008 L-47.3496987939662 -6.9999999999999964 L-37.3496987939662 -6.999999999999997 A38 38 0 0 1 -31.35997276079435 -21.460477824182675 L-31.35997276079435 -21.460477824182675 L-38.431040572659825 -28.531545636048147 L-28.53154563604818 -38.4310405726598 L-21.4604778241827 -31.35997276079433 A38 38 0 0 1 -6.999999999999992 -37.3496987939662 L-6.999999999999992 -37.3496987939662 L-6.999999999999994 -47.3496987939662 L6.999999999999977 -47.3496987939662 L6.999999999999979 -37.3496987939662 A38 38 0 0 1 21.460477824182686 -31.359972760794342 L21.460477824182686 -31.359972760794342 L28.531545636048158 -38.43104057265982 L38.4310405726598 -28.53154563604818 L31.35997276079433 -21.4604778241827 A38 38 0 0 1 37.3496987939662 -6.999999999999995 M0 -23A23 23 0 1 0 0 23 A23 23 0 1 0 0 -23\" fill=\"#767676\"></path></g></g></g></svg>",
			message: text,
			slide: false,
			position: "center",
			class: "izitoast_loader",
			close: false,
			overlay: true,
			image: "",
			timeout: false
		});
	}
}



function loadingOverlayClose() {
	const ref = $('.izitoast_loader').data('izitoastRef');

	if (document.querySelector('.izitoast_loader') !== null) {
		iziToast.hide( {}, document.querySelector('.izitoast_loader'));
		setTimeout(function(){
			const overlay = $('.iziToast-overlay.fadeIn');
			const r = overlay.data('izitoastRef');
			if (r == ref) {
				overlay.addClass('fadeOut');
				setTimeout(function() {
					overlay.remove();
				}, 300);
			}
			$('.button.is-loading').removeClass('is-loading');
		}, 10);


	}
}


function reportError(res, e) {
	try {
		const resJson = JSON.parse(res);
		console.log(resJson);

	} catch (e) {
		console.log('Can\'t decode JSON');
		console.log(res);
	}

	console.log(e.stack);

	$('.is-loading').removeClass('is-loading');

	modalError('Ошибка ответа сервера!');
	modalClose();

	const ev = new CustomEvent('ev_js_error', { detail: {
			res: res,
			e: e.stack.toString(),
		}
	});

	document.dispatchEvent(ev);

}

function modalError(content, title, timeout, callback) {

	if (typeof noCloseModals != "undefined" || timeout == -1) {
		timeout = 0;
	} else {
		timeout = timeout || 7000;
	}
	title = title || 'Внимание!';
	content = content || 'Произошла неизвестная ошибка';
	callback = callback || '';

	if ($('.iziToast-overlay.fadeIn')) {
		//$('.iziToast-overlay.fadeIn').remove();
		// console.log('exists');
	}

	iziToast.error({
		timeout: timeout,
		title: title,
		overlay: true,
		overlayClose: true,
		overlayColor: 'rgba(0, 0, 0, 0.6)',
		message: content,
		position: 'center',
		onClosing: function() {
			if (callback) { callback(); }
		},
	});
}

function modalSuccessInfo(title, content, callback) {
	content = content || '';

	iziToast.success({
		timeout: 0,
		title: title,
		message: content,
		position: 'center',
		overlay: true,
		toastOnce: true,
		overlayClose: true,
		onClosing: function() {
			if (callback) { callback(); }
		},
	});
}


// let loadingBlockClass = '';


const __common = new Common();



function mainContent(caption, content) {
	// $('#main_caption').html(setReportCaption(caption));
	$('.main-section').html(content);
	// applyFeatures('#main_cont');
	// applyTips();
	return true;
}

function modalReport(title, content, options) {
	title = title || '&nbsp;';
	redraw = $('#modal').attr('aria-hidden');

	modalReportShow(title, content, options, redraw);
}


function modalReportShow(title, content, options, redraw) {
	redraw = redraw || false;
	options = options || {};
	const url = options.url || '';
	const width = options.width || '1000px';
	const footer = options.footer || '';

	if (!redraw) {
		$('#modal').iziModal({fullscreen: true, history: false });
	}
	$('#modal').iziModal('setUrl', url);

	$('#modal').iziModal('setTop', 30);
	$('#modal').iziModal('setBottom', 30);
	$('#modal').iziModal('setTitle', title);

	$('#modal').iziModal('setFooter', ((footer) ? '<div class="footer-buttons">' + footer + '</div>' : ''));
	// $('#modal').iziModal('setFooter', 'test footer');

	$('#modal').iziModal('setContent', '<div class="report section">' + content + '</div>');

	$('#modal').iziModal('open');
	$('#modal').iziModal('setWidth', width);
	modalIsOpen = true;

	// applyFeatures('#modal');
	// applyTips();
}

const modalInfo = (title, content, timeout) => {
	timeout = timeout || 3000;

	title = title || '';
	content = content || '';

	iziToast.success({
		timeout: timeout,
		title: title,
		message: content,
		position: 'bottomLeft',
	});
};


document.addEventListener('jq_ready', () => {
	$.fn.serializeForm2Simply = function (e) {

		const formData = [];

		$(this).find('input, select, textarea').each((n, el) => {
			if ($(el).prop('name') && $(el).prop('type') !== 'submit') {
				formData.push({ name: $(el).prop('name'), value: (el.type === 'checkbox')
						? ($(el).prop('checked') ? 1 : 0)
						: (el.value || '')});
			}
		});

		if (undefined !== e && 'object' === typeof e.submitter && $(e.submitter).data('name')) {
			formData.push({ name: '__submitter', value: $(e.submitter).data('name') })
		}

		return formData;
	};

});

