/**
 * @license
 * Copyright (C) 2016 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-account-label/gr-account-label';
import '../gr-button/gr-button';
import '../gr-icons/gr-icons';
import {
  AccountInfo,
  ApprovalInfo,
  ChangeInfo,
  LabelInfo,
} from '../../../types/common';
import {getAppContext} from '../../../services/app-context';
import {LitElement, css, html} from 'lit';
import {customElement, property} from 'lit/decorators';
import {ClassInfo, classMap} from 'lit/directives/class-map';
import {KnownExperimentId} from '../../../services/flags/flags';
import {getLabelStatus, hasVoted, LabelStatus} from '../../../utils/label-util';

@customElement('gr-account-chip')
export class GrAccountChip extends LitElement {
  /**
   * Fired to indicate a key was pressed while this chip was focused.
   *
   * @event account-chip-keydown
   */

  /**
   * Fired to indicate this chip should be removed, i.e. when the x button is
   * clicked or when the remove function is called.
   *
   * @event remove
   */

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

  /**
   * Optional ChangeInfo object, typically comes from the change page or
   * from a row in a list of search results. This is needed for some change
   * related features like adding the user as a reviewer.
   */
  @property({type: Object})
  change?: ChangeInfo;

  /**
   * Should this user be considered to be in the attention set, regardless
   * of the current state of the change object?
   */
  @property({type: Boolean})
  forceAttention = false;

  @property({type: String})
  voteableText?: string;

  @property({type: Boolean, reflect: true})
  disabled = false;

  @property({type: Boolean, reflect: true})
  removable = false;

  /**
   * Should attention set related features be shown in the component? Note
   * that the information whether the user is in the attention set or not is
   * part of the ChangeInfo object in the change property.
   */
  @property({type: Boolean})
  highlightAttention = false;

  @property({type: Boolean, reflect: true})
  showAvatar?: boolean;

  @property({type: Boolean})
  transparentBackground = false;

  @property({type: Object})
  vote?: ApprovalInfo;

  @property({type: Object})
  label?: LabelInfo;

  private readonly restApiService = getAppContext().restApiService;

  private readonly flagsService = getAppContext().flagsService;

  static override get styles() {
    return [
      css`
        :host {
          display: block;
          overflow: hidden;
        }
        .container {
          align-items: center;
          background-color: var(--background-color-primary);
          /** round */
          border-radius: var(--account-chip-border-radius, 20px);
          border: 1px solid var(--border-color);
          display: inline-flex;
          padding: 0 1px;
          /* Any outermost circular icon would fit neatly in the border-radius
             and won't need padding, but the exact outermost elements will
             depend on account state and the context gr-account-chip is used.
             So, these values are passed down to gr-account-label and any
             outermost elements will use the value and then override it. */
          --account-label-padding-left: 6px;
          --account-label-padding-right: 6px;
          --account-label-circle-padding-left: 0;
          --account-label-circle-padding-right: 0;
        }
        :host:focus {
          border-color: transparent;
          box-shadow: none;
          outline: none;
        }
        :host:focus .container,
        :host:focus gr-button {
          background: #ccc;
        }
        .transparentBackground,
        gr-button.transparentBackground {
          background-color: transparent;
        }
        :host([disabled]) {
          opacity: 0.6;
          pointer-events: none;
        }
        iron-icon {
          height: 1.2rem;
          width: 1.2rem;
        }
        .container gr-account-label::part(gr-account-label-text) {
          color: var(--deemphasized-text-color);
        }
        .container.disliked {
          border: 1px solid var(--vote-outline-disliked);
        }
        .container.recommended {
          border: 1px solid var(--vote-outline-recommended);
        }
        .container.disliked,
        .container.recommended {
          --account-label-padding-right: var(--spacing-xs);
          --account-label-circle-padding-right: var(--spacing-xs);
        }
        .container.closeShown {
          --account-label-padding-right: 3px;
          --account-label-circle-padding-right: 3px;
        }
      `,
    ];
  }

  override render() {
    // To pass CSS mixins for @apply to Polymer components, they need to appear
    // in <style> inside the template.
    /* eslint-disable lit/prefer-static-styles */
    const customStyle = html`
      <style>
        gr-button.remove::part(paper-button),
        gr-button.remove:hover::part(paper-button),
        gr-button.remove:focus::part(paper-button) {
          border-top-width: 0;
          border-right-width: 0;
          border-bottom-width: 0;
          border-left-width: 0;
          color: var(--deemphasized-text-color);
          font-weight: var(--font-weight-normal);
          height: 0.6em;
          line-height: 10px;
          /* This cancels most of the --account-label-padding-horizontal. */
          margin-left: -4px;
          padding: 0 2px 0 1px;
          text-decoration: none;
        }
      </style>
    `;
    return html`${customStyle}
      <div
        class=${classMap({
          ...this.computeVoteClasses(),
          container: true,
          transparentBackground: this.transparentBackground,
          closeShown: this.removable,
        })}
      >
        <div>
          <gr-account-label
            .account=${this.account}
            .change=${this.change}
            ?forceAttention=${this.forceAttention}
            ?highlightAttention=${this.highlightAttention}
            .voteableText=${this.voteableText}
            clickable
          >
          </gr-account-label>
        </div>
        <slot name="vote-chip"></slot>
        <gr-button
          id="remove"
          link=""
          ?hidden=${!this.removable}
          aria-label="Remove"
          class=${classMap({
            remove: true,
            transparentBackground: this.transparentBackground,
          })}
          @click=${this._handleRemoveTap}
        >
          <iron-icon icon="gr-icons:close"></iron-icon>
        </gr-button>
      </div>`;
  }

  constructor() {
    super();
    this._getHasAvatars().then(hasAvatars => {
      this.showAvatar = hasAvatars;
    });
  }

  _handleRemoveTap(e: MouseEvent) {
    e.preventDefault();
    this.dispatchEvent(
      new CustomEvent('remove', {
        detail: {account: this.account},
        composed: true,
        bubbles: true,
      })
    );
  }

  _getHasAvatars() {
    return this.restApiService
      .getConfig()
      .then(cfg =>
        Promise.resolve(!!(cfg && cfg.plugin && cfg.plugin.has_avatars))
      );
  }

  private computeVoteClasses(): ClassInfo {
    if (
      !this.flagsService.isEnabled(KnownExperimentId.SUBMIT_REQUIREMENTS_UI) ||
      !this.label ||
      !this.account ||
      !hasVoted(this.label, this.account)
    ) {
      return {};
    }
    const status = getLabelStatus(this.label, this.vote?.value);
    if ([LabelStatus.APPROVED, LabelStatus.RECOMMENDED].includes(status)) {
      return {recommended: true};
    } else if ([LabelStatus.REJECTED, LabelStatus.DISLIKED].includes(status)) {
      return {disliked: true};
    } else {
      return {};
    }
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-account-chip': GrAccountChip;
  }
}
