/* global IITC -- eslint */

/**
 * Namespace for portal highlighters: registering, switching and applying portal highlight styles.
 *
 * @memberof IITC.portal
 * @namespace highlighter
 */

// an object mapping highlighter names to the object containing callback functions
window._highlighters = null;

// the name of the current highlighter
window._current_highlighter = localStorage.portal_highlighter;

window._no_highlighter = 'No Highlights';

/**
 * Adds a new portal highlighter to map. The highlighter is a function that will be called for each portal.
 *
 * @memberof IITC.portal.highlighter
 * @param {string} name - The name of the highlighter.
 * @param {Function} data - The callback function for the highlighter.
 *                          This function receives data about the portal and decides how to highlight it.
 */
const add = function (name, data) {
  if (window._highlighters === null) {
    window._highlighters = {};
  }

  // old-format highlighters just passed a callback function. this is the same as just a highlight method
  if (!data.highlight) {
    data = { highlight: data };
  }

  window._highlighters[name] = data;

  if (window.isApp && window.app.addPortalHighlighter) window.app.addPortalHighlighter(name);

  if (window._current_highlighter === undefined) {
    window._current_highlighter = name;
  }

  if (window._current_highlighter === name) {
    if (window.isApp && window.app.setActiveHighlighter) window.app.setActiveHighlighter(name);

    // call the setSelected callback
    if (window._highlighters[window._current_highlighter].setSelected) {
      window._highlighters[window._current_highlighter].setSelected(true);
    }
  }
  IITC.portal.highlighter.updateControl();
};

/**
 * Updates the portal highlighter dropdown list, recreating the dropdown list of available highlighters.
 *
 * @memberof IITC.portal.highlighter
 */
const updateControl = function () {
  if (window.isApp && window.app.addPortalHighlighter) {
    document.getElementById('portal_highlight_select')?.remove();
    return;
  }

  if (window._highlighters !== null) {
    let select = document.getElementById('portal_highlight_select');
    if (!select) {
      select = document.createElement('select');
      select.id = 'portal_highlight_select';
      select.addEventListener('change', function () {
        IITC.portal.highlighter.change(this.value);
      });
      document.body.append(select);

      const topLeft = document.querySelector('.leaflet-top.leaflet-left');
      if (topLeft) topLeft.style.paddingTop = '20px';
      const scaleLine = document.querySelector('.leaflet-control-scale-line');
      if (scaleLine) scaleLine.style.marginTop = '25px';
    }
    select.innerHTML = '';

    const addOption = (value) => {
      const option = document.createElement('option');
      option.value = value;
      option.textContent = value;
      select.append(option);
    };

    addOption(window._no_highlighter);
    Object.keys(window._highlighters)
      .sort()
      .forEach((name) => addOption(name));

    select.value = window._current_highlighter;
  }
};

/**
 * Changes the current portal highlights based on the selected highlighter.
 *
 * @memberof IITC.portal.highlighter
 * @param {string} name - The name of the highlighter to be applied.
 */
const change = function (name) {
  // first call any previous highlighter select callback
  if (window._current_highlighter && window._highlighters[window._current_highlighter] && window._highlighters[window._current_highlighter].setSelected) {
    window._highlighters[window._current_highlighter].setSelected(false);
  }

  window._current_highlighter = name;
  if (window.isApp && window.app.setActiveHighlighter) window.app.setActiveHighlighter(name);

  // now call the setSelected callback for the new highlighter
  if (window._current_highlighter && window._highlighters[window._current_highlighter] && window._highlighters[window._current_highlighter].setSelected) {
    window._highlighters[window._current_highlighter].setSelected(true);
  }

  IITC.portal.highlighter.resetAll();
  localStorage.portal_highlighter = name;
};

/**
 * Applies the currently active highlighter to a specific portal.
 * This function is typically called for each portal on the map.
 *
 * @memberof IITC.portal.highlighter
 * @param {Object} p - The portal object to be highlighted.
 */
const highlight = function (p) {
  if (window._highlighters !== null && window._highlighters[window._current_highlighter] !== undefined) {
    return window._highlighters[window._current_highlighter].highlight({ portal: p });
  }
};

/**
 * Resets the highlighting of all portals, returning them to their default style.
 *
 * @memberof IITC.portal.highlighter
 */
const resetAll = function () {
  Object.entries(window.portals).forEach(([guid, portal]) => {
    IITC.portal.marker.setStyle(portal, guid === window.selectedPortal);
  });
};

IITC.portal.highlighter = {
  add,
  updateControl,
  change,
  highlight,
  resetAll,
};

// Map of legacy global names to their new names within IITC.portal.highlighter
const legacyHighlighterMappings = {
  addPortalHighlighter: 'add',
  updatePortalHighlighterControl: 'updateControl',
  changePortalHighlights: 'change',
  highlightPortal: 'highlight',
  resetHighlightedPortals: 'resetAll',
};

IITC.registerLegacyAliases(IITC.portal.highlighter, legacyHighlighterMappings);