/**
 * @license
 * Copyright (C) 2022 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 '../../change/gr-submit-requirement-dashboard-hovercard/gr-submit-requirement-dashboard-hovercard';
import '../../shared/gr-change-status/gr-change-status';
import {LitElement, css, html} from 'lit';
import {customElement, property} from 'lit/decorators';
import {
  ApprovalInfo,
  ChangeInfo,
  isDetailedLabelInfo,
  isQuickLabelInfo,
  LabelInfo,
  SubmitRequirementResultInfo,
  SubmitRequirementStatus,
} from '../../../api/rest-api';
import {submitRequirementsStyles} from '../../../styles/gr-submit-requirements-styles';
import {
  extractAssociatedLabels,
  getAllUniqueApprovals,
  getRequirements,
  getTriggerVotes,
  hasNeutralStatus,
  hasVotes,
  iconForStatus,
} from '../../../utils/label-util';
import {sharedStyles} from '../../../styles/shared-styles';
import {ifDefined} from 'lit/directives/if-defined';
import {capitalizeFirstLetter} from '../../../utils/string-util';

@customElement('gr-change-list-column-requirement')
export class GrChangeListColumnRequirement extends LitElement {
  @property({type: Object})
  change?: ChangeInfo;

  @property()
  labelName?: string;

  static override get styles() {
    return [
      submitRequirementsStyles,
      sharedStyles,
      css`
        iron-icon {
          vertical-align: top;
        }
        .container {
          display: flex;
          align-items: center;
          justify-content: center;
        }
        .container.not-applicable {
          background-color: var(--table-header-background-color);
          height: calc(var(--line-height-normal) + var(--spacing-m));
        }
      `,
    ];
  }

  override render() {
    return html`<div
      class="container ${this.computeClass()}"
      title="${ifDefined(this.computeLabelTitle())}"
    >
      ${this.renderContent()}
    </div>`;
  }

  private renderContent() {
    if (!this.labelName) return;
    const requirements = this.getRequirement(this.labelName);
    if (requirements.length === 0) {
      return this.renderTriggerVote();
    }

    const requirement = requirements[0];
    if (requirement.status === SubmitRequirementStatus.UNSATISFIED) {
      return this.renderUnsatisfiedState(requirement);
    } else {
      return this.renderStatusIcon(requirement.status);
    }
  }

  private renderTriggerVote() {
    if (!this.labelName || !this.isTriggerVote(this.labelName)) return;
    const allLabels = this.change?.labels ?? {};
    const labelInfo = allLabels[this.labelName];
    if (isDetailedLabelInfo(labelInfo)) {
      // votes sorted from best e.g +2 to worst e.g -2
      const votes = this.getSortedVotes(this.labelName);
      if (votes.length > 0) {
        const bestVote = votes[0];
        return html`<gr-vote-chip
          .vote="${bestVote}"
          .label="${labelInfo}"
          tooltip-with-who-voted
        ></gr-vote-chip>`;
      }
    }
    if (isQuickLabelInfo(labelInfo)) {
      return html`<gr-vote-chip .label="${labelInfo}"></gr-vote-chip>`;
    }
    return;
  }

  private renderUnsatisfiedState(requirement: SubmitRequirementResultInfo) {
    const requirementLabels = extractAssociatedLabels(
      requirement,
      'onlySubmittability'
    );
    const allLabels = this.change?.labels ?? {};
    const associatedLabels = Object.keys(allLabels).filter(label =>
      requirementLabels.includes(label)
    );

    let worstVote: ApprovalInfo | undefined;
    let labelInfo: LabelInfo | undefined;
    for (const label of associatedLabels) {
      // votes sorted from worst e.g -2 to best e.g +2
      const votes = this.getSortedVotes(label).sort(
        (a, b) => (a.value ?? 0) - (b.value ?? 0)
      );
      if (votes.length === 0) break;
      if (!worstVote || (worstVote.value ?? 0) > (votes[0].value ?? 0)) {
        worstVote = votes[0];
        labelInfo = allLabels[label];
      }
    }
    if (worstVote === undefined) {
      return this.renderStatusIcon(requirement.status);
    } else {
      return html`<gr-vote-chip
        .vote="${worstVote}"
        .label="${labelInfo}"
        tooltip-with-who-voted
      ></gr-vote-chip>`;
    }
  }

  private renderStatusIcon(status: SubmitRequirementStatus) {
    const icon = iconForStatus(status ?? SubmitRequirementStatus.ERROR);
    return html`<iron-icon
      class="${icon}"
      icon="gr-icons:${icon}"
    ></iron-icon>`;
  }

  private computeClass(): string {
    if (!this.labelName) return '';
    const requirements = this.getRequirement(this.labelName);
    if (requirements.length === 0 && !this.isTriggerVote(this.labelName)) {
      return 'not-applicable';
    }
    return '';
  }

  private computeLabelTitle() {
    if (!this.labelName) return;
    const requirements = this.getRequirement(this.labelName);
    if (requirements.length === 0) {
      if (this.isTriggerVote(this.labelName)) {
        return;
      } else {
        return 'Requirement not applicable';
      }
    }
    const requirement = requirements[0];
    if (requirement.status === SubmitRequirementStatus.UNSATISFIED) {
      const requirementLabels = extractAssociatedLabels(
        requirement,
        'onlySubmittability'
      );
      const allLabels = this.change?.labels ?? {};
      const associatedLabels = Object.keys(allLabels).filter(label =>
        requirementLabels.includes(label)
      );
      const requirementWithoutLabelToVoteOn = associatedLabels.length === 0;
      if (requirementWithoutLabelToVoteOn) {
        const status = capitalizeFirstLetter(requirement.status.toLowerCase());
        return status;
      }

      const everyAssociatedLabelsIsWithoutVotes = associatedLabels.every(
        label => !hasVotes(allLabels[label])
      );
      if (everyAssociatedLabelsIsWithoutVotes) {
        return 'No votes';
      } else {
        return; // there is a vote with tooltip, so undefined label title
      }
    } else {
      return capitalizeFirstLetter(requirement.status.toLowerCase());
    }
  }

  private getRequirement(labelName: string) {
    const requirements = getRequirements(this.change).filter(
      sr => sr.name === labelName
    );
    // TODO(milutin): Remove this after migration from legacy requirements.
    if (requirements.length > 1) {
      return requirements.filter(sr => !sr.is_legacy);
    } else {
      return requirements;
    }
  }

  private getSortedVotes(label: string) {
    const allLabels = this.change?.labels ?? {};
    const labelInfo = allLabels[label];
    if (isDetailedLabelInfo(labelInfo)) {
      return getAllUniqueApprovals(labelInfo).filter(
        approval => !hasNeutralStatus(labelInfo, approval)
      );
    }
    return [];
  }

  private isTriggerVote(labelName: string) {
    const triggerVotes = getTriggerVotes(this.change);
    return triggerVotes.includes(labelName);
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-change-list-column-requirement': GrChangeListColumnRequirement;
  }
}
