// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

cr.define('cr.ui', function() {
  /**
   * TODO(beccahughes): Description
   */
  /* #export */ class MediaDataTable {
    /**
     * @param {HTMLElement} table
     * @param {!cr.ui.MediaDataTableDelegate} delegate
     */
    constructor(table, delegate) {
      /** @private {HTMLElement} */
      this.table_ = table;

      /** @private {Array<Object>} */
      this.data_ = [];

      /** @private {cr.ui.MediaDataTableDelegate} */
      this.delegate_ = delegate;

      // Set table header sort handlers.
      const headers = this.table_.querySelectorAll('th[sort-key]');
      headers.forEach(header => {
        header.addEventListener('click', this.handleSortClick_.bind(this));
      });
    }

    handleSortClick_(e) {
      if (e.target.classList.contains('sort-column')) {
        e.target.toggleAttribute('sort-reverse');
      } else {
        document.querySelector('.sort-column').classList.remove('sort-column');
        e.target.classList.add('sort-column');
      }

      this.render();
    }

    render() {
      // Find the body of the table and clear it.
      const body = this.table_.querySelectorAll('tbody')[0];
      body.innerHTML = '';

      // Get the sort key from the columns to determine which data should be in
      // which column.
      const headerCells = Array.from(this.table_.querySelectorAll('thead th'));
      const dataAndSortKeys = headerCells.map((e) => {
        return e.getAttribute('sort-key') ? e.getAttribute('sort-key') :
                                            e.getAttribute('data-key');
      });

      const currentSortCol = this.table_.querySelectorAll('.sort-column')[0];
      const currentSortKey = currentSortCol.getAttribute('sort-key');
      const currentSortReverse = currentSortCol.hasAttribute('sort-reverse');

      // Sort the data based on the current sort key.
      this.data_.sort((a, b) => {
        return (currentSortReverse ? -1 : 1) *
            this.delegate_.compareTableItem(currentSortKey, a, b);
      });

      // Generate the table rows.
      this.data_.forEach((dataRow) => {
        const tr = document.createElement('tr');
        body.appendChild(tr);

        dataAndSortKeys.forEach((key) => {
          const td = document.createElement('td');

          // Keys with a period denote nested objects.
          let data = dataRow;
          const expandedKey = key.split('.');
          expandedKey.forEach((k) => {
            data = data[k];
            key = k;
          });

          this.delegate_.insertDataField(td, data, key, dataRow);
          tr.appendChild(td);
        });
      });
    }

    /**
     * @param {Array} data The data to update
     */
    setData(data) {
      this.data_ = data;
      this.render();
    }
  }

  /** @interface */
  /* #export */ class MediaDataTableDelegate {
    /**
     * Formats a field to be displayed in the data table and inserts it into the
     * element.
     * @param {Element} td
     * @param {?Object} data
     * @param {string} key
     * @param {Object} dataRow This is the row itself in case we need extra
     *   data to render the field.
     */
    insertDataField(td, data, key, dataRow) {}

    /**
     * Compares two objects based on |sortKey|.
     * @param {string} sortKey The name of the property to sort by.
     * @param {?Object} a The first object to compare.
     * @param {?Object} b The second object to compare.
     * @return {number} A negative number if |a| should be ordered
     *     before |b|, a positive number otherwise.
     */
    compareTableItem(sortKey, a, b) {}
  }

  // #cr_define_end
  return {MediaDataTable, MediaDataTableDelegate};
});
