/**
 * @license
 * Copyright (C) 2017 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 '@polymer/iron-selector/iron-selector';
import '../../shared/gr-button/gr-button';
import '../../../styles/gr-voting-styles';
import '../../../styles/shared-styles';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-label-score-row_html';
import {customElement, property} from '@polymer/decorators';
import {IronSelectorElement} from '@polymer/iron-selector/iron-selector';
import {
  LabelNameToValueMap,
  LabelNameToInfoMap,
  QuickLabelInfo,
  DetailedLabelInfo,
} from '../../../types/common';
import {hasOwnProperty} from '../../../utils/common-util';

export interface Label {
  name: string;
  value: string | null;
}

// TODO(TS): add description to explain what this is after moving
// gr-label-scores to ts
export interface LabelValuesMap {
  [key: number]: number;
}

export interface GrLabelScoreRow {
  $: {
    labelSelector: IronSelectorElement;
  };
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-label-score-row': GrLabelScoreRow;
  }
}

@customElement('gr-label-score-row')
export class GrLabelScoreRow extends PolymerElement {
  static get template() {
    return htmlTemplate;
  }

  /**
   * Fired when any label is changed.
   *
   * @event labels-changed
   */

  @property({type: Object})
  label: Label | undefined | null;

  @property({type: Object})
  labels?: LabelNameToInfoMap;

  @property({type: String, reflectToAttribute: true})
  name?: string;

  @property({type: Object})
  permittedLabels: LabelNameToValueMap | undefined | null;

  @property({type: Object})
  labelValues?: LabelValuesMap;

  @property({type: String})
  _selectedValueText = 'No value selected';

  @property({
    computed: '_computePermittedLabelValues(permittedLabels, label.name)',
    type: Array,
  })
  _items!: string[];

  get selectedItem() {
    if (!this._ironSelector) {
      return undefined;
    }
    return this._ironSelector.selectedItem;
  }

  get selectedValue() {
    if (!this._ironSelector) {
      return undefined;
    }
    return this._ironSelector.selected;
  }

  setSelectedValue(value: string) {
    // The selector may not be present if it’s not at the latest patch set.
    if (!this._ironSelector) {
      return;
    }
    this._ironSelector.select(value);
  }

  get _ironSelector() {
    return this.$ && this.$.labelSelector;
  }

  _computeBlankItems(
    permittedLabels: LabelNameToValueMap,
    label: string,
    side: string
  ) {
    if (
      !permittedLabels ||
      !permittedLabels[label] ||
      !permittedLabels[label].length ||
      !this.labelValues ||
      !Object.keys(this.labelValues).length
    ) {
      return [];
    }
    const startPosition = this.labelValues[Number(permittedLabels[label][0])];
    if (side === 'start') {
      return new Array(startPosition);
    }
    const endPosition = this.labelValues[
      Number(permittedLabels[label][permittedLabels[label].length - 1])
    ];
    return new Array(Object.keys(this.labelValues).length - endPosition - 1);
  }

  _getLabelValue(
    labels: LabelNameToInfoMap,
    permittedLabels: LabelNameToValueMap,
    label: Label
  ) {
    if (label.value) {
      return label.value;
    } else if (
      hasOwnProperty(labels[label.name], 'default_value') &&
      hasOwnProperty(permittedLabels, label.name)
    ) {
      // default_value is an int, convert it to string label, e.g. "+1".
      return permittedLabels[label.name].find(
        value =>
          Number(value) === (labels[label.name] as QuickLabelInfo).default_value
      );
    }
    return;
  }

  /**
   * Maps the label value to exactly one of: min, max, positive, negative,
   * neutral. Used for the 'vote' attribute, because we don't want to
   * interfere with <iron-selector> using the 'class' attribute for setting
   * 'iron-selected'.
   */
  _computeVoteAttribute(value: number, index: number, totalItems: number) {
    if (value < 0 && index === 0) {
      return 'min';
    } else if (value < 0) {
      return 'negative';
    } else if (value > 0 && index === totalItems - 1) {
      return 'max';
    } else if (value > 0) {
      return 'positive';
    } else {
      return 'neutral';
    }
  }

  _computeLabelValue(
    labels?: LabelNameToInfoMap,
    permittedLabels?: LabelNameToValueMap,
    label?: Label
  ) {
    // Polymer 2+ undefined check
    if (
      labels === undefined ||
      permittedLabels === undefined ||
      label === undefined
    ) {
      return null;
    }

    if (!labels[label.name]) {
      return null;
    }
    const labelValue = this._getLabelValue(labels, permittedLabels, label);
    const len = permittedLabels[label.name]
      ? permittedLabels[label.name].length
      : 0;
    for (let i = 0; i < len; i++) {
      const val = permittedLabels[label.name][i];
      if (val === labelValue) {
        return val;
      }
    }
    return null;
  }

  _setSelectedValueText(e: Event) {
    // Needed because when the selected item changes, it first changes to
    // nothing and then to the new item.
    const selectedItem = (e.target as IronSelectorElement)
      .selectedItem as HTMLElement;
    if (!selectedItem) {
      return;
    }
    if (!this.$.labelSelector.items) {
      return;
    }
    for (const item of this.$.labelSelector.items) {
      if (selectedItem === item) {
        item.setAttribute('aria-checked', 'true');
      } else {
        item.removeAttribute('aria-checked');
      }
    }
    this._selectedValueText = selectedItem.getAttribute('title') || '';
    // Needed to update the style of the selected button.
    this.updateStyles();
    const name = selectedItem.dataset['name'];
    const value = selectedItem.dataset['value'];
    this.dispatchEvent(
      new CustomEvent('labels-changed', {
        detail: {name, value},
        bubbles: true,
        composed: true,
      })
    );
  }

  _computeAnyPermittedLabelValues(
    permittedLabels: LabelNameToValueMap,
    labelName: string
  ) {
    return (
      permittedLabels &&
      hasOwnProperty(permittedLabels, labelName) &&
      permittedLabels[labelName].length
    );
  }

  _computeHiddenClass(permittedLabels: LabelNameToValueMap, labelName: string) {
    return !this._computeAnyPermittedLabelValues(permittedLabels, labelName)
      ? 'hidden'
      : '';
  }

  _computePermittedLabelValues(
    permittedLabels?: LabelNameToValueMap,
    labelName?: string
  ) {
    // Polymer 2: check for undefined
    if (permittedLabels === undefined || labelName === undefined) {
      return [];
    }

    return permittedLabels[labelName] || [];
  }

  _computeLabelValueTitle(
    labels: LabelNameToInfoMap,
    label: string,
    value: string
  ) {
    // TODO(TS): maybe add a type guard for DetailedLabelInfo and QuickLabelInfo
    return (
      labels[label] &&
      (labels[label] as DetailedLabelInfo).values &&
      (labels[label] as DetailedLabelInfo).values![value]
    );
  }
}
