// Copyright 2019 The Chromium Authors
// 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);
