/*  DS2 core (c) 2024 Alexander McIlwraith 
	Released under Creative Commons Attribution-ShareAlike 4.0 International
 */

// create a pure JS mouse click event
const click = new MouseEvent('click', {
	view: window,
	bubbles: false,
	cancelable: true
});

const waitForElement = (selector) => {
    return new Promise(resolve => {
        if (document.querySelector(selector)) {
            return resolve(document.querySelector(selector));
        }

        const observer = new MutationObserver(mutations => {
            if (document.querySelector(selector)) {
                observer.disconnect();
                resolve(document.querySelector(selector));
            }
        });

        // If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
}

const chooseTab = (tab) => {
	const siblings = Array.from(tab.parentNode.children);
	siblings.forEach(sibling => sibling.classList.remove("selected"));
	tab.classList.add("selected");
	
	const tabPanels = Array.from(tab.parentNode.parentNode.children)
	tabPanels.forEach(panel => panel.classList.remove("open"));

	const tabPanelId = tab.getAttribute("id").replace("tab", "tab-panel");
	document.getElementById(tabPanelId).classList.add("open");
}

let pushState = 0;
let tabsetCount = 0;
module.exports = {
	"init": (container = document, spacer = true, args = {}) => { 
		container.querySelectorAll(".tab-group, tabset").forEach(tabGroup => {
			if (tabGroup.querySelector("[role=tablist]") === null) {
				if (tabGroup.getAttribute("id") == null) {
					tabGroup.setAttribute("id", "tab-group-" + tabsetCount);
					tabsetCount++;
				}

				const tabgroup = tabGroup.getAttribute("id");
				let tablist = "";

				Array.from(tabGroup.children).forEach(child => {

					// is details? 
					let dtls = child.nodeName == "DETAILS" ? true : false;

					// get the tab text 
					let tab = dtls ? child.querySelector("summary").innerHTML : child.getAttribute("tab") || child.getAttribute("data-tab");

					// if the tab text is not blank 
					if (tab !== null) {
						const tabID = tab.replace(/\W+/g, "-").toLowerCase();
						

						// define the tab panel content
						let tabPanel = null;
						if (dtls) { 
							tabPanel = child;
							tabPanel.setAttribute("open", "");
						} else {
							tabPanel = document.createElement('div');
							tabPanel.appendChild(child.cloneNode(true));
						}

						tabPanel.id = `tab-panel-${tabgroup}-${tabID}`;
						tabPanel.className = tablist === "" ? "open" : "";
						tabPanel.setAttribute("role", "tabpanel");
						tabPanel.setAttribute("tabindex", "0");
						tabPanel.setAttribute("aria-labelledby", `tab-${tabgroup}-${tabID}`);
						child.parentNode.replaceChild(tabPanel, child);
						let cls = tablist === "" ? "class='selected'" : "";
						tablist += `<li tabindex="0" role="tab" ${cls} id="tab-${tabgroup}-${tabID}"><span>${tab}</span></li>`;
					} else {
						child.classList.add("tab-hidden");
					}
				});

				const ul = document.createElement('ul');
				ul.setAttribute("role", "tablist");
				ul.innerHTML = spacer != true ? `${tablist}` : `${tablist}<li role="separator" class="separator"></li>`;
				tabGroup.insertBefore(ul, tabGroup.firstChild);

				tabGroup.querySelectorAll('[role="tab"]').forEach(tab => {
					tab.addEventListener("click", (evt) => {
						if (pushState == 0) {
							window.history.pushState({rand: Math.random(), pushState: pushState, tab: tab.parentNode.firstChild.getAttribute("id")}, "", `#${tab.parentNode.firstChild.getAttribute("id")}`);
							pushState++;
						}

						chooseTab(evt.currentTarget);
						window.history.pushState({rand: Math.random(), pushState: pushState, tab: tab.getAttribute("id")}, "", `#${tab.getAttribute("id")}`);
						pushState++;
					});

					tab.addEventListener("keypress", (e) => {
						e.preventDefault();
						if( e.which == 32 || e.which == 13 ) {
							e.currentTarget.dispatchEvent(click);
						}
					})
				});
			}

			if (document.location.hash != "" && document.location.hash.substring(0,5) == "#tab-") {
				waitForElement(document.location.hash).then((el) => {
					el.scrollIntoView();
					el.focus();
					el.dispatchEvent(click);
				});
			}
		});

		window.addEventListener("popstate", function (e) {
			e.preventDefault();
			if (e.state != null) {
				chooseTab(document.querySelector(`#${e.state.tab}`));
			} else {
				history.go(-1);
			}
		});

	}
}

