/**
 * @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 '../gr-label-score-row/gr-label-score-row';
import '../../../styles/shared-styles';
import {LitElement, css, html} from 'lit';
import {customElement, property} from 'lit/decorators';
import {hasOwnProperty} from '../../../utils/common-util';
import {
  LabelNameToValueMap,
  ChangeInfo,
  AccountInfo,
  DetailedLabelInfo,
  LabelNameToInfoMap,
  LabelNameToValuesMap,
} from '../../../types/common';
import {
  GrLabelScoreRow,
  Label,
  LabelValuesMap,
} from '../gr-label-score-row/gr-label-score-row';
import {appContext} from '../../../services/app-context';
import {labelCompare} from '../../../utils/label-util';
import {Execution} from '../../../constants/reporting';
import {ChangeStatus} from '../../../constants/constants';

@customElement('gr-label-scores')
export class GrLabelScores extends LitElement {
  @property({type: Object})
  permittedLabels?: LabelNameToValueMap;

  @property({type: Object})
  change?: ChangeInfo;

  @property({type: Object})
  account?: AccountInfo;

  private readonly reporting = appContext.reportingService;

  static override get styles() {
    return [
      css`
        .scoresTable {
          display: table;
          width: 100%;
        }
        .mergedMessage,
        .abandonedMessage {
          font-style: italic;
          text-align: center;
          width: 100%;
        }
        gr-label-score-row:hover {
          background-color: var(--hover-background-color);
        }
        gr-label-score-row {
          display: table-row;
        }
        gr-label-score-row.no-access {
          display: none;
        }
      `,
    ];
  }

  override render() {
    const labels = this._computeLabels();
    const labelValues = this._computeColumns();
    return html`<div class="scoresTable">
        ${labels.map(
          label => html`<gr-label-score-row
            class="${this.computeLabelAccessClass(label.name)}"
            .label="${label}"
            .name="${label.name}"
            .labels="${this.change?.labels}"
            .permittedLabels="${this.permittedLabels}"
            .labelValues="${labelValues}"
          ></gr-label-score-row>`
        )}
      </div>
      <div
        class="mergedMessage"
        ?hidden=${this.change?.status !== ChangeStatus.MERGED}
      >
        Because this change has been merged, votes may not be decreased.
      </div>
      <div
        class="abandonedMessage"
        ?hidden=${this.change?.status !== ChangeStatus.ABANDONED}
      >
        Because this change has been abandoned, you cannot vote.
      </div>`;
  }

  getLabelValues(includeDefaults = true): LabelNameToValuesMap {
    const labels: LabelNameToValuesMap = {};
    if (this.shadowRoot === null || !this.change) {
      return labels;
    }
    for (const label of Object.keys(this.permittedLabels ?? {})) {
      const selectorEl = this.shadowRoot.querySelector(
        `gr-label-score-row[name="${label}"]`
      ) as null | GrLabelScoreRow;
      if (!selectorEl?.selectedItem) continue;

      const selectedVal =
        typeof selectorEl.selectedValue === 'string'
          ? Number(selectorEl.selectedValue)
          : selectorEl.selectedValue;

      if (selectedVal === undefined) continue;

      const defValNum = this.getDefaultValue(label);
      if (includeDefaults || selectedVal !== defValNum) {
        labels[label] = selectedVal;
      }
    }
    return labels;
  }

  private getStringLabelValue(
    labels: LabelNameToInfoMap,
    labelName: string,
    numberValue?: number
  ): string {
    const detailedInfo = labels[labelName] as DetailedLabelInfo;
    if (detailedInfo.values) {
      for (const labelValue of Object.keys(detailedInfo.values)) {
        if (Number(labelValue) === numberValue) {
          return labelValue;
        }
      }
    }
    const stringVal = `${numberValue}`;
    this.reporting.reportExecution(Execution.REACHABLE_CODE, {
      value: stringVal,
      id: 'label-value-not-found',
    });
    return stringVal;
  }

  private getDefaultValue(labelName?: string) {
    const labels = this.change?.labels;
    if (!labelName || !labels?.[labelName]) return undefined;
    const labelInfo = labels[labelName] as DetailedLabelInfo;
    return labelInfo.default_value;
  }

  _getVoteForAccount(labelName: string): string | null {
    const labels = this.change?.labels;
    if (!labels) return null;
    const votes = labels[labelName] as DetailedLabelInfo;
    if (votes.all && votes.all.length > 0) {
      for (let i = 0; i < votes.all.length; i++) {
        if (
          this.account &&
          // TODO(TS): Replace == with === and check code can assign string to _account_id instead of number
          // eslint-disable-next-line eqeqeq
          votes.all[i]._account_id == this.account._account_id
        ) {
          return this.getStringLabelValue(
            labels,
            labelName,
            votes.all[i].value
          );
        }
      }
    }
    return null;
  }

  _computeLabels(): Label[] {
    if (!this.account) return [];
    const labelsObj = this.change?.labels;
    if (!labelsObj) return [];
    return Object.keys(labelsObj)
      .sort(labelCompare)
      .map(key => {
        return {
          name: key,
          value: this._getVoteForAccount(key),
        };
      });
  }

  _computeColumns() {
    if (!this.permittedLabels) return;
    const labels = Object.keys(this.permittedLabels);
    const values: Set<number> = new Set();
    for (const label of labels) {
      for (const value of this.permittedLabels[label]) {
        values.add(Number(value));
      }
    }

    const orderedValues = Array.from(values.values()).sort((a, b) => a - b);

    const labelValues: LabelValuesMap = {};
    for (let i = 0; i < orderedValues.length; i++) {
      labelValues[orderedValues[i]] = i;
    }
    return labelValues;
  }

  private computeLabelAccessClass(label?: string) {
    if (!this.permittedLabels || !label) return '';

    return hasOwnProperty(this.permittedLabels, label) &&
      this.permittedLabels[label].length
      ? 'access'
      : 'no-access';
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-label-scores': GrLabelScores;
  }
}
