/**
 * @license
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(function() {
  'use strict';

  /**
   * Fired when a comment is saved or deleted
   *
   * @event thread-list-modified
   * @extends Polymer.Element
   */
  class GrThreadList extends Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element)) {
    static get is() { return 'gr-thread-list'; }

    static get properties() {
      return {
      /** @type {?} */
        change: Object,
        threads: Array,
        changeNum: String,
        loggedIn: Boolean,
        _sortedThreads: {
          type: Array,
        },
        _filteredThreads: {
          type: Array,
          computed: '_computeFilteredThreads(_sortedThreads, ' +
            '_unresolvedOnly, _draftsOnly)',
        },
        _unresolvedOnly: {
          type: Boolean,
          value: false,
        },
        _draftsOnly: {
          type: Boolean,
          value: false,
        },
      };
    }

    static get observers() { return ['_computeSortedThreads(threads.*)']; }

    _computeShowDraftToggle(loggedIn) {
      return loggedIn ? 'show' : '';
    }

    /**
     * Order as follows:
     *  - Unresolved threads with drafts (reverse chronological)
     *  - Unresolved threads without drafts (reverse chronological)
     *  - Resolved threads with drafts (reverse chronological)
     *  - Resolved threads without drafts (reverse chronological)
     *
     * @param {!Object} changeRecord
     */
    _computeSortedThreads(changeRecord) {
      const threads = changeRecord.base;
      if (!threads) { return []; }
      this._updateSortedThreads(threads);
    }

    _updateSortedThreads(threads) {
      this._sortedThreads =
          threads.map(this._getThreadWithSortInfo).sort((c1, c2) => {
            const c1Date = c1.__date || util.parseDate(c1.updated);
            const c2Date = c2.__date || util.parseDate(c2.updated);
            const dateCompare = c2Date - c1Date;
            if (c2.unresolved || c1.unresolved) {
              if (!c1.unresolved) { return 1; }
              if (!c2.unresolved) { return -1; }
            }
            if (c2.hasDraft || c1.hasDraft) {
              if (!c1.hasDraft) { return 1; }
              if (!c2.hasDraft) { return -1; }
            }

            if (dateCompare === 0 && (!c1.id || !c1.id.localeCompare)) {
              return 0;
            }
            return dateCompare ? dateCompare : c1.id.localeCompare(c2.id);
          });
    }

    _computeFilteredThreads(sortedThreads, unresolvedOnly, draftsOnly) {
      // Polymer 2: check for undefined
      if ([
        sortedThreads,
        unresolvedOnly,
        draftsOnly,
      ].some(arg => arg === undefined)) {
        return undefined;
      }

      return sortedThreads.filter(c => {
        if (draftsOnly) {
          return c.hasDraft;
        } else if (unresolvedOnly) {
          return c.unresolved;
        } else {
          const comments = c && c.thread && c.thread.comments;
          let robotComment = false;
          let humanReplyToRobotComment = false;
          comments.forEach(comment => {
            if (comment.robot_id) {
              robotComment = true;
            } else if (robotComment) {
              // Robot comment exists and human comment exists after it
              humanReplyToRobotComment = true;
            }
          });
          if (robotComment) {
            return humanReplyToRobotComment ? c : false;
          }
          return c;
        }
      }).map(threadInfo => threadInfo.thread);
    }

    _getThreadWithSortInfo(thread) {
      const lastComment = thread.comments[thread.comments.length - 1] || {};

      const lastNonDraftComment =
          (lastComment.__draft && thread.comments.length > 1) ?
            thread.comments[thread.comments.length - 2] :
            lastComment;

      return {
        thread,
        // Use the unresolved bit for the last non draft comment. This is what
        // anybody other than the current user would see.
        unresolved: !!lastNonDraftComment.unresolved,
        hasDraft: !!lastComment.__draft,
        updated: lastComment.updated,
      };
    }

    removeThread(rootId) {
      for (let i = 0; i < this.threads.length; i++) {
        if (this.threads[i].rootId === rootId) {
          this.splice('threads', i, 1);
          // Needed to ensure threads get re-rendered in the correct order.
          Polymer.dom.flush();
          return;
        }
      }
    }

    _handleThreadDiscard(e) {
      this.removeThread(e.detail.rootId);
    }

    _handleCommentsChanged(e) {
      // Reset threads so thread computations occur on deep array changes to
      // threads comments that are not observed naturally.
      this._updateSortedThreads(this.threads);

      this.dispatchEvent(new CustomEvent('thread-list-modified',
          {detail: {rootId: e.detail.rootId, path: e.detail.path}}));
    }

    _isOnParent(side) {
      return !!side;
    }
  }

  customElements.define(GrThreadList.is, GrThreadList);
})();
