// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {LitElement, html} from 'lit-element';

import 'elements/chops/chops-dialog/chops-dialog.js';
import 'elements/chops/chops-collapse/chops-collapse.js';
import {store, connectStore} from 'reducers/base.js';
import * as issueV0 from 'reducers/issueV0.js';
import * as projectV0 from 'reducers/projectV0.js';
import * as userV0 from 'reducers/userV0.js';
import * as ui from 'reducers/ui.js';
import {fieldTypes} from 'shared/issue-fields.js';
import 'elements/framework/mr-comment-content/mr-description.js';
import '../mr-comment-list/mr-comment-list.js';
import 'elements/issue-detail/metadata/mr-edit-metadata/mr-edit-metadata.js';
import 'elements/issue-detail/metadata/mr-metadata/mr-metadata.js';
import {APPROVER_RESTRICTED_STATUSES, STATUS_ENUM_TO_TEXT, TEXT_TO_STATUS_ENUM,
  STATUS_CLASS_MAP, CLASS_ICON_MAP, APPROVAL_STATUSES,
} from 'shared/consts/approval.js';
import {commentListToDescriptionList} from 'shared/convertersV0.js';
import {cueNames, cueNameToSpec} from 'elements/help/mr-cue/cue-helpers.js';


/**
 * @type {Array<string>} The list of built in metadata fields to show on
 *   issue approvals.
 */
const APPROVAL_METADATA_FIELDS = ['ApprovalStatus', 'Approvers', 'Setter',
  cueNameToSpec(cueNames.AVAILABILITY_MSGS)];

/**
 * `<mr-approval-card>`
 *
 * This element shows a card for a single approval.
 *
 */
export class MrApprovalCard extends connectStore(LitElement) {
  /** @override */
  render() {
    return html`
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
            rel="stylesheet">
      <style>
        mr-approval-card {
          width: 100%;
          background-color: var(--chops-white);
          font-size: var(--chops-main-font-size);
          border-bottom: var(--chops-normal-border);
          box-sizing: border-box;
          display: block;
          border-left: 4px solid var(--approval-bg-color);

          /* Default styles are for the NotSet/NeedsReview case. */
          --approval-bg-color: var(--chops-purple-50);
          --approval-accent-color: var(--chops-purple-700);
        }
        mr-approval-card.status-na {
          --approval-bg-color: hsl(227, 20%, 92%);
          --approval-accent-color: hsl(227, 80%, 40%);
        }
        mr-approval-card.status-approved {
          --approval-bg-color: hsl(78, 55%, 90%);
          --approval-accent-color: hsl(78, 100%, 30%);
        }
        mr-approval-card.status-pending {
          --approval-bg-color: hsl(40, 75%, 90%);
          --approval-accent-color: hsl(33, 100%, 39%);
        }
        mr-approval-card.status-rejected {
          --approval-bg-color: hsl(5, 60%, 92%);
          --approval-accent-color: hsl(357, 100%, 39%);
        }
        mr-approval-card chops-button.edit-survey {
          border: var(--chops-normal-border);
          margin: 0;
        }
        mr-approval-card h3 {
          margin: 0;
          padding: 0;
          display: inline;
          font-weight: inherit;
          font-size: inherit;
          line-height: inherit;
        }
        mr-approval-card mr-description {
          display: block;
          margin-bottom: 0.5em;
        }
        .approver-notice {
          padding: 0.25em 0;
          width: 100%;
          display: flex;
          flex-direction: row;
          align-items: baseline;
          justify-content: space-between;
          border-bottom: 1px dotted hsl(0, 0%, 83%);
        }
        .card-content {
          box-sizing: border-box;
          padding: 0.5em 16px;
          padding-bottom: 1em;
        }
        .expand-icon {
          display: block;
          margin-right: 8px;
          color: hsl(0, 0%, 45%);
        }
        mr-approval-card .header {
          margin: 0;
          width: 100%;
          border: 0;
          font-size: var(--chops-large-font-size);
          font-weight: normal;
          box-sizing: border-box;
          display: flex;
          align-items: center;
          flex-direction: row;
          padding: 0.5em 8px;
          background-color: var(--approval-bg-color);
          cursor: pointer;
        }
        mr-approval-card .status {
          font-size: var(--chops-main-font-size);
          color: var(--approval-accent-color);
          display: inline-flex;
          align-items: center;
          margin-left: 32px;
        }
        mr-approval-card .survey {
          padding: 0.5em 0;
          max-height: 500px;
          overflow-y: auto;
          max-width: 100%;
          box-sizing: border-box;
        }
        mr-approval-card [role="heading"] {
          display: flex;
          flex-direction: row;
          justify-content: space-between;
          align-items: flex-end;
        }
        mr-approval-card .edit-header {
          margin-top: 40px;
        }
      </style>
      <button
        class="header"
        @click=${this.toggleCard}
        aria-expanded=${(this.opened || false).toString()}
      >
        <i class="material-icons expand-icon">
          ${this.opened ? 'expand_less' : 'expand_more'}
        </i>
        <h3>${this.fieldName}</h3>
        <span class="status">
          <i class="material-icons status-icon" role="presentation">
            ${CLASS_ICON_MAP[this._statusClass]}
          </i>
          ${this._status}
        </span>
      </button>
      <chops-collapse class="card-content" ?opened=${this.opened}>
        <div class="approver-notice">
          ${this._isApprover ? html`
            You are an approver for this bit.
          `: ''}
          ${this.user && this.user.isSiteAdmin ? html`
            Your site admin privileges give you full access to edit this approval.
          `: ''}
        </div>
        <mr-metadata
          aria-label="${this.fieldName} Approval Metadata"
          .approvalStatus=${this._status}
          .approvers=${this.approvers}
          .setter=${this.setter}
          .fieldDefs=${this.fieldDefs}
          .builtInFieldSpec=${APPROVAL_METADATA_FIELDS}
          isApproval
        ></mr-metadata>
        <h4
          class="medium-heading"
          role="heading"
        >
          ${this.fieldName} Survey
          <chops-button class="edit-survey" @click=${this._openSurveyEditor}>
            Edit responses
          </chops-button>
        </h4>
        <mr-description
          class="survey"
          .descriptionList=${this._allSurveys}
        ></mr-description>
        <mr-comment-list
          headingLevel=4
          .comments=${this.comments}
        ></mr-comment-list>
        ${this.issuePermissions.includes('addissuecomment') ? html`
          <h4 id="edit${this.fieldName}" class="medium-heading edit-header">
            Editing approval: ${this.phaseName} &gt; ${this.fieldName}
          </h4>
          <mr-edit-metadata
            .formName="${this.phaseName} > ${this.fieldName}"
            .approvers=${this.approvers}
            .fieldDefs=${this.fieldDefs}
            .statuses=${this._availableStatuses}
            .status=${this._status}
            .error=${this.updateError && (this.updateError.description || this.updateError.message)}
            ?saving=${this.updatingApproval}
            ?hasApproverPrivileges=${this._hasApproverPrivileges}
            isApproval
            @save=${this.save}
            @discard=${this.reset}
          ></mr-edit-metadata>
        ` : ''}
      </chops-collapse>
    `;
  }

  /** @override */
  static get properties() {
    return {
      fieldName: {type: String},
      approvers: {type: Array},
      phaseName: {type: String},
      setter: {type: Object},
      fieldDefs: {type: Array},
      focusId: {type: String},
      user: {type: Object},
      issue: {type: Object},
      issueRef: {type: Object},
      issuePermissions: {type: Array},
      projectConfig: {type: Object},
      comments: {type: String},
      opened: {
        type: Boolean,
        reflect: true,
      },
      statusEnum: {type: String},
      updatingApproval: {type: Boolean},
      updateError: {type: Object},
      _allSurveys: {type: Array},
    };
  }

  /** @override */
  constructor() {
    super();
    this.opened = false;
    this.comments = [];
    this.fieldDefs = [];
    this.issuePermissions = [];
    this._allSurveys = [];
  }

  /** @override */
  createRenderRoot() {
    return this;
  }

  /** @override */
  stateChanged(state) {
    const fieldDefsByApproval = projectV0.fieldDefsByApprovalName(state);
    if (fieldDefsByApproval && this.fieldName &&
        fieldDefsByApproval.has(this.fieldName)) {
      this.fieldDefs = fieldDefsByApproval.get(this.fieldName);
    }
    const commentsByApproval = issueV0.commentsByApprovalName(state);
    if (commentsByApproval && this.fieldName &&
        commentsByApproval.has(this.fieldName)) {
      const comments = commentsByApproval.get(this.fieldName);
      this.comments = comments.slice(1);
      this._allSurveys = commentListToDescriptionList(comments);
    }
    this.focusId = ui.focusId(state);
    this.user = userV0.currentUser(state);
    this.issue = issueV0.viewedIssue(state);
    this.issueRef = issueV0.viewedIssueRef(state);
    this.issuePermissions = issueV0.permissions(state);
    this.projectConfig = projectV0.viewedConfig(state);
    this.updatingApproval = issueV0.requests(state).updateApproval.requesting;
    this.updateError = issueV0.requests(state).updateApproval.error;
  }

  /** @override */
  update(changedProperties) {
    if ((changedProperties.has('comments') ||
        changedProperties.has('focusId')) && this.comments) {
      const focused = this.comments.find(
          (comment) => `c${comment.sequenceNum}` === this.focusId);
      if (focused) {
        // Make sure to open the card when a comment is focused.
        this.opened = true;
      }
    }
    if (changedProperties.has('statusEnum')) {
      this.setAttribute('class', this._statusClass);
    }
    if (changedProperties.has('user') || changedProperties.has('approvers')) {
      if (this._isApprover) {
        // Open the card by default if the user is an approver.
        this.opened = true;
      }
    }
    super.update(changedProperties);
  }

  /** @override */
  updated(changedProperties) {
    if (changedProperties.has('issue')) {
      this.reset();
    }
  }

  /**
   * Resets the approval edit form.
   */
  reset() {
    const form = this.querySelector('mr-edit-metadata');
    if (!form) return;
    form.reset();
  }

  /**
   * Saves the user's changes in the approval update form.
   */
  async save() {
    const form = this.querySelector('mr-edit-metadata');
    const delta = form.delta;

    if (delta.status) {
      delta.status = TEXT_TO_STATUS_ENUM[delta.status];
    }

    // TODO(ehmaldonado): Show snackbar on change, and prevent starring issues
    // to resetting the form.

    const message = {
      issueRef: this.issueRef,
      fieldRef: {
        type: fieldTypes.APPROVAL_TYPE,
        fieldName: this.fieldName,
      },
      approvalDelta: delta,
      commentContent: form.getCommentContent(),
      sendEmail: form.sendEmail,
    };

    // Add files to message.
    const uploads = await form.getAttachments();

    if (uploads && uploads.length) {
      message.uploads = uploads;
    }

    if (message.commentContent || message.approvalDelta || message.uploads) {
      store.dispatch(issueV0.updateApproval(message));
    }
  }

  /**
   * Opens and closes the approval card.
   */
  toggleCard() {
    this.opened = !this.opened;
  }

  /**
   * @return {string} The CSS class used to style the approval card,
   *   given its status.
   * @private
   */
  get _statusClass() {
    return STATUS_CLASS_MAP[this._status];
  }

  /**
   * @return {string} The human readable value of an approval status.
   * @private
   */
  get _status() {
    return STATUS_ENUM_TO_TEXT[this.statusEnum || ''];
  }

  /**
   * @return {boolean} Whether the user is an approver or not.
   * @private
   */
  get _isApprover() {
    // Assumption: Since a user who is an approver should always be a project
    // member, displayNames should be visible to them if they are an approver.
    if (!this.approvers || !this.user || !this.user.displayName) return false;
    const userGroups = this.user.groups || [];
    return !!this.approvers.find((a) => {
      return a.displayName === this.user.displayName || userGroups.find(
          (group) => group.displayName === a.displayName,
      );
    });
  }

  /**
   * @return {boolean} Whether the user can approver the approval or not.
   *   Not the same as _isApprover because site admins can approve approvals
   *   even if they are not approvers.
   * @private
   */
  get _hasApproverPrivileges() {
    return (this.user && this.user.isSiteAdmin) || this._isApprover;
  }

  /**
   * @return {Array<StatusDef>}
   * @private
   */
  get _availableStatuses() {
    return APPROVAL_STATUSES.filter((s) => {
      if (s.status === this._status) {
        // The current status should always appear as an option.
        return true;
      }

      if (!this._hasApproverPrivileges &&
          APPROVER_RESTRICTED_STATUSES.has(s.status)) {
        // If you are not an approver and and this status is restricted,
        // you can't change to this status.
        return false;
      }

      // No one can set statuses to NotSet, not even approvers.
      return s.status !== 'NotSet';
    });
  }

  /**
   * Launches the description editing dialog for the survey.
   * @fires CustomEvent#open-dialog
   * @private
   */
  _openSurveyEditor() {
    this.dispatchEvent(new CustomEvent('open-dialog', {
      bubbles: true,
      composed: true,
      detail: {
        dialogId: 'edit-description',
        fieldName: this.fieldName,
      },
    }));
  }
}

customElements.define('mr-approval-card', MrApprovalCard);
