/**
 * @license
 * Copyright (C) 2020 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.
 */
import {CodeOwnersModelMixin} from './code-owners-model-mixin.js';
import {SuggestionsState} from './code-owners-model.js';

const SUGGESTION_POLLING_INTERVAL = 1000;

class OwnerGroupFileList extends Polymer.Element {
  static get is() {
    return 'owner-group-file-list';
  }

  static get properties() {
    return {
      files: Array,
    };
  }

  static get template() {
    return Polymer.html`
      <style include="shared-styles">
        :host {
          display: block;
          max-height: 500px;
          overflow: auto;
        }
        span {
          display: inline-block;
          border-radius: var(--border-radius);
          margin-left: var(--spacing-s);
          padding: 0 var(--spacing-m);
          color: var(--primary-text-color);
          font-size: var(--font-size-small);
        }
        .Renamed {
          background-color: var(--dark-remove-highlight-color);
          margin: var(--spacing-s) 0;
        }
      </style>
      <ul>
        <template
          is="dom-repeat"
          items="[[files]]"
          as="file"
        >
          <li>
            [[computeFilePath(file)]]<!--
            --><strong>[[computeFileName(file)]]</strong>
            <template is="dom-if" if="[[file.status]]">
              <span class$="[[file.status]]">
                [[file.status]]
              </span>
            </template>
          </li>
        </template>
      </ul>
    `;
  }

  computeFilePath(file) {
    const parts = file.path.split('/');
    return parts.slice(0, parts.length - 1).join('/') + '/';
  }

  computeFileName(file) {
    const parts = file.path.split('/');
    return parts.pop();
  }
}

customElements.define(OwnerGroupFileList.is, OwnerGroupFileList);

export class SuggestOwners extends CodeOwnersModelMixin(Polymer.Element) {
  static get is() {
    return 'suggest-owners';
  }

  static get template() {
    return Polymer.html`
      <style include="shared-styles">
        :host {
          display: block;
          background-color: var(--view-background-color);
          border: 1px solid var(--view-background-color);
          border-radius: var(--border-radius);
          box-shadow: var(--elevation-level-1);
          padding: var(--spacing-s);
          margin: var(--spacing-m) 0;
        }
        p.loading {
          text-align: center;
        }
        .loadingSpin {
          display: inline-block;
        }
        li {
          list-style: none;
        }
        .suggestion-container {
          /* TODO: TBD */
          max-height: 300px;
          overflow-y: auto;
        }
        .suggestion-row {
          display: flex;
          flex-direction: row;
          align-items: flex-start;
          border-bottom: 1px solid var(--border-color);
          padding: var(--spacing-s) 0;
        }
        .suggestion-row:last-of-type {
          border-bottom: none;
        }
        .suggestion-row-indicator {
          margin-right: var(--spacing-m);
          visibility: hidden;
          line-height: 26px;
        }
        .suggestion-row-indicator[visible] {
          visibility: visible;
        }
        .suggestion-row-indicator[visible] iron-icon {
          color: var(--link-color);
        }
        .suggestion-group-name {
          width: 200px;
          line-height: 26px;
          text-overflow: ellipsis;
          overflow: hidden;
          padding-right: var(--spacing-l);
          white-space: nowrap;
        }
        .group-name-content {
          display: flex;
          align-items: center;
        }
        .group-name-content .group-name {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        .group-name-prefix {
          padding-left: var(--spacing-s);
          white-space: nowrap;
          color: var(--deemphasized-text-color);
        }
        .suggested-owners {
          flex: 1;
        }
        .fetch-error-content,
        .no-owners-content {
          line-height: 26px;
          flex: 1;
          padding-left: var(--spacing-m);
        }
        .fetch-error-content {
          color: var(--error-text-color);
        }
        .no-owners-content a {
          padding-left: var(--spacing-s);
        }
        .no-owners-content a iron-icon {
          width: 16px;
          height: 16px;
        }
        gr-account-label {
          display: inline-block;
          padding: var(--spacing-xs) var(--spacing-m);
          user-select: none;
          border: 1px solid transparent;
          --label-border-radius: 8px;
          /* account-max-length defines the max text width inside account-label.
           With 60px the gr-account-label always has width <= 100px and 5 labels
           are always fit in a single row */
          --account-max-length: 60px;
          border: 1px solid var(--border-color);
        }
        gr-account-label:focus {
          outline: none;
        }
        gr-account-label:hover {
          box-shadow: var(--elevation-level-1);
          cursor: pointer;
        }
        gr-account-label[selected] {
          background-color: var(--chip-selected-background-color);
          border: 1px solid var(--chip-selected-background-color);
          color: var(--chip-selected-text-color);
        }
        gr-hovercard {
          max-width: 800px;
        }
        .loading {
          display: flex;
          align-content: center;
          align-items: center;
          justify-content: center;
          padding: var(--spacing-m);
        }
        .loadingSpin {
          width: 18px;
          height: 18px;
          margin-right: var(--spacing-m);
        }
      </style>
      <p class="loading" hidden="[[!isLoading]]">
        <span class="loadingSpin"></span>
        [[progressText]]
      </p>
      <ul class="suggestion-container">
        <template
          is="dom-repeat"
          items="[[suggestedOwners]]"
          as="suggestion"
          index-as="suggestionIndex"
        >
          <li class="suggestion-row">
            <div
              class="suggestion-row-indicator"
              visible$="[[suggestion.hasSelected]]"
            >
              <iron-icon icon="gr-icons:check-circle"></iron-icon>
            </div>
            <div class="suggestion-group-name">
              <div class="group-name-content">
                <span class="group-name">
                  [[suggestion.groupName.name]]
                </span>
                <template is="dom-if" if="[[suggestion.groupName.prefix]]">
                  <span class="group-name-prefix">
                    ([[suggestion.groupName.prefix]])
                  </span>
                </template>
                <gr-hovercard hidden="[[suggestion.expanded]]">
                  <owner-group-file-list
                    files="[[suggestion.files]]"
                  >
                  </owner-group-file-list>
                </gr-hovercard>
              </div>
              <owner-group-file-list
                hidden="[[!suggestion.expanded]]"
                files="[[suggestion.files]]"
              ></owner-group-file-list>
            </div>
            <template is="dom-if" if="[[suggestion.error]]">
              <div class="fetch-error-content">
                [[suggestion.error]]
                <a on-click="_showErrorDetails"
              </div>
            </template>
            <template is="dom-if" if="[[!suggestion.error]]">
              <template is="dom-if" if="[[!suggestion.owners.length]]">
                <div class="no-owners-content">
                  <span>Not found</span>
                  <a on-click="_reportDocClick" href="https://gerrit.googlesource.com/plugins/code-owners/+/master/resources/Documentation/how-to-use.md#no-code-owners-found" target="_blank">
                    <iron-icon icon="gr-icons:help-outline" title="read documentation"></iron-icon>
                  </a>
                </div>
              </template>
              <ul class="suggested-owners">
                <template
                  is="dom-repeat"
                  items="[[suggestion.owners]]"
                  as="owner"
                  index-as="ownerIndex"
                >
                  <gr-account-label
                    data-suggestion-index$="[[suggestionIndex]]"
                    data-owner-index$="[[ownerIndex]]"
                    account="[[owner.account]]"
                    selected$="[[isSelected(owner)]]"
                    on-click="toggleAccount">
                  </gr-account-label>
                </template>
              </ul>
            </template>
          </li>
        </template>
      </ul>
    `;
  }

  static get properties() {
    return {
      // @internal attributes
      hidden: {
        type: Boolean,
        value: true,
        reflectToAttribute: true,
        computed: '_isHidden(model.areAllFilesApproved, ' +
            'model.showSuggestions)',
      },
      suggestedOwners: Array,
      isLoading: {
        type: Boolean,
        value: true,
      },
      reviewers: {
        type: Array,
      },
      pendingReviewers: Array,
    };
  }

  static get observers() {
    return [
      '_onReviewerChanged(reviewers)',
      '_onShowSuggestionsChanged(model.showSuggestions)',
      '_onSuggestionsStateChanged(model.suggestionsState)',
      '_onSuggestionsChanged(model.suggestions, model.suggestionsState)',
      '_onSuggestionsLoadProgressChanged(model.suggestionsLoadProgress)',
    ];
  }

  _onShowSuggestionsChanged(showSuggestions) {
    if (!showSuggestions ||
        this.model.suggestionsLoadProgress === SuggestionsState.NotLoaded) {
      return;
    }
    // this is more of a hack to let review input lose focus
    // to avoid suggestion dropdown
    // gr-autocomplete has a internal state for tracking focus
    // that will be canceled if any click happens outside of
    // it's target
    // Can not use `this.async` as it's only available in
    // legacy element mixin which not used in this plugin.
    Polymer.Async.timeOut.run(() => this.click(), 100);

    this.modelLoader.loadSuggestions();
    this.reporting.reportLifeCycle('owners-suggestions-fetching-start');
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    this._stopUpdateProgressTimer();
  }

  _startUpdateProgressTimer() {
    if (this._progressUpdateTimer) return;
    this._progressUpdateTimer = setInterval(() => {
      this.modelLoader.updateLoadSuggestionsProgress();
    }, SUGGESTION_POLLING_INTERVAL);
  }

  _stopUpdateProgressTimer() {
    if (!this._progressUpdateTimer) return;
    clearInterval(this._progressUpdateTimer);
    this._progressUpdateTimer = undefined;
  }

  _onSuggestionsStateChanged(state) {
    this._stopUpdateProgressTimer();
    if (state === SuggestionsState.Loading) {
      this._startUpdateProgressTimer();
    }
    this.isLoading = state === SuggestionsState.Loading;
  }

  _isHidden(allFilesApproved, showSuggestions) {
    if (!showSuggestions) return true;
    // if all approved, no need to show the container
    return allFilesApproved === undefined || !!allFilesApproved;
  }

  loadPropertiesAfterModelChanged() {
    super.loadPropertiesAfterModelChanged();
    this._stopUpdateProgressTimer();
    this.modelLoader.loadAreAllFilesApproved();
  }

  _onSuggestionsChanged(suggestions, suggestionsState) {
    // The updateLoadSuggestionsProgress method also updates suggestions
    this._updateSuggestions(suggestions || []);
    this._updateAllChips(this._currentReviewers);
    if (!suggestions || suggestionsState !== SuggestionsState.Loaded) return;
    const reportDetails = suggestions.reduce((details, cur) => {
      details.totalGroups++;
      details.stats.push([cur.files.length,
        cur.owners ? cur.owners.length : 0]);
      return details;
    }, {totalGroups: 0, stats: []});
    this.reporting.reportLifeCycle(
        'owners-suggestions-fetching-finished', reportDetails);
  }

  _onSuggestionsLoadProgressChanged(progress) {
    this.progressText = progress;
  }

  _updateSuggestions(suggestions) {
    // update group names and files, no modification on owners or error
    this.suggestedOwners = suggestions.map(suggestion => {
      return this.formatSuggestionInfo(suggestion);
    });
  }

  _onReviewerChanged(reviewers) {
    this._currentReviewers = reviewers;
    this._updateAllChips(reviewers);
  }

  formatSuggestionInfo(suggestion) {
    const res = {};
    res.groupName = suggestion.groupName;
    res.files = suggestion.files.slice();
    res.owners = (suggestion.owners || []).map(owner => {
      const updatedOwner = {...owner};
      const reviewers = this.change.reviewers.REVIEWER;
      if (
        reviewers &&
        reviewers.find(reviewer => reviewer._account_id === owner._account_id)
      ) {
        updatedOwner.selected = true;
      }
      return updatedOwner;
    });
    res.error = suggestion.error;
    return res;
  }

  addAccount(owner) {
    owner.selected = true;
    this.dispatchEvent(
        new CustomEvent('add-reviewer', {
          detail: {
            reviewer: {...owner.account, _pendingAdd: true},
          },
          composed: true,
          bubbles: true,
        })
    );
    this.reporting.reportInteraction('add-reviewer');
  }

  removeAccount(owner) {
    owner.selected = false;
    this.dispatchEvent(
        new CustomEvent('remove-reviewer', {
          detail: {
            reviewer: {...owner.account, _pendingAdd: true},
          },
          composed: true,
          bubbles: true,
        })
    );
    this.reporting.reportInteraction('remove-reviewer');
  }

  toggleAccount(e) {
    const grAccountLabel = e.currentTarget;
    const owner = this.suggestedOwners[grAccountLabel.dataset.suggestionIndex]
        .owners[grAccountLabel.dataset.ownerIndex];
    if (this.isSelected(owner)) {
      this.removeAccount(owner);
    } else {
      this.addAccount(owner);
    }
  }

  _updateAllChips(accounts) {
    if (!this.suggestedOwners || !accounts) return;
    // update all occurences
    this.suggestedOwners.forEach((suggestion, sId) => {
      let hasSelected = false;
      suggestion.owners.forEach((owner, oId) => {
        if (
          accounts.some(account => account._account_id
              === owner.account._account_id)
        ) {
          this.set(
              ['suggestedOwners', sId, 'owners', oId],
              {...owner,
                selected: true,
              }
          );
          hasSelected = true;
        } else {
          this.set(
              ['suggestedOwners', sId, 'owners', oId],
              {...owner, selected: false}
          );
        }
      });
      this.set(['suggestedOwners', sId, 'hasSelected'], hasSelected);
    });
  }

  isSelected(owner) {
    return owner.selected;
  }

  _reportDocClick() {
    this.reporting.reportInteraction('code-owners-doc-click',
        {section: 'no owners found'});
  }
}

customElements.define(SuggestOwners.is, SuggestOwners);
