// 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, css} from 'lit-element';
import {store} from 'reducers/base.js';
import * as issueV0 from 'reducers/issueV0.js';

import 'elements/chops/chops-button/chops-button.js';
import 'elements/chops/chops-timestamp/chops-timestamp.js';
import 'elements/framework/mr-comment-content/mr-comment-content.js';
import 'elements/framework/mr-comment-content/mr-attachment.js';
import 'elements/framework/mr-dropdown/mr-dropdown.js';
import 'elements/framework/links/mr-issue-link/mr-issue-link.js';
import 'elements/framework/links/mr-user-link/mr-user-link.js';
import {SHARED_STYLES} from 'shared/shared-styles.js';
import {issueStringToRef} from 'shared/convertersV0.js';
import {prpcClient} from 'prpc-client-instance.js';
import 'shared/typedef.js';

const ISSUE_REF_FIELD_NAMES = [
  'Blocking',
  'Blockedon',
  'Mergedinto',
];

/**
 * `<mr-comment>`
 *
 * A component for an individual comment.
 *
 */
export class MrComment extends LitElement {
  /** @override */
  constructor() {
    super();

    this._isExpandedIfDeleted = false;
  }

  /** @override */
  static get properties() {
    return {
      comment: {type: Object},
      headingLevel: {type: String},
      highlighted: {
        type: Boolean,
        reflect: true,
      },
      commenterIsMember: {type: Boolean},
      _isExpandedIfDeleted: {type: Boolean},
      _showOriginalContent: {type: Boolean},
    };
  }

  /** @override */
  updated(changedProperties) {
    super.updated(changedProperties);

    if (changedProperties.has('highlighted') && this.highlighted) {
      window.requestAnimationFrame(() => {
        this.scrollIntoView();
        // TODO(ehmaldonado): Figure out a way to get the height from the issue
        // header, and scroll by that amount.
        window.scrollBy(0, -150);
      });
    }
  }

  /** @override */
  static get styles() {
    return [
      SHARED_STYLES,
      css`
        :host {
          display: block;
          margin: 1.5em 0 0 0;
        }
        :host([highlighted]) {
          border: 1px solid var(--chops-primary-accent-color);
          box-shadow: 0 0 4px 4px var(--chops-active-choice-bg);
        }
        :host([hidden]) {
          display: none;
        }
        .comment-header {
          background: var(--chops-card-heading-bg);
          padding: 3px 1px 1px 8px;
          width: 100%;
          display: flex;
          flex-direction: row;
          justify-content: space-between;
          align-items: center;
          box-sizing: border-box;
        }
        .comment-header a {
          display: inline-flex;
        }
        .role-label {
          background-color: var(--chops-gray-600);
          border-radius: 3px;
          color: var(--chops-white);
          display: inline-block;
          padding: 2px 4px;
          font-size: 75%;
          font-weight: bold;
          line-height: 14px;
          vertical-align: text-bottom;
          margin-left: 16px;
        }
        .comment-options {
          float: right;
          text-align: right;
          text-decoration: none;
        }
        .comment-body {
          margin: 4px;
          box-sizing: border-box;
        }
        .deleted-comment-notice {
          margin-left: 4px;
        }
        .issue-diff {
          background: var(--chops-card-details-bg);
          display: inline-block;
          padding: 4px 8px;
          width: 100%;
          box-sizing: border-box;
        }
      `,
    ];
  }

  /** @override */
  render() {
    return html`
      ${this._renderHeading()}
      ${_shouldShowComment(this._isExpandedIfDeleted, this.comment) ? html`
        ${this._renderDiff()}
        ${this._renderBody()}
      ` : ''}
    `;
  }

  /**
   * @return {TemplateResult}
   */
  _renderHeading() {
    return html`
      <div
        role="heading"
        aria-level=${this.headingLevel}
        class="comment-header">
        <div>
          <a
            href="?id=${this.comment.localId}#c${this.comment.sequenceNum}"
            class="comment-link"
          >Comment ${this.comment.sequenceNum}</a>

          ${this._renderByline()}
        </div>
        ${_shouldOfferCommentOptions(this.comment) ? html`
          <div class="comment-options">
            <mr-dropdown
              .items=${this._commentOptions}
              label="Comment options"
              icon="more_vert"
            ></mr-dropdown>
          </div>
        ` : ''}
      </div>
    `;
  }

  /**
   * @return {TemplateResult}
   */
  _renderByline() {
    if (_shouldShowComment(this._isExpandedIfDeleted, this.comment)) {
      return html`
        by
        <mr-user-link .userRef=${this.comment.commenter}></mr-user-link>
        on
        <chops-timestamp
          .timestamp=${this.comment.timestamp}
        ></chops-timestamp>
        ${this.commenterIsMember && !this.comment.isDeleted ? html`
          <span class="role-label">Project Member</span>` : ''}
      `;
    } else {
      return html`<span class="deleted-comment-notice">Deleted</span>`;
    }
  }

  /**
   * @return {TemplateResult}
   */
  _renderDiff() {
    if (!(this.comment.descriptionNum || this.comment.amendments)) return '';

    return html`
      <div class="issue-diff">
        ${(this.comment.amendments || []).map((delta) => html`
          <strong>${delta.fieldName}:</strong>
          ${_issuesForAmendment(delta, this.comment.projectName).map((issueForAmendment) => html`
            <mr-issue-link
              projectName=${this.comment.projectName}
              .issue=${issueForAmendment.issue}
              text=${issueForAmendment.text}
            ></mr-issue-link>
          `)}
          ${!_amendmentHasIssueRefs(delta.fieldName) ? delta.newOrDeltaValue : ''}
          ${delta.oldValue ? `(was: ${delta.oldValue})` : ''}
          <br>
        `)}
        ${this.comment.descriptionNum ? 'Description was changed.' : ''}
      </div><br>
    `;
  }

  /**
   * @return {TemplateResult}
   */
  _renderBody() {
    const commentContent = this._showOriginalContent ?
      this.comment.inboundMessage :
      this.comment.content;
    return html`
      <div class="comment-body">
        <mr-comment-content
          ?hidden=${this.comment.descriptionNum}
          .content=${commentContent}
          .author=${this.comment.commenter.displayName}
          ?isDeleted=${this.comment.isDeleted}
        ></mr-comment-content>
        <div ?hidden=${this.comment.descriptionNum}>
          ${(this.comment.attachments || []).map((attachment) => html`
            <mr-attachment
              .attachment=${attachment}
              projectName=${this.comment.projectName}
              localId=${this.comment.localId}
              sequenceNum=${this.comment.sequenceNum}
              ?canDelete=${this.comment.canDelete}
            ></mr-attachment>
          `)}
        </div>
      </div>
    `;
  }

  /**
   * Displays three dot menu options available to the current user for a given
   * comment.
   * @return {Array<MenuItem>}
   */
  get _commentOptions() {
    const options = [];
    if (_canExpandDeletedComment(this.comment)) {
      const text =
        (this._isExpandedIfDeleted ? 'Hide' : 'Show') + ' comment content';
      options.push({
        text: text,
        handler: this._toggleHideDeletedComment.bind(this),
      });
      options.push({separator: true});
    }
    if (this.comment.canDelete) {
      const text =
        (this.comment.isDeleted ? 'Undelete' : 'Delete') + ' comment';
      options.push({
        text: text,
        handler: _deleteComment.bind(null, this.comment),
      });
    }
    if (this.comment.canFlag) {
      const text = (this.comment.isSpam ? 'Unflag' : 'Flag') + ' comment';
      options.push({
        text: text,
        handler: _flagComment.bind(null, this.comment),
      });
    }
    if (this.comment.inboundMessage) {
      const text =
        (this._showOriginalContent ? 'Hide' : 'Show') + ' original email';
      options.push({
        text: text,
        handler: this._toggleShowOriginalContent.bind(this),
      });
    }
    return options;
  }

  /**
   * Toggles whether the email of the user who deleted the comment should be
   * shown.
   */
  _toggleShowOriginalContent() {
    this._showOriginalContent = !this._showOriginalContent;
  }

  /**
   * Change if deleted content for a comment is shown or not.
   */
  _toggleHideDeletedComment() {
    this._isExpandedIfDeleted = !this._isExpandedIfDeleted;
  }
}

/**
 * Says whether a comment should be shown or not.
 * @param {boolean} isExpandedIfDeleted If the user has chosen to see the
 *   deleted comment.
 * @param {IssueComment} comment
 * @return {boolean} If the comment should be shown.
 */
function _shouldShowComment(isExpandedIfDeleted, comment) {
  return !comment.isDeleted || isExpandedIfDeleted;
}

/**
 * Whether the user can view additional comment options like flagging or
 * deleting.
 * @param {IssueComment} comment
 * @return {boolean}
 */
function _shouldOfferCommentOptions(comment) {
  return comment.canDelete || comment.canFlag;
}

/**
 * Whether a user has permission to view a given deleted comment.
 * @param {IssueComment} comment
 * @return {boolean}
 */
function _canExpandDeletedComment(comment) {
  return ((comment.isSpam && comment.canFlag) ||
          (comment.isDeleted && comment.canDelete));
}

/**
 * Deletes a given comment or undeletes it if it's already deleted.
 * @param {IssueComment} comment The comment to delete.
 */
async function _deleteComment(comment) {
  const issueRef = {
    projectName: comment.projectName,
    localId: comment.localId,
  };
  await prpcClient.call('monorail.Issues', 'DeleteIssueComment', {
    issueRef,
    sequenceNum: comment.sequenceNum,
    delete: comment.isDeleted === undefined,
  });
  store.dispatch(issueV0.fetchComments(issueRef));
}

/**
 * Sends a request to flag a comment as spam. Flags or unflags based on
 * the comments existing isSpam state.
 * @param {IssueComment} comment The comment to flag.
 */
async function _flagComment(comment) {
  const issueRef = {
    projectName: comment.projectName,
    localId: comment.localId,
  };
  await prpcClient.call('monorail.Issues', 'FlagComment', {
    issueRef,
    sequenceNum: comment.sequenceNum,
    flag: comment.isSpam === undefined,
  });
  store.dispatch(issueV0.fetchComments(issueRef));
}

/**
 * Finds if a given change in a comment contains issues (ie: for Blocking or
 * BlockedOn edits), then formats those issues into a list to be rendered by the
 * frontend.
 * @param {Amendment} delta
 * @param {string} projectName The project name the user is currently viewing.
 * @return {Array<{issue: Issue, text: string}>}
 */
function _issuesForAmendment(delta, projectName) {
  if (!_amendmentHasIssueRefs(delta.fieldName) ||
      !delta.newOrDeltaValue) {
    return [];
  }
  // TODO(ehmaldonado): Request the issue to check for permissions and display
  // the issue summary.
  return delta.newOrDeltaValue.split(' ').map((deltaValue) => {
    let refString = deltaValue;

    // When an issue is removed, its ID is prepended with a minus sign.
    if (refString.startsWith('-')) {
      refString = refString.substr(1);
    }
    const issueRef = issueStringToRef(refString, projectName);
    return {
      issue: {
        ...issueRef,
      },
      text: deltaValue,
    };
  });
}

/**
 * Check if a field is one of the field types that accepts issues as input.
 * @param {string} fieldName
 * @return {boolean} If the field contains issues.
 */
function _amendmentHasIssueRefs(fieldName) {
  return ISSUE_REF_FIELD_NAMES.includes(fieldName);
}

customElements.define('mr-comment', MrComment);
