/**
 * @module modules/sort-sk
 * @description <h2><code>sort-sk</code></h2>
 *
 * Allows sorting the members of the indicated element by the values of the
 * data attributes.
 *
 * This element does *not* support the elements to sort changing. It assumes the data in
 * the table is constant (otherwise, lit-html will not be able to render it accurately).
 *
 * Add children to <sort-sk> that generate click events and that have child
 * content, such as buttons. Add a data-key * attribute to each child element
 * that indicates which data-* attribute the children should be sorted on.
 *
 * Note that all sorting is done numerically, unless the
 * 'data-sort-type=alpha' attribute is set on the element generating the
 * click, in which case the sorting is done alphabetically.
 *
 * Additionally a single child element can have a data-default attribute with
 * a value of 'up' or 'down' to indicate the default sorting that already
 * exists in the data.
 *
 *
 * @example An example usage, that will present two buttons to sort the contents of
 *   div#stuffToBeSorted.
 *
 *    <sort-sk target=stuffToBeSorted>
 *      <button data-key=clustersize data-default=down>Cluster Size </button>
 *      <button data-key=stepsize data-sort-type=alpha>Name</button>
 *    </sort-sk>
 *
 *    <div id=stuffToBeSorted>
 *      <div data-clustersize=10 data-name=foo></div>
 *      <div data-clustersize=50 data-name=bar></div>
 *      ...
 *    </div>
 *
 * @attr target - The id of the container element whose children are to be sorted.
 *
 */
import { define } from 'elements-sk/define';
import { $, $$ } from 'common-sk/modules/dom';
import { ElementSk } from '../ElementSk';
import 'elements-sk/icon/arrow-drop-down-icon-sk';
import 'elements-sk/icon/arrow-drop-up-icon-sk';

export type SortDirection = 'down' | 'up';

// The states to move each button through on a click.
const toggle = (value: string): SortDirection => (value === 'down' ? 'up' : 'down');

interface SortableEntry {
  value: string;
  valueAsNumber: number;
  node: HTMLElement;
}

// Functions to pass to sort().
const f_alpha_up = (x: SortableEntry, y: SortableEntry) => x.value.localeCompare(y.value);
const f_alpha_down = (x: SortableEntry, y: SortableEntry) => f_alpha_up(y, x);
const f_num_up = (x: SortableEntry, y: SortableEntry) => {
  if (x.valueAsNumber === y.valueAsNumber) {
    return 0;
  } if (x.valueAsNumber > y.valueAsNumber) {
    return 1;
  }
  return -1;
};
const f_num_down = (x: SortableEntry, y: SortableEntry) => f_num_up(y, x);

export class SortSk extends ElementSk {
  connectedCallback() {
    super.connectedCallback();
    $('[data-key]', this).forEach((ele) => {
      // Only attach the icons once.
      if (ele.querySelector('arrow-drop-down-icon-sk')) {
        return;
      }
      ele.appendChild(document.createElement('arrow-drop-down-icon-sk'));
      ele.appendChild(document.createElement('arrow-drop-up-icon-sk'));
      ele.addEventListener('click', (e) => this._clickHandler(e));
    });

    // Handle a default value if one has been set.
    const def = $$<HTMLElement>('[data-default]', this);
    if (def) {
      this._setSortClass(def, def.dataset.default! as SortDirection);
    }
  }

  _setSortClass(ele: Element, value: SortDirection) {
    ele.setAttribute('data-sort-sk', value);
  }

  _clearSortClass(ele: Element) {
    ele.removeAttribute('data-sort-sk');
  }

  _getSortClass(ele: Element) {
    return ele.getAttribute('data-sort-sk') || '';
  }

  _clickHandler(e: Event) {
    let ele = e.target! as HTMLElement;
    // The click might have been on something inside the button (e.g. on the arrow-drop-up-icon-sk),
    // so we want to bubble up to where the key is and set the class that displays the appropriate
    // arrow.
    while (!ele.hasAttribute('data-key') && ele.parentElement !== this) {
      if (ele.parentElement === null) {
        break;
      }
      ele = ele.parentElement;
    }

    const dir = toggle(this._getSortClass(ele));

    $('[data-key]', this).forEach((e) => {
      this._clearSortClass(e);
    });
    this._setSortClass(ele, dir);

    // Are we sorting alphabetically or numerically.
    const alpha = ele.dataset.sortType === 'alpha';

    // Sort the children of the element at #target.
    const sortBy = ele.dataset.key || '(key not found)';
    this.sort(sortBy, dir, alpha);
  }

  /** Re-sort the data by the given key in the given direction. If alpha is true, it will
   * sort the data as if it were a string (using localeCompare).
   */
  sort(key: string, dir: SortDirection, alpha: boolean) {
    // Remember the direction we are sorting in.
    const up = dir === 'up';

    const container = this.parentElement!.querySelector(
      `#${this.getAttribute('target')}`,
    );
    if (container === null) {
      throw 'Failed to find "target" attribute.';
    }
    const arr: SortableEntry[] = [];
    for (const ele of Array.from(container.children)) {
      const htmlEle = ele as HTMLElement;
      const value: string = htmlEle.dataset[key] || '';
      const entry = {
        value: value,
        valueAsNumber: +value,
        node: htmlEle,
      };
      arr.push(entry);
    }

    // Pick the desired sort function.
    let f = f_alpha_up;
    if (alpha) {
      f = up ? f_alpha_up : f_alpha_down;
    } else {
      f = up ? f_num_up : f_num_down;
    }
    arr.sort(f);

    // Rearrange the elements in the sorted order.
    arr.forEach((e) => {
      // Reminder: appendChild will *move* existing nodes, which is what we want here while
      // reordering things.
      container!.appendChild(e.node);
    });
  }
}

define('sort-sk', SortSk);
