let MenuEditor = (function() {
	let public = {};

	/**
	 * ID редактироуемого элемента
	 */
	let __EditItemID = -1;

	let __Elements = {
		/**
		 * @type {HTMLDivElement}
		 */
		ButtonMenuAdd: undefined,

		/**
		 * @type {HTMLDivElement}
		 */
		ButtonMenuTopAdd: undefined,

		/**
		 * @type {HTMLDivElement}
		 */
		ButtonMenuEdit: undefined,

		/**
		 * @type {HTMLDivElement}
		 */
		ButtonMenuTopEdit: undefined,
	};

	let __CurrentCategory = undefined;

	__Elements.ButtonMenuAdd = document.querySelector("#CreateMainMenuItem");
	if (!__Elements.ButtonMenuAdd) {
		Messenger.Show("Некоторые элементы не были найдены");
		return undefined;
	}
	__Elements.ButtonMenuAdd.onclick = addItemModal.bind(__Elements.ButtonMenuAdd, MENU_CATEGORY.MAIN);

	__Elements.ButtonMenuTopAdd = document.querySelector("#CreateTopMenuItem");
	if (!__Elements.ButtonMenuTopAdd) {
		Messenger.Show("Некоторые элементы не были найдены");
		return undefined;
	}
	__Elements.ButtonMenuTopAdd.onclick = addItemModal.bind(__Elements.ButtonMenuTopAdd, MENU_CATEGORY.TOP);

	__Elements.ButtonMenuEdit = document.querySelector("#EditMainMenuItem");
	if (!__Elements.ButtonMenuEdit) {
		Messenger.Show("Некоторые элементы не были найдены");
		return undefined;
	}
	__Elements.ButtonMenuEdit.onclick = addControls.bind(__Elements.ButtonMenuEdit, MENU_CATEGORY.MAIN);

	__Elements.ButtonMenuTopEdit = document.querySelector("#EditTopMenuItem");
	if (!__Elements.ButtonMenuTopEdit) {
		Messenger.Show("Некоторые элементы не были найдены");
		return undefined;
	}
	__Elements.ButtonMenuTopEdit.onclick = addControls.bind(__Elements.ButtonMenuTopEdit, MENU_CATEGORY.TOP);

	function getMenu() {
		XHR.POST(replaceMenu, "/menu-get");
	}

	function replaceMenu(result) {
		if (result && "Menu" in result) {
			Main.ReplaceMenu(result.Menu);
		} else {
			Messenger.Show("Обновленное меню не было получено :(");
		}
	}

	function addItem() {

		/**
		 * @type {HTMLDivElement}
		 */
		let tree = document.querySelector("#NewItemParent");

		/**
		 * @type {HTMLInputElement}
		 */
		let caption = document.querySelector("#NewItemCaption");
		/**
		 * @type {HTMLInputElement}
		 */
		let link = document.querySelector("#NewItemLink");

		let isLink = document.querySelector("#NewItemIsLink");

		if (!caption || !link || !isLink || !tree) {
			Messenger.Show("Необходимые элементы не были найдены. Перезагрузите страницу и повторите попытку");
			return;
		}

		if (caption.value.length < 2) {
			Messenger.Show("Некорректный заголовок");
			return;
		}

		if (isLink.checked) {
			if (link.value.length < 1) {
				Messenger.Show("Некорректная ссылка");
				return;
			}
		}

		let parent = tree.querySelector(".branch.selected");
		if (parent) {
			parent = {
				Int32: (parent.dataset.id * 1),
				Valid: true,
			};
		} else {
			parent = {
				Valid: false,
				Int32: 0,
			}
		}

		let data = {
			Parent: parent,
			Caption: caption.value,
			Link: {
				Valid: isLink.checked,
				String: link.value,
			},
		};

		XHR.POST(
			function (result) {
				if (result && "Error" in result && result.Error) {
					Messenger.Show(result.Error);
				} else {
					Messenger.Show("Пункт меню был успешно добавлен");
					getMenu();
				}
			},
			"/menu-insert-item/"+__CurrentCategory,
			data
		);

		this.closest(".modal").querySelector(".close").click();
	}

	function editItem() {
		/**
		 * @type {HTMLInputElement}
		 */
		let caption = document.querySelector("#EditItemCaption");
		/**
		 * @type {HTMLInputElement}
		 */
		let link = document.querySelector("#EditItemLink");

		let isLink = document.querySelector("#EditItemIsLink");

		if (!caption || !link || !isLink) {
			Messenger.Show("Необходимые элементы не были найдены. Перезагрузите страницу и повторите попытку");
			return;
		}

		if (caption.value.length < 2) {
			Messenger.Show("Некорректный заголовок");
			return;
		}

		if (isLink.checked) {
			if (link.value.length < 2) {
				Messenger.Show("Некорректная ссылка");
				return;
			}
		}

		let data = {
			ID: __EditItemID,
			Caption: caption.value,
			Link: {
				Valid: isLink.checked,
				String: link.value,
			},
		};

		XHR.POST(
			function (result) {
				if (result && "Error" in result && result.Error) {
					Messenger.Show(result.Error);
				} else {
					Messenger.Show("Пункт меню был успешно изменён");
					caption.value = "";
					link.value = "";
					isLink.checked = false;
					getMenu();
				}
			},
			"/menu-update-item",
			data
		);

		this.closest(".modal").querySelector(".close").click();
	}

	function deleteItem(event) {
		let data = { ID: __EditItemID };

		XHR.POST(
			function (result) {
				if (result && "Error" in result && result.Error) {
					Messenger.Show(result.Error);
				} else {
					Messenger.Show("Пункт меню был успешно удалён");
					getMenu();
				}
			},
			"/menu-delete-item",
			data
		);

		this.closest(".modal").querySelector(".close").click();
	}

	/**
	 * Добавить элементы управления (редактировать, удалить) на каждый пункт меню
	 */
	function addControls(category) {
		__CurrentCategory = category;

		let query = "";
		if (__CurrentCategory === MENU_CATEGORY.MAIN) {
			query = ".menu .text[data-id]";
		} else {
			if (__CurrentCategory === MENU_CATEGORY.TOP) {
				query = "nav .text[data-id]";
			} else {
				return;
			}
		}

		let items = document.querySelectorAll(query);
		for (const item of items) {
			let edit = document.createElement("i"),
				textContent = document.createElement("span");

			textContent.textContent = item.textContent;
			item.textContent = null;

			edit.className = "fas fa-pen";
			edit.onclick = editItemModal;

			item.append(textContent, edit);
		}
	}

	/**
	 * Открыть окно для редактирования пункта меню
	 *
	 * @param {MouseEvent} event
	 */
	function editItemModal(event) {
		event.stopPropagation();
		event.preventDefault();

		let body = document.createElement("div"),
			inputCaption = document.createElement("input"),
			inputLink = document.createElement("input"),
			button = document.createElement("button"),
			buttonDel = document.createElement("button"),
			buttonGroup = document.createElement("div"),
			inputCheckbox = Controls.CreateCheckbox("Сделать ссылкой?", "EditItemIsLink", null, toggleIsLink),
			inputCheckboxActive = Controls.CreateCheckbox("Активный пункт?", "EditItemIsActive", null, toggleIsActive);

		let item = this.parentElement;
		item.classList.add("edit");

		__EditItemID = item.dataset.id * 1;

		inputCaption.type = "text";
		inputCaption.placeholder = "Заголовок пункта";
		inputCaption.id = "EditItemCaption";
		inputCaption.value = item.firstChild.textContent;

		inputLink.type = "text";
		inputLink.placeholder = "Ссылка на материал или внешний URL";
		inputLink.id = "EditItemLink";

		if (item.dataset.link) {
			if (item.dataset.link == "none") {
				inputLink.disabled = true;
			} else {
				inputCheckbox.querySelector("input").checked = true;

				if (item.dataset.link == "url") {
					inputLink.value = item.href;
				} else {
					inputLink.value = item.dataset.link;
				}
			}
		}

		if (item.parentElement.matches(".hide")) {
			inputCheckboxActive.querySelector("input").checked = false;
		} else {
			inputCheckboxActive.querySelector("input").checked = true;
		}

		button.onclick = editItem;
		button.textContent = "Изменить";

		buttonDel.onclick = deleteItem;
		buttonDel.textContent = "Удалить";

		buttonGroup.append(button, buttonDel);
		buttonGroup.className = "button-group";

		body.append(inputCaption, inputCheckboxActive, inputCheckbox, inputLink, buttonGroup);

		Modal.Create("Редактировать пункт в меню", body, cancelEdit);
	}

	function cancelEdit() {
		if (__EditItemID > -1) {
			let editableItem = document.querySelector(`.text[data-id="${__EditItemID}"`);
			if (editableItem) {
				editableItem.classList.remove("edit");
			}

			__EditItemID = -1;
		}
	}

	/**
	 * Создать мадальное окно с указанным типом
	 *
	 * @param {MENU_CATEGORY} category категория меню
	 */
	function addItemModal(category) {
		__CurrentCategory = category;

		let body = document.createElement("div"),
			menuTreeLabel = document.createElement("label"),
			menuTree = document.createElement("div"),
			inputCaption = document.createElement("input"),
			inputLink = document.createElement("input"),
			button = document.createElement("button"),
			buttonGroup = document.createElement("div"),
			inputCheckbox = Controls.CreateCheckbox("Сделать ссылкой?", "NewItemIsLink", null, toggleIsLink);

		menuTreeLabel.textContent = "Родительский элемент:";
		menuTree.className = "menu-tree";
		menuTree.id = "NewItemParent";

		inputCaption.type = "text";
		inputCaption.placeholder = "Заголовок пункта";
		inputCaption.id = "NewItemCaption";

		inputLink.type = "text";
		inputLink.placeholder = "Ссылка на материал или внешний URL";
		inputLink.id = "NewItemLink";
		inputLink.disabled = true;

		button.onclick = addItem;
		button.textContent = "Добавить";

		buttonGroup.append(button);
		buttonGroup.className = "button-group";

		body.append(menuTreeLabel, menuTree, inputCaption, inputCheckbox, inputLink, buttonGroup);

		getMenuSource(menuTree);

		Modal.Create("Добавить новый пункт в меню", body);
	}

	function toggleIsLink() {
		/**
		 * @type {HTMLInputElement}
		 */
		let input = this.parentElement.nextElementSibling;

		if (input) {
			input.disabled = !this.checked;
			if (input.disabled) {
				input.value = "";
			}
		}
	}

	function getMenuSource(elem) {
		XHR.POST(postGetMenuSource, "/menu-get-source/"+__CurrentCategory, {}, elem);
	}

	function postGetMenuSource(result, elem) {
		if (!result || !elem) {
			return;
		}

		if (!"Menu" in result) {
			Messenger.Show("Нет данных меню");
			return;
		}

		let tree = __init__Tree();

		buildTree(result.Menu, tree);

		tree.SetTo(elem);
	}

	/**
	 * 
	 * @param {[Object]} root 
	 * @param {Object} tree
	 */
	function buildTree(root, tree, branch) {
		for (let item of root) {

			let newBranch = tree.AddBranch(item.Caption, {id: item.ID}, branch);

			if (item.Rows !== null) {
				buildTree(item.Rows, tree, newBranch);
			}
		}
	}

	/**
	 *
	 * @param {MouseEvent} event
	 */
	function toggleIsActive(event) {
		if (__EditItemID < 0) {
			event.preventDefault();
			return;
		}

		let data = {
			ID: __EditItemID,
			Active: this.checked,
		};

		XHR.POST(
			function (result) {
				if (result && "Error" in result && result.Error) {
					Messenger.Show(result.Error);
				} else {
					Messenger.Show("Статус пункта меню был успешно изменён");
					getMenu();
				}
			},
			"/menu-update-item-active",
			data
		);

		this.closest(".modal").querySelector(".close").click();
	}

	return public;
})();