(() => {
	const selectEl = document.getElementById("summary-ref-select");
	const commitLinkEl = document.getElementById("summary-ref-commit-link");
	const browseLinkEl = document.getElementById("summary-ref-browse-link");
	const logLinkEl = document.getElementById("summary-ref-log-link");
	const shortlogLinkEl = document.getElementById("summary-ref-shortlog-link");
	const treeContainerEl = document.getElementById("summary-tree-container");
	const treeBrowseLinkEl = document.getElementById("summary-tree-browse-link");
	const readmeContainerEl = document.getElementById("summary-readme-container");
	if (!selectEl || !commitLinkEl || !browseLinkEl || !readmeContainerEl) {
		return;
	}

	const project = readmeContainerEl.dataset.project;
	if (!project) {
		return;
	}

	const projectApiBase = () =>
		"/project/" + project.split("/").map((segment) => encodeURIComponent(segment)).join("/");

	const SUBSCRIBE_BACKOFF_MS = 5000;

	const rerunScripts = () => {
		for (const oldScript of readmeContainerEl.querySelectorAll("script")) {
			const scriptEl = document.createElement("script");
			if (oldScript.src) {
				scriptEl.src = oldScript.src;
			} else if (oldScript.textContent) {
				scriptEl.textContent = oldScript.textContent;
			}
			oldScript.replaceWith(scriptEl);
		}
	};

	const loadState = async (ref) => {
		const response = await fetch(
			`${projectApiBase()}/summary-ref-state?ref=${encodeURIComponent(ref)}`,
		);
		if (!response.ok) {
			return;
		}
		const state = await response.json();
		commitLinkEl.href = state.commit_href;
		commitLinkEl.textContent = state.display;
		browseLinkEl.href = state.browse_href;
		if (logLinkEl) {
			logLinkEl.href = state.log_href;
		}
		if (shortlogLinkEl) {
			shortlogLinkEl.href = state.shortlog_href;
		}
		if (treeContainerEl) {
			treeContainerEl.innerHTML = state.tree_html || "";
		}
		if (treeBrowseLinkEl) {
			treeBrowseLinkEl.href = state.browse_href;
		}
		readmeContainerEl.innerHTML = state.readme_html || "";
		if (state.readme_html) {
			rerunScripts();
		}
	};

	const populateOptions = (options) => {
		const previousValue = selectEl.value;
		for (const opt of Array.from(selectEl.options)) {
			if (opt.value !== "HEAD") {
				opt.remove();
			}
		}
		for (const optionData of options || []) {
			const optionEl = document.createElement("option");
			optionEl.value = optionData.value;
			optionEl.textContent = `${optionData.kind}: ${optionData.label}`;
			selectEl.appendChild(optionEl);
		}
		const stillPresent = Array.from(selectEl.options).some((opt) => opt.value === previousValue);
		selectEl.value = stillPresent ? previousValue : "HEAD";
		return selectEl.value;
	};

	const loadOptions = async () => {
		const response = await fetch(`${projectApiBase()}/summary-refs`);
		if (!response.ok) {
			return null;
		}
		const data = await response.json();
		return populateOptions(data.options);
	};

	selectEl.addEventListener("change", () => {
		void loadState(selectEl.value);
	});

	const subscriptionController = new AbortController();
	window.addEventListener("beforeunload", () => subscriptionController.abort());

	const subscribeToUpdates = async () => {
		while (!subscriptionController.signal.aborted) {
			let resp;
			try {
				resp = await fetch(`${projectApiBase()}?a=heads&updates=true`, {
					signal: subscriptionController.signal,
				});
			} catch (err) {
				if (subscriptionController.signal.aborted) {
					return;
				}
				await new Promise((resolve) => setTimeout(resolve, SUBSCRIBE_BACKOFF_MS));
				continue;
			}
			if (subscriptionController.signal.aborted) {
				return;
			}
			if (resp.status === 200) {
				const text = await resp.text();
				if (text.length > 0) {
					const effectiveRef = await loadOptions();
					await loadState(effectiveRef ?? selectEl.value);
				}
			} else if (resp.status !== 304) {
				await new Promise((resolve) => setTimeout(resolve, SUBSCRIBE_BACKOFF_MS));
			}
		}
	};

	void loadOptions();
	void subscribeToUpdates();
})();