(function module() {
// A list of all sections.
let sectionList;

// The main content area.
let contentArea;

// The language currently in use.
let currentLanguage = 'german';

// A hash of all elements explicitly marked as belonging to a language,
// e.g., by adding the class `wiai-german`.
const languageElements = {};

// All elements that contain multiple languages inline, 
// separated by ' | '.
const multiLanguageElements = [];

// The links that allow to change the language.
const languageChooserOptions = [];

const LANGUAGES = ['german', 'english'];
const LANGUAGE_NAMES = {'german': 'Deutsch', 'english': 'English'};
const LANGUAGE_PREFIXES = {'img[alt="German"]': 'german', 'img[alt="English"]': 'english'};
const URL = 'https://wiai.stuve-bamberg.de/vc-customization/';

const MULTI_LANGUAGE_CANDIDATE_QUERY = 'h1, h2, h3, h4, h5, span.instancename';
const STORAGE_LANGUAGE_PREFERENCE_KEY = 'wiai-language-preference';

window.addEventListener('load', init);
addStylesheetTag();

function init() {
	initializeElements();
	categorizeElementsByPrefix();
	initializeMultiLanguageElements();
  addLanguageChooser();
  readUserPreferences();
  updateMultiLanguageElements();
  updateLanguageOptions();
}

/**
 * Add a link to the bilingual.css stylesheet.
 */
function addStylesheetTag() {
	let tag = document.createElement('link');
	tag.rel = 'stylesheet';
	tag.href = URL + 'bilingual.css';
	document.head.appendChild(tag);
}

/**
 * Fill the `languageElements` hash with lists of objects that have explicit language classes (e.g., `wiai-german`),
 * as well as the `sectionList` array of all main sections and the `contentArea` element.
 */
function initializeElements() {
	LANGUAGES.forEach(function (language) {
		languageElements[language] = Array.from(document.querySelectorAll(`.${getClassNameForLanguage(language)}`));
	});
	sectionList = Array.from(document.querySelectorAll('.topics .section.main'));
	contentArea = document.querySelector('.course-content');
}

/**
 * Add the language chooser element to the top of the `contentArea`.
 */
function addLanguageChooser() {
	let languageChooser = document.createElement('div');
	languageChooser.classList.add('wiai-language-chooser');
	
	LANGUAGES.forEach(function (language) {
		let languageLink = document.createElement('a');
		languageLink.href = '#';
		languageLink.classList.add('wiai-language-option');
		languageLink.setAttribute('data-wiai-language', language);
		languageLink.textContent = LANGUAGE_NAMES[language];

		languageLink.addEventListener('click', function (event) {
      event.preventDefault();
      switchLanguage(currentLanguage, language);
      updateLanguageOptions();
    });

    if (language === currentLanguage) {
      languageLink.classList.add('active');
    }

		languageChooser.appendChild(languageLink);
    languageChooserOptions.push(languageLink);
	});

	contentArea.prepend(languageChooser);
}

/**
 * Marks the language option for the `currentLanguage` as `.active`.
 */
function updateLanguageOptions() {
  languageChooserOptions.forEach(function (element) { 
    if (element.getAttribute('data-wiai-language') === currentLanguage) {
      element.classList.add('active');
    } else {
      element.classList.remove('active'); 
    }
  });
}

/**
 * Update the language class on the document body (`wiai-language-XYZ`) 
 * and update all elements in `multiLanguageElements`.
 * The `currentLanguage` is updated in the process.
 */
function switchLanguage(oldLanguage, newLanguage) {
	document.body.classList.remove(`wiai-language-${oldLanguage}`);
	document.body.classList.add(`wiai-language-${newLanguage}`);
  currentLanguage = newLanguage;
  writeUserPreferences();
  updateMultiLanguageElements();
}

/**
 * Update all `multiLanguageElements` to fit the new language.
 **/
function updateMultiLanguageElements() {
  multiLanguageElements.forEach(function (element) {
    element.textContent = element.getAttribute(`data-wiai-title-${currentLanguage}`);
  });
}

/**
 * Add the correct language class to elements starting with one of the 
 * `LANGUAGE_PREFIXES`. The prefix is removed from the element itself.
 */
function categorizeElementsByPrefix() {
	Object.keys(LANGUAGE_PREFIXES).forEach(function (languagePrefix) {
		const language = LANGUAGE_PREFIXES[languagePrefix];
		const prefixElements = document.querySelectorAll(languagePrefix);
		prefixElements.forEach(function (prefixElement) {
			const parent = prefixElement.parentElement;
			parent.removeChild(prefixElement);
			parent.classList.add(getClassNameForLanguage(language));	
		});
	});
}

/**
 * Find and process all elements containing multiple languages inline.
 */
function initializeMultiLanguageElements() {
  const candidates = Array.from(contentArea.querySelectorAll(MULTI_LANGUAGE_CANDIDATE_QUERY));
  candidates.forEach(initializeMultiLanguageElement);
}

/**
 * Split the title of each `multiLanguageElement` and store the individual values
 * in data attributes (`data-wiai-title-<language>`). The text content is then set
 * to match the `currentLanguage`.
 */
function initializeMultiLanguageElement(element) {
  const title = element.textContent;

  if (title.includes(' | ')) {
    const titleFragments = title.split(' | ');
    for (let i = 0; i < titleFragments.length && i < LANGUAGES.length; i++) {
      const language = LANGUAGES[i];
      const localTitle = titleFragments[i];
      element.setAttribute(`data-wiai-title-${language}`, localTitle);
      multiLanguageElements.push(element);
    }

    element.textContent = element.getAttribute(`data-wiai-title-${currentLanguage}`);
  }
}

function getClassNameForLanguage(language) {
	return `wiai-${language}`;
}

/**
 * Read the user's language preference—if any—from LocalStorage and update elements accordingly.
 * In case there is no LocalStorage entry, but the user selected English as its default VC or browser
 * language, the `currentLanguage` is set to English.
 */
function readUserPreferences() {
  const localStorageEntry = localStorage.getItem(STORAGE_LANGUAGE_PREFERENCE_KEY);
  const documentLanguage = document.querySelector('html').getAttribute('lang');
  
  if (localStorageEntry != null) {
    currentLanguage = localStorage.getItem(STORAGE_LANGUAGE_PREFERENCE_KEY);
  } else if (documentLanguage === 'en' || documentLanguage === 'en_us'
    || navigator.language === 'en' || navigator.language.includes('en-')) {
    currentLanguage = 'english';
  }
  document.body.classList.add(`wiai-language-${currentLanguage}`);
}

/**
 * Store the user's language preference in LocalStorage.
 */
function writeUserPreferences() {
  localStorage.setItem(STORAGE_LANGUAGE_PREFERENCE_KEY, currentLanguage);
}
})()
