const resName = GetParentResourceName();
// Utils
function showNotification(message, duration=false) {
    var notification = $("#notification");
    
    if(duration) {
        notification.toast({
            autohide: true,
            delay: duration
        })
    } else {
        notification.toast({
            autohide: false,
        })
    }
    $("#notification-message").text(message)
    notification.toast("show")
}
async function buildingsDialog() {
	let inputBuildingModal = $("#input-building-dialog-modal")
	inputBuildingModal.modal("show");
	$("#input-building-search").val("");
	const buildings = await $.post(`https://${resName}/getAllBuildings`);
	let buildingsListDiv = $("#buildings-list");
	buildingsListDiv.empty();
	return new Promise(resolve => {
		for(const[_, buildingData] of Object.entries(buildings)) {
			let buildingDiv = $(`
				
${buildingData.id} - ${buildingData.label}
			`);
	
			buildingDiv.click(function() {
				inputBuildingModal.modal("hide");
				resolve(buildingData.id);
			});
	
			buildingsListDiv.append(buildingDiv);
		}	
	})
}
$("#input-building-search").on("keyup", function() {
	let text = $(this).val().toLowerCase();
	$("#buildings-list li").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
    });
})
async function playersListDialog(cb) {
	// Get players list
	let playersList = await $.get(`https://${resName}/getPlayersList`);
	let modal = $("#players-dialog-modal");
	$("#input-players-search").val("");
	let playerListDiv = $("#players-list")
	playerListDiv.empty();
	for(const playerData of playersList) {
		let playerDiv = $(`
			${playerData.playerName}
		`);
		playerDiv.click(function() {
			modal.modal("hide");
			cb(playerData.identifier);
		});
		playerListDiv.append(playerDiv);
	}
	modal.modal("show");
}
$("#input-players-search").on("keyup", function() {
	let text = $(this).val().toLowerCase();
	$("#players-list li").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(text) > -1)
    });
})
/* DOORS */
function changeLockIconButton(row, newState) {
	const lockedIcon = ``;
	const unlockedIcon = ``;
	const btnDiv = $(row).find(".toggle-lock-btn");
	if(newState) {
		btnDiv.html(lockedIcon);
		btnDiv.removeClass("btn-success");
		btnDiv.addClass("btn-danger");
	} else {
		btnDiv.html(unlockedIcon);
		btnDiv.removeClass("btn-danger");
		btnDiv.addClass("btn-success");
	}
}
let doorsDatatable = $("#doors-container").DataTable( {
	"lengthMenu": [10, 15, 20],
	"columnDefs": [
        { 
            "targets": -1, // Ultima colonna
            "data": null,
			"className": "col-1",
            "defaultContent": `
			
				
				
			
			`
        }
    ],
	"createdRow": async function ( row, data, index ) {
		const doorsData = data[data.length - 1]; 
		$(row).addClass("clickable");
		$(row).click(function() {
			editDoor(doorsData.id);
		});
		$(row).find(".toggle-lock-btn").click(async function(event) {
			event.stopPropagation();
			const newState = await $.post(`https://${resName}/toggleLock`, JSON.stringify({doorsId: doorsData.id}));
			if(newState < 0) return;
			changeLockIconButton(row, newState);
		});
		$(row).find(".teleport-to-door-btn").click(async function(event) {
			event.stopPropagation();
			$.post(`https://${resName}/teleportToDoor`, JSON.stringify({doorsId: doorsData.id}));
			$(this).tooltip("hide");
		}).tooltip();
		const currentLockState = await $.post(`https://${resName}/getLockState`, JSON.stringify({doorsId: doorsData.id}));
		if(currentLockState < 0) return;
		changeLockIconButton(row, currentLockState);
	},
} );
let doors = {};
function loadDoors() {
    $.post(`https://${resName}/getAllDoors`, {}, async function(rawDoors) {
		// Manually create the table to avoid incompatibilities due table indexing
		doors = {};
		for(const[k, doorsData] of Object.entries(rawDoors)) {
			doors[doorsData.id] = doorsData;
		}
		doorsDatatable.clear();
		for(const[doorsId, doorsData] of Object.entries(doors)) {
			doorsDatatable.row.add([
				doorsData.distance,
				doorsId,
                doorsData.label,
                doorsData.doors ? Object.entries(doorsData.doors).length : 0,
				doorsData.parentBuilding ? buildings[doorsData.parentBuilding].label : getLocalizedText("menu:none"),
				doorsData // Will be the last element of the data parameter in the createdRow callback
			])
		}
		doorsDatatable.draw()
	})
}
function setDoorsModalType(type) {
	$("#door-modal").data("type", type);
	switch(type) {
		case "building": {
			$("#used-doors-div").hide();
			$("#maximum-distance-div").hide().find("input").prop("required", false);
			$("#icon-coordinates-div").hide().find("input").prop("required", false);
			$("#use-building-rules-div").hide();
			$("#sliding-door-div").hide();
			$("#display-door-icon-div").hide();
			$("#can-be-lockpicked-div").hide();
			$("#vault-door-div").hide();
			$("#sound-data-div").hide();
			showBuildingOptions();
			break;
		}
		case "door": {
			$("#used-doors-div").show();
			$("#maximum-distance-div").show().find("input").prop("required", true);
			$("#icon-coordinates-div").show().find("input").prop("required", true);
			$("#use-building-rules-div").show();
			$("#sliding-door-div").show();
			$("#display-door-icon-div").show();
			$("#can-be-lockpicked-div").show();
			$("#vault-door-div").show();
			$("#sound-data-div").show();
			break;
		}
	}
}
function setupDefaultModalValues() {
	let doorModal = $("#door-modal");
	doorModal.find(".form-control").val("");
	$("#door-label").val( getLocalizedText("menu:default") );
	$(`input[name="doors-default-state"][value="0"]`).prop("checked", true);
	$("#used-doors-table").empty();
	$("#maximum-distance").val(4.0);
	$("#requires-job").prop("checked", false).change();
	$("#requires-item").prop("checked", false).change();
	$("#required-item-remove-on-use").prop("checked", false);
	$("#requires-code").prop("checked", false).change();
	$("#auto-closure-switch").prop("checked", false).change();
	$("#can-be-lockpicked").prop("checked", true).change();
	$("#alert-police-on-lockpick").prop("checked", false).change();
	$("#is-sliding-door").prop("checked", true).change();
	$("#display-door-icon").prop("checked", true).change();
	$("#requires-identifier").prop("checked", false).change();
	$("#allowed-identifiers").empty();
	$("#is-vault-door").prop("checked", false).change();
}
$("#register-bulk-doors-btn").click(async function() {
	let doorModal = $("#door-modal");
	$("html").hide();
	setDoorsModalType("door");
	// Converts from edit modal to create modal
	doorModal.data("action", "create");
	$("#delete-door-btn").hide();
	$("#save-door-btn").text( getLocalizedText("menu:create") );
	// Resets fields (only for the first door in bulk list)
	setupDefaultModalValues();
	// Gets the bulk doors list
	let mergedDoors = await $.get(`https://${resName}/getMergedDoors`);
	if(!mergedDoors || mergedDoors.length == 0) {
		$("html").show();
		return;
	}
	let finalDoorsObjectUsed = {};
	for(let i=0; i < mergedDoors.length; i++) {
		$("html").hide();
		let data = await $.post(`https://${resName}/bulkRegisterDoorsGroup`, JSON.stringify({
			doorsGroup: mergedDoors[i],
			finalDoorsObjectUsed: finalDoorsObjectUsed
		}));
		$("html").show();
		if(!data.doorsData) continue;
		doorModal.modal("show");
		// merge the final doors object used
		finalDoorsObjectUsed = Object.assign(finalDoorsObjectUsed, data.finalDoorsObjectUsed);
		let doorsData = data.doorsData;
		setUsedDoors(doorsData.doors);
		$("#icon-coords-x").val(doorsData.iconCoords.x).change();
		$("#icon-coords-y").val(doorsData.iconCoords.y).change();
		$("#icon-coords-z").val(doorsData.iconCoords.z).change();
		// Wait till the modal is closed
		await new Promise(resolve => {
			doorModal.one("hidden.bs.modal", function() {
				resolve();
			})
		})
	}
})
$("#new-door-btn").click(function() {
	let doorModal = $("#door-modal");
	setDoorsModalType("door");
	// Converts from create modal to edit modal
	doorModal.data("action", "create");
	
	$("#delete-door-btn").hide();
	$("#save-door-btn").text( getLocalizedText("menu:create") );
	
	// Resets fields
	setupDefaultModalValues();
	setParentBuilding(null);
	doorModal.modal("show");
})
function setUsedDoors(doors = {}) {
	let usedDoorsTable = $("#used-doors-table");
	usedDoorsTable.empty();
	for(const[doorObject, doorData] of Object.entries(doors)) {
		let x = (doorData.coords.x).toFixed(2);
		let y = (doorData.coords.y).toFixed(2);
		let z = (doorData.coords.z).toFixed(2);
		let newRow = $(`
			
				| ${x} | ${y} | ${z} | ${doorData.model} | 
		`)
		newRow.data("doorObject", doorObject);
		usedDoorsTable.append(newRow);
	}
}
$("#select-doors-btn").click(function() {
	closeMenu();
	let doorModal = $("#door-modal");
	doorModal.modal("hide");
	let action = doorModal.data("action");
	if(action === "edit") {
		var doorsId = doorModal.data("doorsId");
	}
	
	$.post(`https://${resName}/selectDoors`, JSON.stringify({doorsId: doorsId}), function(doors) {
		if(doors) {
			setUsedDoors(doors);
		}
		$("#doors_creator").show();
		doorModal.modal("show");
	})
})
$("#choose-icon-coords-btn").click(function() {
	closeMenu();
	let doorModal = $("#door-modal");
	doorModal.modal("hide");
	$.post(`https://${resName}/chooseIconCoords`, JSON.stringify({usedDoors: getUsedDoors()}), function(coords) {
		if(coords) {
			$("#icon-coords-x").val(coords.x).change();
			$("#icon-coords-y").val(coords.y).change();
			$("#icon-coords-z").val(coords.z).change();
		}
		
		$("#doors_creator").show();
		doorModal.modal("show");
	})
})
function getUsedDoors() {
	let doorsTable = $("#used-doors-table");
	let usedDoors = {};
	
	let isThereAtLeastOneDoor = false;
	doorsTable.find(".used-door").each(function() {
		isThereAtLeastOneDoor = true;
		let doorObject = $(this).data("doorObject");
		let model = parseInt( $(this).find(".model").text() );
		let x = parseFloat( $(this).find(".x-coord").text() );
		let y = parseFloat( $(this).find(".y-coord").text() );
		let z = parseFloat( $(this).find(".z-coord").text() );
		usedDoors[doorObject] = {
			coords: {
				x: x,
				y: y,
				z: z
			},
			model: model
		}
	});
	return isThereAtLeastOneDoor && usedDoors || null;
}
$("#choose-maximum-distance-btn").click(function() {
	let doors = getUsedDoors();
	if(!doors) return swal("ERROR", getLocalizedText("menu:no_doors_selected"), "error");;
	closeMenu();
	let doorModal = $("#door-modal");
	doorModal.modal("hide");
	let currentDistance = parseFloat( $("#maximum-distance").val() );
	$.post(`https://${resName}/chooseMaximumDistance`, JSON.stringify({doors: doors, distance: currentDistance}), function(maxDistance) {
		if(maxDistance) {
			$("#maximum-distance").val(maxDistance);
		}
		$("#doors_creator").show();
		doorModal.modal("show");
	})
})
async function getGangLabel(gangName) {
	return new Promise((resolve, reject) => {
		$.post(`https://${resName}/getGangLabel`, JSON.stringify({gangName: gangName}), function(gangLabel) {
			resolve(gangLabel);
		})
	})
}
async function setRequiredJob(requiresJob, allowedJobs) {
	$("#requires-job").prop("checked", requiresJob).change();
	let allowedJobsDiv = $("#allowed-jobs");
	allowedJobsDiv.val("");
	if(allowedJobs) {
		allowedJobsDiv.data("allowedJobs", allowedJobs);
		let text = "";
		let isTheFirst = true;
		for(const[jobName, _] of Object.entries(allowedJobs)) {
			if(isTheFirst) {
				text = await getJobLabel(jobName);
				isTheFirst = false;
			} else {
				text += `, ${await getJobLabel(jobName)}`;
			}
		}
		allowedJobsDiv.val(text);
	} else {
		allowedJobsDiv.data("allowedJobs", null);
	}
}
async function setRequiredGang(requiresGang, allowedGangs) {
	$("#requires-gang").prop("checked", requiresGang).change();
	let allowedGangsDiv = $("#allowed-gangs");
	allowedGangsDiv.val("");
	if(allowedGangs) {
		allowedGangsDiv.data("allowedGangs", allowedGangs);
		let text = "";
		let isTheFirst = true;
		for(const[gangName, _] of Object.entries(allowedGangs)) {
			if(isTheFirst) {
				text = await getGangLabel(gangName);
				isTheFirst = false;
			} else {
				text += `, ${await getGangLabel(gangName)}`;
			}
		}
		allowedGangsDiv.val(text);
	} else {
		allowedGangsDiv.data("allowedGangs", null);
	}
}
async function setRequiredItem(requiresItem, requiredItem) {
	$("#requires-item").prop("checked", requiresItem).change();
	let requiredItemDiv = $("#required-item");
	requiredItemDiv.val(requiredItem);
}
$("#requires-code").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#required-code").prop("disabled", !isEnabled).prop("required", isEnabled);;
})
function setRequiredCode(requiredCode) {
	$("#requires-code").prop("checked", requiredCode != undefined).change();
	
	$("#required-code").val(requiredCode);
}
function hideBuildingOptions() {
	$("#requires-job-div").hide();
	$("#requires-item-div").hide();
	$("#requires-code-div").hide();
	$("#auto-closure-div").hide();
	$("#default-doors-state-div").hide();
	$("#requires-identifier-div").hide();
}
function showBuildingOptions() {
	$("#requires-job-div").show();
	$("#requires-item-div").show();
	$("#requires-code-div").show();
	$("#auto-closure-div").show();
	$("#default-doors-state-div").show();
	$("#requires-identifier-div").show();
}
function setParentBuilding(buildingId) {
	if(buildingId != undefined) {
		$("#use-building-rules").prop("checked", true).change();
		$("#parent-building").data("buildingId", buildingId).val(buildings[buildingId].label);
	} else {
		$("#use-building-rules").prop("checked", false).change();
		$("#parent-building").data("buildingId", null).val("");
	}
}
async function editDoor(doorsId) {
	setDoorsModalType("door");
	let doorModal = $("#door-modal");
	doorModal.find("input .form-control").val("");
	doorModal.data("doorsId", doorsId);
	// Converts from create modal to edit modal
	doorModal.data("action", "edit");
	
	$("#delete-door-btn").show();
	$("#save-door-btn").text( getLocalizedText("menu:save") );
	
	let doorsData = doors[doorsId];
	$("#door-label").val(doorsData.label);
	setUsedDoors(doorsData.doors);
	$(`input[name="doors-default-state"][value="${doorsData.defaultState}"]`).prop("checked", true);
	$("#maximum-distance").val(doorsData.maxDistance);
	setRequiredJob(doorsData.allowedJobs ? true : false, doorsData.allowedJobs);
	
	if(await getFramework() == "QB-core") {
		setRequiredGang(doorsData.allowedGangs ? true : false, doorsData.allowedGangs);
	}
	setRequiredItem(doorsData.requiredItem ? true : false, doorsData.requiredItem);
	$("#required-item-remove-on-use").prop("checked", doorsData.requiredItem && doorsData.requiredItemRemoveOnUse);
	setRequiredCode(doorsData.requiredCode);
	setAutoClosure(doorsData.autoClosureSeconds);
	setParentBuilding(doorsData.parentBuilding);
	$("#requires-job-and-item").prop("checked", doorsData.requiresJobAndItem);
	$("#is-sliding-door").prop("checked", doorsData.isSliding);
	$("#display-door-icon").prop("checked", doorsData.displayIcon);
	$("#can-be-lockpicked").prop("checked", doorsData.canBeLockpicked);
	$("#alert-police-on-lockpick").prop("checked", doorsData.alertPoliceOnLockpick);
	// Requires identifier
	$("#requires-identifier").prop("checked", doorsData.requiresIdentifier).change();
	// Add identifiers
	$("#allowed-identifiers").empty();
	if(doorsData.allowedIdentifiers) {
		for(const [identifier, _] of Object.entries(doorsData.allowedIdentifiers)) {
			addIdentifierToList(identifier);
		}
	}
	setVaultData(doorsData.vault);
	setSoundsData(doorsData.soundsData);
	$("#icon-coords-x").val(doorsData.iconCoords.x).change();
	$("#icon-coords-y").val(doorsData.iconCoords.y).change();
	$("#icon-coords-z").val(doorsData.iconCoords.z).change();
	doorModal.modal("show");
}
function submitDoor() {
	let doorModal = $("#door-modal");
	let action = doorModal.data("action");
	let doorData = {
		label: $("#door-label").val(),
		defaultState: parseInt( $("input[name='doors-default-state']:checked").val() ),
		maxDistance: parseFloat( $("#maximum-distance").val() ),
		iconCoords: {
			x: parseFloat( $("#icon-coords-x").val() ),
			y: parseFloat( $("#icon-coords-y").val() ),
			z: parseFloat( $("#icon-coords-z").val() )
		},
		doors: getUsedDoors(),
		allowedJobs: $("#requires-job").prop("checked") ? $("#allowed-jobs").data("allowedJobs") : null,
		allowedGangs: $("#requires-gang").prop("checked") ? $("#allowed-gangs").data("allowedGangs") : null,
		requiredItem: $("#requires-item").prop("checked") ? $("#required-item").val() : null,
		requiredItemRemoveOnUse: $("#required-item-remove-on-use").prop("checked"),
		requiresJobAndItem: $("#requires-job-and-item").prop("checked"),
		requiredCode: $("#requires-code").prop("checked") ? $("#required-code").val() : null,
		autoClosureSeconds: $("#auto-closure-switch").prop("checked") ? parseInt( $("#auto-closure").val() ) : null,
		parentBuilding: $("#use-building-rules").prop("checked") ? $("#parent-building").data("buildingId") : null,
		isSliding: $("#is-sliding-door").prop("checked"),
		displayIcon: $("#display-door-icon").prop("checked"),
		requiresIdentifier: $("#requires-identifier").prop("checked"),
		allowedIdentifiers: getAllowedIdentifiers(),
		vault: getVaultData(),
		canBeLockpicked: $("#can-be-lockpicked").prop("checked"),
		alertPoliceOnLockpick: $("#alert-police-on-lockpick").prop("checked"),
		soundsData: getSoundsData()
	}
	switch(action) {
		case "create": {
			$.post(`https://${resName}/createDoor`, JSON.stringify(doorData), function(isSuccessful) {
				if(isSuccessful) {
					loadDoors();
					doorModal.modal("hide");
				}
			});
			break;
		}
		case "edit": {
			let doorsId = doorModal.data("doorsId");
			$.post(`https://${resName}/updateDoor`, JSON.stringify({doorsId: doorsId, doorData: doorData}), function(isSuccessful) {
				if(isSuccessful) {
					loadDoors();
					doorModal.modal("hide");
				}
			});
			break;
		}
	}
}
function submitBuilding() {
	let buildingModal = $("#door-modal");
	let action = buildingModal.data("action");
	let buildingData = {
		label: $("#door-label").val(),
		defaultState: parseInt( $("input[name='doors-default-state']:checked").val() ),
		allowedJobs: $("#requires-job").prop("checked") ? $("#allowed-jobs").data("allowedJobs") : null,
		allowedGangs: $("#requires-gang").prop("checked") ? $("#allowed-gangs").data("allowedGangs") : null,
		requiredItem: $("#requires-item").prop("checked") ? $("#required-item").val() : null,
		requiredItemRemoveOnUse: $("#required-item-remove-on-use").prop("checked"),
		requiresJobAndItem: $("#requires-job-and-item").prop("checked"),
		requiredCode: $("#requires-code").prop("checked") ? $("#required-code").val() : null,
		autoClosureSeconds: $("#auto-closure-switch").prop("checked") ? parseInt( $("#auto-closure").val() ) : null,
		requiresIdentifier: $("#requires-identifier").prop("checked"),
		allowedIdentifiers: getAllowedIdentifiers()
	}
	switch(action) {
		case "create": {
			$.post(`https://${resName}/createBuilding`, JSON.stringify(buildingData), function(isSuccessful) {
				if(isSuccessful) {
					loadBuildings();
					buildingModal.modal("hide");
				}
			});
			break;
		}
		case "edit": {
			let buildingId = buildingModal.data("buildingId");
			$.post(`https://${resName}/updateBuilding`, JSON.stringify({buildingId: buildingId, buildingData: buildingData}), function(isSuccessful) {
				if(isSuccessful) {
					loadBuildings();
					buildingModal.modal("hide");
				}
			});
			
			break;
		}
	}
}
$("#door-form").submit(function(event) {
	if(isThereAnyErrorInForm(event)) return;
	let type = $("#door-modal").data("type");
	if(type == "door") {
		submitDoor();
	} else if(type == "building") {
		submitBuilding();
	}
})
$("#delete-door-btn").click(function() {
	let doorModal = $("#door-modal");
	let type = doorModal.data("type");
	switch(type) {
		case "door": {
			let doorsId = doorModal.data("doorsId");
			$.post(`https://${resName}/deleteDoor`, JSON.stringify({doorsId: doorsId}), function(isSuccessful) {
				if(isSuccessful) {
					loadDoors();
					doorModal.modal("hide");
				}
			});
			break;
		}
		case "building": {
			let buildingId = doorModal.data("buildingId");
			$.post(`https://${resName}/deleteBuilding`, JSON.stringify({buildingId: buildingId}), function(isSuccessful) {
				if(isSuccessful) {
					loadBuildings();
					doorModal.modal("hide");
				}
			});
			break;
		}
	}
});
/* DOORS - Jobs */
$("#requires-job").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#choose-jobs-btn").prop("disabled", !isEnabled);
});
$("#choose-jobs-btn").click(async function() {
	const oldJobs =  $("#allowed-jobs").data("allowedJobs");
	
	let allowedJobs = await jobsDialog(oldJobs);
	setRequiredJob(allowedJobs ? true : false, allowedJobs);
});
/* DOORS - Gangs QBCore */
$("#requires-gang").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#choose-gangs-btn").prop("disabled", !isEnabled);
});
$("#choose-gangs-btn").click(async function() {
	const oldGangs =  $("#allowed-gangs").data("allowedGangs");
	
	let allowedGangs = await gangsDialog(oldGangs);
	setRequiredGang(allowedGangs ? true : false, allowedGangs);
});
/* DOORS - Item */
$("#requires-item").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#choose-item-btn").prop("disabled", !isEnabled);
	$("#required-item").prop("disabled", !isEnabled);
	$("#required-item").prop("required", isEnabled);
	$("#required-item-remove-on-use").prop("checked", false).prop("disabled", !isEnabled);
});
$("#choose-item-btn").click(async function() {
	const itemName = await itemsDialog();
	if(!itemName) return;
	$("#required-item").val(itemName);
});
/* DOORS - Item & Job */
function requiresBothJobAndItem() {
	let requiresItem = $("#requires-item").prop("checked");
	let requiresJob = $("#requires-job").prop("checked");
	let requiresBoth = requiresItem && requiresJob;
	$("#requires-job-and-item-div").toggle(requiresBoth);
	if(!requiresBoth) {
		$("#requires-job-and-item").prop("checked", false);
	}
}
$("#requires-item, #requires-job").change(requiresBothJobAndItem);
/* DOORS - Auto closure */
$("#auto-closure-switch").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#auto-closure").prop("disabled", !isEnabled);
})
function setAutoClosure(seconds) {
	$("#auto-closure-switch").prop("checked", seconds ? true : false).change();
	$("#auto-closure").val(seconds ? seconds : null);
}
/* BUILDINGS */
let buildingsDatatable = $("#buildings-container").DataTable( {
	"lengthMenu": [10, 15, 20],
	"columnDefs": [
        { 
            "targets": -1, // Ultima colonna
            "data": null,
			"className": "col-1",
            "defaultContent": `
			
			`
        }
    ],
	"createdRow": async function ( row, data, index ) {
		const buildingData = data[data.length - 1]; 
		$(row).addClass("clickable");
		$(row).click(function() {
			editBuilding(buildingData.id);
		})
		
		$(row).find(".unlock-building-btn").click(function(event) {
			event.stopPropagation();
			$.post(`https://${resName}/setBuildingLockState`, JSON.stringify({buildingId: buildingData.id, newState: 0}));
		});
		$(row).find(".lock-building-btn").click(function(event) {
			event.stopPropagation();
			$.post(`https://${resName}/setBuildingLockState`, JSON.stringify({buildingId: buildingData.id, newState: 1}));
		});
	},
} );
let buildings = {};
function loadBuildings() {
    $.post(`https://${resName}/getAllBuildings`, {}, async function(rawBuildings) {
		// Manually create the table to avoid incompatibilities due table indexing
		buildings = {};
		for(const[k, buildingData] of Object.entries(rawBuildings)) {
			buildings[buildingData.id] = buildingData;
		}
		buildingsDatatable.clear();
		for(const[buildingId, buildingData] of Object.entries(buildings)) {
			buildingsDatatable.row.add([
				buildingId,
                buildingData.label,
                buildingData.defaultState === 0 ? getLocalizedText("menu:unlocked") : getLocalizedText("menu:locked"),
				buildingData
			])
		}
		buildingsDatatable.draw()
	})
}
$("#new-building-btn").click(function() {
	let buildingModal = $("#door-modal");
	setDoorsModalType("building");
	setupDefaultModalValues();
	buildingModal.data("action", "create");
	buildingModal.modal("show");
});
function editBuilding(buildingId) {
	let buildingData = buildings[buildingId];
	setDoorsModalType("building");
	let buildingModal = $("#door-modal");
	buildingModal.data("action", "edit");
	
	buildingModal.find("input .form-control").val("");
	buildingModal.data("buildingId", buildingId);
	// Converts from create modal to edit modal
	buildingModal.data("action", "edit");
	
	$("#delete-door-btn").show();
	$("#save-door-btn").text( getLocalizedText("menu:save") );
	
	$("#door-label").val(buildingData.label);
	$(`input[name="doors-default-state"][value="${buildingData.defaultState}"]`).prop("checked", true);
	setRequiredJob(buildingData.allowedJobs ? true : false, buildingData.allowedJobs);
	setRequiredGang(buildingData.allowedGangs ? true : false, buildingData.allowedGangs);
	setRequiredItem(buildingData.requiredItem ? true : false, buildingData.requiredItem);
	$("#required-item-remove-on-use").prop("checked", buildingData.requiredItem && buildingData.requiredItemRemoveOnUse);
	
	setRequiredCode(buildingData.requiredCode);
	setAutoClosure(buildingData.autoClosureSeconds);
	$("#requires-job-and-item").prop("checked", buildingData.requiresJobAndItem);
	// Requires identifier
	$("#requires-identifier").prop("checked", buildingData.requiresIdentifier).change();
	// Add identifiers
	$("#allowed-identifiers").empty();
	if(buildingData.allowedIdentifiers) {
		for(const [identifier, _] of Object.entries(buildingData.allowedIdentifiers)) {
			addIdentifierToList(identifier);
		}
	}
	buildingModal.modal("show");
}
$("#use-building-rules").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#choose-building-btn").prop("disabled", !isEnabled);
	if(isEnabled) {
		hideBuildingOptions();
	} else {
		showBuildingOptions();
	}
})
$("#choose-building-btn").click(async function() {
	const buildingId = await buildingsDialog();
	if(!buildingId) return;
	setParentBuilding(buildingId);
});
/* SETTINGS */
$("#settings_enableDoorlockAnimation").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#doorlock-animation-div").find("input").prop("disabled", !isEnabled).prop("required", isEnabled);
})
function setDoorlockAnimation(doorLockAnimation) {
	$("#settings_enableDoorlockAnimation").prop("checked", doorLockAnimation.isEnabled).change();
	
	$("#settings_doorlockAnimationDictionary").val(doorLockAnimation.dict);
	$("#settings_doorlockAnimationName").val(doorLockAnimation.name);
	$("#settings_doorlockAnimationDuration").val(doorLockAnimation.duration);
}
function getDoorlockAnimation() {
	if( $("#settings_enableDoorlockAnimation").prop("checked") ) {
		let doorLockAnimation = {
			dict: $("#settings_doorlockAnimationDictionary").val(),
			name: $("#settings_doorlockAnimationName").val(),
			duration: parseInt( $("#settings_doorlockAnimationDuration").val() ),
			isEnabled: true
		}
		return doorLockAnimation;
	} else {
		let doorLockAnimation = {
			isEnabled: false
		}
		return doorLockAnimation;
	}
}
$("#import-from-qb-doorlock-btn").click(async function() {
	if(!await confirmWarning(getLocalizedText("menu:backup_reccomended"))) return;
	const response = await $.post(`https://${resName}/importFromQbDoorlock`, JSON.stringify({}));
	if(response === true) {
		loadDoors();
	}
	showServerResponse(response);
});
$("#import-from-ox-doorlock-btn").click(async function() {
	if(!await confirmWarning(getLocalizedText("menu:backup_reccomended"))) return;
	const response = await $.post(`https://${resName}/importFromOxDoorlock`, JSON.stringify({}));
	if(response === true) {
		loadDoors();
	}
	showServerResponse(response);
});
function loadSettings(fullConfig) {
	setTomSelectValue("#settings_locale", fullConfig.locale);
	
	$("#settings_acePermission").val(fullConfig.acePermission);
	$("#settings_saveDoorStateAfterRestart").prop("checked", fullConfig.saveDoorStateAfterRestart);
	$("#settings_doorlockIconSize").val(fullConfig.doorLockIconSize);
	$("#settings_lockpickName").val(fullConfig.lockpickName);
	$("#settings_lockpickMinimumQuantity").val(fullConfig.lockpickMinimumQuantity);
	$("#settings_lockpickLoseOnUse").prop("checked", fullConfig.lockpickLoseOnUse);
	$("#settings_lockpickMinimumPolice").val(fullConfig.lockpickMinimumPolice);
	// Door icon
	$("#settings_use3dTextInsteadOfIcon").prop("checked", fullConfig.use3dTextInsteadOfIcon);
	$("#settings_exclusiveDoorIcon").prop("checked", fullConfig.exclusiveDoorIcon);
	setDoorlockAnimation(fullConfig.doorLockAnimation);
	// Targeting
	setTomSelectValue("settings-targeting-script", fullConfig.targetingScript);
	// Keys
	$("#settings-confirm-key").val(fullConfig.confirmKey);
	$("#settings-key-to-toggle-door-status").val(fullConfig.keyToToggleDoorStatus);
}
$("#settings").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	let clientSettings = {
		doorLockAnimation: getDoorlockAnimation(),
		doorLockIconSize: parseFloat( $("#settings_doorlockIconSize").val() ),
		use3dTextInsteadOfIcon: $("#settings_use3dTextInsteadOfIcon").prop("checked"),
		targetingScript:$("#settings-targeting-script").val(),
		confirmKey: parseInt( $("#settings-confirm-key").val() ),
		keyToToggleDoorStatus: parseInt( $("#settings-key-to-toggle-door-status").val() ),
		exclusiveDoorIcon: $("#settings_exclusiveDoorIcon").prop("checked"),
	}
	let sharedSettings = {
		locale: $("#settings_locale").val(),
		lockpickName: $("#settings_lockpickName").val(),
	}
	let serverSettings = {
		acePermission: $("#settings_acePermission").val(),
		saveDoorStateAfterRestart: $("#settings_saveDoorStateAfterRestart").prop("checked"),
		lockpickMinimumQuantity: parseInt( $("#settings_lockpickMinimumQuantity").val() ),
		lockpickLoseOnUse: $("#settings_lockpickLoseOnUse").prop("checked"),
		lockpickMinimumPolice: parseInt( $("#settings_lockpickMinimumPolice").val() )
	}
	const response = await $.post(`https://${resName}/saveSettings`, JSON.stringify({ clientSettings, serverSettings, sharedSettings}));
	showServerResponse(response);
	refreshTranslations(sharedSettings.locale);
});
// Doors Identifiers 
$("#requires-identifier").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#identifiers-div").find("input, button").prop("disabled", !isEnabled);
});
$("#is-vault-door").change(function() {
	let isEnabled = $(this).prop("checked");
	$("#vault-door-options").toggle(isEnabled);
	$("#vault-speed").prop("required", isEnabled);
	if(isEnabled) {
		$(`input[name="vault-type"][value="heading"]`).prop("checked", true).change();
	} else {
		$("#vault-opened-angle").prop("required", false);
		$("#vault-closed-angle").prop("required", false);
	}
})
$(`input[name="vault-type"]`).change(function() {
	let type = $(this).val();
	if(type == "ratio") {
		$("#vault-opened-angle").attr('placeholder', "Usually 1.0 or -1.0").prop("required", false);
		$("#vault-closed-angle").attr('placeholder', "Usually 0.0").prop("required", false);
		$("#vault-get-opened-heading").hide();
		$("#vault-get-closed-heading").hide();
	} else {
		$("#vault-opened-angle").attr('placeholder', "0-360").prop("required", true);
		$("#vault-closed-angle").attr('placeholder', "0-360").prop("required", true);
		$("#vault-get-opened-heading").show();
		$("#vault-get-closed-heading").show();
	}
});
async function getHeadingOfFirstDoorObject() {
	return new Promise((resolve, reject) => {
		closeMenu();
		let doorModal = $("#door-modal");
		doorModal.modal("hide");
		
		const doorObject = $("#used-doors-table").find(".used-door").first().data("doorObject");
		$.post(`https://${resName}/getHeading`, JSON.stringify({doorObject: doorObject}), function(heading) {
			$("#doors_creator").show();
			doorModal.modal("show");
			resolve( Math.floor(heading) );
		});
	})
}
$("#vault-get-opened-heading").click(async function() {
	const heading = await getHeadingOfFirstDoorObject();
	$("#vault-opened-angle").val(heading);
})
$("#vault-get-closed-heading").click(async function() {
	const heading = await getHeadingOfFirstDoorObject();
	$("#vault-closed-angle").val(heading);
})
function addIdentifierToList(identifier) {
	let allowedIdentifiers = $("#allowed-identifiers");
	let identifierDiv = $(`
		${identifier} 
	`)
	identifierDiv.find(".btn-close").click(function() {
		$(this).parent().remove();
	});
	allowedIdentifiers.append(identifierDiv);
}
$("#add-identifier-btn").click(function() {
	let identifierDiv = $("#identifier-to-add")
	let identifier = identifierDiv.val();
	if(identifier) {
		addIdentifierToList(identifier);
		identifierDiv.val("");
	}
})
$("#choose-player-btn").click(function() {
	playersListDialog(identifier => {
		$("#identifier-to-add").val(identifier);
	});
})
function getAllowedIdentifiers() {
	let identifiers = {};
	$("#allowed-identifiers").find("li").each(function() {
		identifiers[$(this).data("identifier")] = true;
	});
	return identifiers;
}
function getVaultData() {
	if(!$("#is-vault-door").prop("checked"))
		return null;
	let vaultData = {
		speed: parseFloat( $("#vault-speed").val() ),
		doorHeavy: $("#vault-make-door-extremely-heavy").prop("checked"),
		invertedDirection: $("#vault-inverted-direction").prop("checked"),
		openedAngle: parseFloat( $("#vault-opened-angle").val() ),
		closedAngle: parseFloat( $("#vault-closed-angle").val() ),
		type: $('input[name="vault-type"]:checked').val()
	}
	return vaultData
}
function setVaultData(vaultData) {
	if(vaultData) {
		$("#is-vault-door").prop("checked", true).change();
		$("#vault-speed").val(vaultData.speed);
		$("#vault-make-door-extremely-heavy").prop("checked", vaultData.doorHeavy);
		$("#vault-inverted-direction").prop("checked", vaultData.invertedDirection);
		$("#vault-opened-angle").val(vaultData.openedAngle);
		$("#vault-closed-angle").val(vaultData.closedAngle);
		$(`input[name="vault-type"][value=${vaultData.type || "ratio"}]`).prop("checked", true).change();
	} else {
		$("#is-vault-door").prop("checked", false).change();
	}
}
function getSoundsData() {
	let unlockSound = $("#unlock-sound").val();
	let lockSound = $("#lock-sound").val();
	return {
		unlockSound: unlockSound == "none" ? null : unlockSound,
		lockSound: lockSound == "none" ? null : lockSound
	}
}
function setSoundsData(data) {
	if(!data) {
		setTomSelectValue("#unlock-sound", "none");
		setTomSelectValue("#lock-sound", "none");
		return;
	};
	setTomSelectValue("#unlock-sound", data.unlockSound);
	setTomSelectValue("#lock-sound", data.lockSound);
}
function reloadAllData() {
	resetNexus();
	loadBuildings();
    loadDoors();
}
// Open/Close menu
async function openMenu(version, fullConfig) {
	$("#doors-creator-version").text(version);
    $("#doors_creator").show();
	reloadAllData();
	loadSettings(fullConfig);
	if(await getFramework() == "QB-core") {
		$("#requires-gang-div").show()
	}
}
function closeMenu() {
	// Resets current active tab
	$("#doors_creator").find(".nav-link, .tab-pane").each(function() {
		if($(this).data("isDefault") == "1") {
			$(this).addClass(["active", "show"])
		} else {
			$(this).removeClass(["active", "show"])
		}
	})
	
    $("#doors_creator").hide();
    $.post(`https://${resName}/close`, {})
}
$("#close-main-btn").click(closeMenu);
$("#input-div").submit(function(event) {
	if(isThereAnyErrorInForm(event)) return;
	let input = $("#code-input").val();
	$.post(`https://${resName}/receiveInput`, JSON.stringify({input: input}));
	$("#code-input").val("");
})
$("#code-input-cancel-btn").click(function() {
	$.post(`https://${resName}/cancelInput`, JSON.stringify({}));
})
// [[ NEXUS ]]
const voteInstanceRater = raterJs({
	starSize: 35,
	element: document.querySelector("#vote-instance-rater"),
	rateCallback: async function rateCallback(rating, done) {
		const instanceId = $("#nexus-modal").data("instance").id;
		const success = await $.post(`https://${resName}/nexus/rateInstance`, JSON.stringify({rating, instanceId}));
		if(success) voteInstanceRater.setRating(rating);
		done();
	}
});
const averageInstanceVotes = raterJs({
	starSize: 20,
	readOnly: true,
	element: document.querySelector("#nexus-modal-instance-average-rating"),
});
$("#nexus-import-instance-btn").click(async function() {
	const instance = $("#nexus-modal").data("instance");
	const id = instance.id;
	const response = await $.post(`https://${resName}/nexus/importInstance`, JSON.stringify({id}));
	$("#nexus-modal").modal("hide");
	if(response === true) reloadAllData();
	showServerResponse(response);
});
let nexusDataTable = $("#nexus-table").DataTable({
	"lengthMenu": [5, 10, 15, 20],
	"pageLength": 5,
	"order": [[4, 'desc'], [5, 'desc']],
	"createdRow": function(row, data, index) {
		$(row).addClass("clickable");
		$(row).click(function() {
			const instance = $(this).data("instance");
			showInstance(instance);
			$("#nexus-modal").modal("show");
		});
	},
	"columnDefs": [
		{ "defaultContent": "???", "targets": "_all" },
		{
			"targets": 2,
			render: function(data, type, row) {
				if(!data) return 9999;
				if(type === "display" || type === "filter") return data + "m";
				return parseFloat(data);
			}
		}
	]
});
function showInstance(instance) {
	$("#nexus-modal").data("instance", instance);
	$("#nexus-modal-instance-listing-label").text(instance.label);
	$("#nexus-modal-instance-description").text(instance.description || getLocalizedText("menu:nexus:no_description"));
	$("#nexus-modal-instance-author").text(instance.author);
	$("#nexus-instance-building-name").text(instance.content.building.label);
	// Content names and labels
	$("#nexus-modal-instance-content").empty();
	instance.content.doors.forEach(content => {
		$("#nexus-modal-instance-content").append(`
			${content.label || content.name}
		`);
	});
	// Votes
	if(instance?.votes?.total > 0) {
		averageInstanceVotes.setRating(instance?.votes.averageRating);
	} else {
		averageInstanceVotes.setRating(0);
	}
	$("#nexus-modal-instance-total-votes").text(instance.votes?.total || 0);
	// This server vote
	voteInstanceRater.setRating(0);
}
$("#upload-to-nexus-btn").click(async function() {
	const buildingId = await buildingsDialog();
	if(!buildingId) return;
	$("#nexus-modal-upload").data("buildingId", buildingId);
	$("#nexus-upload-label").val("");
	$("#nexus-upload-description").val("");
	$("#nexus-upload-accept-tos").prop("checked", false);
	
	$("#nexus-modal-upload").modal("show");
});
$("#nexus-upload-form").submit(async function(event) {
	if(isThereAnyErrorInForm(event)) return;
	const dataToUpload = {
		buildingId: $("#nexus-modal-upload").data("buildingId"),
		label: $("#nexus-upload-label").val(),
		description: $("#nexus-upload-description").val(),
	}
	const result = await $.post(`https://${resName}/nexus/uploadData`, JSON.stringify(dataToUpload));
	if(result == true) {
		swal("Success", getLocalizedText("menu:nexus:upload_success"), "success");
		resetNexus();
	} else {
		swal("Error", result, "error");
	}
	$("#nexus-modal-upload").modal("hide");
});
async function getInstancesDoorsDistance(instances) {
	return await $.post(`https://${resName}/nexus/getInstancesDoorsDistance`, JSON.stringify({instances}));
}
$("#enter-in-nexus-btn").click(async function() {
	$("#nexus-login").find(".spinner-border").show();
	$("#enter-in-nexus-label").text("...");
	const sharedData = await $.get(`https://${resName}/nexus/getSharedData`);
	if(!sharedData) {
		swal("Error", getLocalizedText("menu:nexus:not_available"), "error");
		resetNexus();
		return;
	} 
	nexusDataTable.clear()
	
	const distances = await getInstancesDoorsDistance(sharedData);
	Object.values(sharedData).forEach(instance => {
		const roundedAverageRating = instance?.votes?.averageRating ? Math.round(instance.votes.averageRating) : 0;
		const ratingStars = instance?.votes?.total ? "⭐".repeat(roundedAverageRating) : getLocalizedText("menu:nexus:not_rated");
		const limitedDescription = instance.description?.length > 30 ? instance.description.substring(0, 30) + "..." : instance.description;
		const doorsCount = instance.content.doors.length;
		const distance = distances[instance.id];
	
		const rawRow = nexusDataTable.row.add( [instance.label, limitedDescription, distance, doorsCount, ratingStars, instance.votes?.total || 0, instance.author] );
		const rowDiv = $(rawRow.node());
		$(rowDiv).data("instance", instance);
	})
	nexusDataTable.draw();
	$("#nexus-login").hide();
	$("#nexus-container").show();
})
function resetNexus() {
	$("#nexus-login").show();
	$("#nexus-login").find(".spinner-border").hide();
	$("#enter-in-nexus-label").text("Enter in Nexus");
	$("#nexus-container").hide();
}
// Messages received by client
window.addEventListener('message', (event) => {
	let data = event.data;
	let action = data.action;
    switch (action) {
		case 'openMenu':
			openMenu(data.version, data.fullConfig);
			break;
		case 'notification':
			showNotification(data.message, data.duration);
			break;
		case 'getInput':
			$("#input-div").show();
			$("#code-input").focus().val("");
			break;
		case 'hideInput':
			$("#input-div").hide();
			break;
		case "sound":
			const sound = document.createElement("audio");
			sound.src = `../audio/${data.soundId}`;
			sound.volume = data.calculatedVolume;
			sound.play();
			break;
	}	
})
// Closes menu when clicking ESC
$(document).on('keyup', function(e) {
	if (e.key != "Escape") return;
	closeMenu();
});