var current_hash = "";
var server_address = "";

window.onload = () => {
	get_updated_server_address();
	fetch(`${document.URL}static/tracker/data/holy_cross_codes.json`)
		.then((response) => response.json())
		.then(
			(data) => {
				const cross_codes = JSON.parse(JSON.stringify(data));
				const refresh_interval = setInterval(
					refresh_elements,
					500,
					cross_codes
				);
			},
			(error) => {
				console.log(error);
			}
		);
};

async function get_updated_filepath() {
	fetch(`${document.URL}get/settings`)
		.then((response) => response.json())
		.then(
			(data) => {
				backend_filepath = JSON.parse(JSON.stringify(data));
				fetch(`${server_address}settings`, {
					method: "post",
					headers: { "Content-type": "application/json" },
					body: JSON.stringify({
						secretLegend: backend_filepath,
						address: ":8000",
					}),
				});
			},
			(error) => {
				console.log(error);
			}
		);
}

// This won't work properly. For now, the user will need to input themselves.
// async function get_filepath() {
// 	try {
// 		const filepath_selection = await window.showDirectoryPicker();
// 		console.log(filepath_selection);
// 	} catch {
// 		console.log("Browser does not support showDirectoryPicker()");
// 	}
// }

async function get_updated_server_address() {
	fetch(`${document.URL}get/address`)
		.then(
			(response) => response.json(),
			(error) => {
				console.log("Are you sure the front end is up?");
			}
		)
		.then(
			(data) => {
				parsed_data = JSON.parse(JSON.stringify(data));
				server_address = parsed_data["listen_address"];
				if (parsed_data["backend_filepath_updated"]) {
					get_updated_filepath();
				}
			},
			(error) => {
				console.log(error);
			}
		);
}

async function refresh_elements(cross_codes) {
	fetch(`${server_address}spoiler`)
		.then((response) => response.json())
		.then(
			(data) => {
				// Attempt to receive response JSON.
				const response_object = JSON.parse(JSON.stringify(data));
				document.getElementById("status-block").classList.add("hidden");
				if (response_object.Debug.Hash == current_hash) {
					return;
				} else {
					current_hash = response_object.Debug.Hash;
					get_updated_server_address();
				}

				// Parse out data from the back-end into variables.
				const overview_checks_undiscovered =
					response_object.Totals.Checks.Undiscovered;
				const overview_checks_total = response_object.Totals.Checks.Total;
				const overview_entrances_undiscovered =
					response_object.Totals.Entrances.Undiscovered;
				const overview_entrances_total = response_object.Totals.Entrances.Total;
				const current_scene_name = response_object.Current.Scene;
				const all_scenes = response_object.Scenes;
				const debug_info = response_object.Debug;
				const cross_codes_entered = response_object.Codes;
				const default_cross_codes = cross_codes.Default;
				const global_cross_codes = cross_codes.Global;

				// Refresh elements with new data from the back end.

				//  Clone all the needed elements for updating.
				let overview_checks_title = document
					.getElementById("overview")
					.querySelector(".overview-checks");
				let overview_entrances_title = document
					.getElementById("overview")
					.querySelector(".overview-entrances");
				let summary_block = document
					.getElementById("overview")
					.querySelector(".summary-list")
					.firstElementChild.firstElementChild.cloneNode(true);
				let breakdown_block = document
					.getElementById("overview")
					.querySelector(".breakdown-list")
					.firstElementChild.cloneNode(true);
				let cross_codes_block = document
					.getElementById("overview")
					.querySelector(".breakdown-list")
					.firstElementChild.querySelector(".codes-block")
					.cloneNode(true);
				breakdown_block.classList.remove("hidden");
				let debug_item = document
					.getElementById("debug-block")
					.firstElementChild.cloneNode(true);
				debug_item.classList.remove("hidden");
				let new_breakdown_list = document
					.getElementById("overview")
					.querySelector(".breakdown-list")
					.cloneNode(true);
				let new_summary_list = document
					.getElementById("overview")
					.querySelector(".summary-list")
					.cloneNode(true);
				let new_debug_block = document
					.getElementById("debug-block")
					.cloneNode(true);

				// Clear out the current lists.
				new_breakdown_list.innerHTML = "";
				new_summary_list.firstElementChild.innerHTML = "";
				new_debug_block.innerHTML = "";

				// Set content to updated data.
				overview_checks_title.textContent = `Checks: ${overview_checks_undiscovered}/${overview_checks_total}`;
				overview_entrances_title.textContent = `Entrances: ${overview_entrances_undiscovered}/${overview_entrances_total}`;

				// Create new lists with updated data.
				Object.keys(all_scenes).forEach((scene) => {
					// Create variables for element pointers.
					summary_block = document
						.getElementById("overview")
						.querySelector(".summary-list")
						.firstElementChild.firstElementChild.cloneNode(true);
					summary_block.classList.remove("hidden");
					let summary_title = summary_block.querySelector(".summary-title");
					let summary_checks = summary_block.querySelector(".summary-checks");
					let summary_entrances =
						summary_block.querySelector(".summary-entrances");

					breakdown_block = document
						.getElementById("overview")
						.querySelector(".breakdown-list")
						.firstElementChild.cloneNode(true);
					breakdown_block.classList.remove("hidden");
					let breakdown_block_title = breakdown_block.querySelector(
						".breakdown-block-title"
					);
					let breakdown_block_checks_title = breakdown_block.querySelector(
						".breakdown-block-checks-title"
					);
					let new_breakdown_block_checks_list = breakdown_block
						.querySelector(".breakdown-block-checks-list")
						.cloneNode(true);
					let breakdown_block_checks_list_item = breakdown_block
						.querySelector(".breakdown-block-checks-list")
						.firstElementChild.cloneNode(true);
					breakdown_block_checks_list_item.classList.remove("hidden");
					let breakdown_block_entrances_title = breakdown_block.querySelector(
						".breakdown-block-entrances-title"
					);
					let new_breakdown_block_entrances_list = breakdown_block
						.querySelector(".breakdown-block-entrances-list")
						.cloneNode(true);
					let breakdown_block_entrances_list_item = breakdown_block
						.querySelector(".breakdown-block-entrances-list")
						.firstElementChild.cloneNode(true);
					breakdown_block_entrances_list_item.classList.remove("hidden");
					let new_breakdown_block_mapped_list = breakdown_block
						.querySelector(".breakdown-block-mapped-list")
						.cloneNode(true);
					let breakdown_block_mapped_list_item = breakdown_block
						.querySelector(".breakdown-block-mapped-list")
						.firstElementChild.cloneNode(true);
					breakdown_block_mapped_list_item.classList.remove("hidden");

					cross_codes_block = document
						.getElementById("overview")
						.querySelector(".breakdown-list")
						.firstElementChild.querySelector(".codes-block")
						.cloneNode(true);
					let new_cross_codes_block_list = cross_codes_block
						.querySelector(".codes-list")
						.cloneNode(true);
					let cross_codes_block_list_item = cross_codes_block
						.querySelector(".codes-list")
						.firstElementChild.cloneNode(true);

					// Clear out current list content.
					new_breakdown_block_checks_list.innerHTML = "";
					new_breakdown_block_entrances_list.innerHTML = "";
					new_breakdown_block_mapped_list.innerHTML = "";
					new_cross_codes_block_list.innerHTML = "";
					new_breakdown_block_checks_list.appendChild(
						breakdown_block_checks_list_item.cloneNode(true)
					);
					new_breakdown_block_entrances_list.appendChild(
						breakdown_block_entrances_list_item.cloneNode(true)
					);
					new_breakdown_block_mapped_list.appendChild(
						breakdown_block_mapped_list_item.cloneNode(true)
					);

					// Create variables for commonly used values.
					let scene_checks_undiscovered =
						all_scenes[scene].Totals.Checks.Undiscovered;
					let scene_checks_total = all_scenes[scene].Totals.Checks.Total;
					let scene_entrances_undiscovered =
						all_scenes[scene].Totals.Entrances.Undiscovered;
					let scene_entrances_total = all_scenes[scene].Totals.Entrances.Total;
					let scene_has_codes = Object.keys(cross_codes).includes(scene);

					// Set textContent.
					summary_title.textContent = scene;
					summary_checks.textContent = `Checks: ${scene_checks_undiscovered}/${scene_checks_total}`;
					summary_entrances.textContent = `Entrances: ${scene_entrances_undiscovered}/${scene_entrances_total}`;
					breakdown_block_title.textContent = scene;
					breakdown_block_checks_title.textContent = `Checks: ${all_scenes[scene].Totals.Checks.Undiscovered}/${all_scenes[scene].Totals.Checks.Total}`;
					breakdown_block_entrances_title.textContent = `Entrances: ${all_scenes[scene].Totals.Entrances.Undiscovered}/${all_scenes[scene].Totals.Entrances.Total}`;

					// Create checks, entrances, mapped entrances, and cross code lists.
					Object.keys(all_scenes[scene].Checks).forEach((check) => {
						if (!all_scenes[scene].Checks[check]) {
							breakdown_block_checks_list_item.textContent = `❌ ${check}`;
							new_breakdown_block_checks_list.appendChild(
								breakdown_block_checks_list_item.cloneNode(true)
							);
						}
					});
					Object.keys(all_scenes[scene].Entrances).forEach((entrances) => {
						if (all_scenes[scene].Entrances[entrances] == "") {
							breakdown_block_entrances_list_item.textContent = `❌ ${entrances}`;
							new_breakdown_block_entrances_list.appendChild(
								breakdown_block_entrances_list_item.cloneNode(true)
							);
						} else {
							breakdown_block_mapped_list_item.textContent = `✔️ ${entrances} -> ${all_scenes[scene].Entrances[entrances]}`;
							new_breakdown_block_mapped_list.appendChild(
								breakdown_block_mapped_list_item.cloneNode(true)
							);
						}
					});
					Object.keys(default_cross_codes).forEach((code) => {
						cross_codes_block_list_item.querySelector(
							".codes-list-item-title"
						).textContent = code;
						cross_codes_block_list_item.querySelector(
							".codes-list-item-code"
						).textContent = default_cross_codes[code]
							.replace(/U/g, "⬆️")
							.replace(/R/g, "➡️")
							.replace(/D/g, "⬇️")
							.replace(/L/g, "⬅️");
						new_cross_codes_block_list.appendChild(
							cross_codes_block_list_item.cloneNode(true)
						);
					});
					Object.keys(global_cross_codes).forEach((code) => {
						cross_codes_block_list_item.querySelector(
							".codes-list-item-title"
						).textContent = code;
						cross_codes_block_list_item.querySelector(
							".codes-list-item-code"
						).textContent = global_cross_codes[code]
							.replace(/U/g, "⬆️")
							.replace(/R/g, "➡️")
							.replace(/D/g, "⬇️")
							.replace(/L/g, "⬅️");
						if (cross_codes_entered.Global[code]) {
							cross_codes_block_list_item.classList.add("hidden");
						} else {
							cross_codes_block_list_item.classList.remove("hidden");
						}
						new_cross_codes_block_list.appendChild(
							cross_codes_block_list_item.cloneNode(true)
						);
					});
					if (scene_has_codes) {
						Object.keys(cross_codes[scene]).forEach((code) => {
							cross_codes_block_list_item.querySelector(
								".codes-list-item-title"
							).textContent = code;
							cross_codes_block_list_item.querySelector(
								".codes-list-item-code"
							).textContent = cross_codes[scene][code]
								.replace(/U/g, "⬆️")
								.replace(/R/g, "➡️")
								.replace(/D/g, "⬇️")
								.replace(/L/g, "⬅️");
							if (cross_codes_entered[scene][code]) {
								cross_codes_block_list_item.classList.add("hidden");
							} else {
								cross_codes_block_list_item.classList.remove("hidden");
							}
							new_cross_codes_block_list.appendChild(
								cross_codes_block_list_item.cloneNode(true)
							);
						});
					}

					// Apply color coding to summary block
					summary_block.classList.remove(
						"bg-green-900",
						"bg-yellow-900",
						"bg-blue-900",
						"bg-red-900"
					);
					if (
						scene_checks_undiscovered > 0 &&
						scene_entrances_undiscovered > 0
					) {
						if (scene_entrances_undiscovered == scene_entrances_total) {
							summary_block.classList.add("bg-red-900");
						} else {
							summary_block.classList.add("bg-green-900");
						}
					} else if (scene_checks_undiscovered > 0) {
						summary_block.classList.add("bg-yellow-900");
					} else if (scene_entrances_undiscovered > 0) {
						summary_block.classList.add("bg-blue-900");
					}

					// Replace lists
					breakdown_block
						.querySelector(".breakdown-block-checks-list")
						.replaceWith(new_breakdown_block_checks_list);
					breakdown_block
						.querySelector(".breakdown-block-entrances-list")
						.replaceWith(new_breakdown_block_entrances_list);
					breakdown_block
						.querySelector(".breakdown-block-mapped-list")
						.replaceWith(new_breakdown_block_mapped_list);
					breakdown_block
						.querySelector(".codes-list")
						.replaceWith(new_cross_codes_block_list);

					// Append relevant elements to lists.
					if (scene == current_scene_name) {
						summary_block.classList.add("hidden");
						breakdown_block
							.querySelector(".codes-block")
							.classList.remove("hidden");
						document
							.getElementById("breakdown-current")
							.firstElementChild.replaceWith(breakdown_block.cloneNode(true));
						breakdown_block.classList.add("hidden");
					} else if (
						scene_checks_undiscovered <= 0 &&
						scene_entrances_undiscovered <= 0
					) {
						summary_block.classList.add("hidden");
						// breakdown_block.classList.add("hidden");
					}
					new_summary_list.firstElementChild.appendChild(
						summary_block.cloneNode(true)
					);
					new_breakdown_list.appendChild(breakdown_block.cloneNode(true));
				});
				Object.keys(debug_info).forEach((item) => {
					debug_item.textContent = `${item}: ${debug_info[item]}`;
					new_debug_block.appendChild(debug_item.cloneNode(true));
				});

				// Replace with new data.
				document
					.getElementById("overview")
					.querySelector(".summary-list")
					.replaceWith(new_summary_list.cloneNode(true));
				document
					.getElementById("overview")
					.querySelector(".breakdown-list")
					.replaceWith(new_breakdown_list.cloneNode(true));
				document
					.getElementById("debug-block")
					.replaceWith(new_debug_block.cloneNode(true));
			},
			(error) => {
				document.getElementById("status-block").classList.remove("hidden");
				get_updated_server_address();
				return error;
			}
		);
}

// Outdated funcion to log the data gathered from the backend.
function log_elements() {
	console.log(overview.checks.textContent);
	console.log(overview.entrances.textContent);
	console.log(current_scene.name.textContent);
	console.log(current_scene.checks.title.textContent);
	for (i in current_scene.checks.list.children) {
		if (current_scene.checks.list.children[i].textContent) {
			console.log(current_scene.checks.list.children[i].textContent);
		}
	}
	console.log(current_scene.entrances.title.textContent);
	for (i in current_scene.entrances.list.children) {
		if (current_scene.entrances.list.children[i].textContent) {
			console.log(current_scene.entrances.list.children[i].textContent);
		}
	}
	for (i in current_scene.entrances.mapped.children) {
		if (current_scene.entrances.mapped.children[i].textContent) {
			console.log(current_scene.entrances.mapped.children[i].textContent);
		}
	}
}
