// 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, css} from 'lit-element';
import page from 'page';
import qs from 'qs';
import Mousetrap from 'mousetrap';

import {store, connectStore} from 'reducers/base.js';
import * as issueV0 from 'reducers/issueV0.js';
import * as projectV0 from 'reducers/projectV0.js';
import 'elements/chops/chops-dialog/chops-dialog.js';
import {issueRefToString} from 'shared/convertersV0.js';


const SHORTCUT_DOC_GROUPS = [
  {
    title: 'Issue list',
    keyDocs: [
      {
        keys: ['k', 'j'],
        tip: 'up/down in the list',
      },
      {
        keys: ['o', 'Enter'],
        tip: 'open the current issue',
      },
      {
        keys: ['Shift-O'],
        tip: 'open issue in new tab',
      },
      {
        keys: ['x'],
        tip: 'select the current issue',
      },
    ],
  },
  {
    title: 'Issue details',
    keyDocs: [
      {
        keys: ['k', 'j'],
        tip: 'prev/next issue in list',
      },
      {
        keys: ['u'],
        tip: 'up to issue list',
      },
      {
        keys: ['r'],
        tip: 'reply to current issue',
      },
      {
        keys: ['Ctrl+Enter', '\u2318+Enter'],
        tip: 'save issue reply (submit issue on issue filing page)',
      },
    ],
  },
  {
    title: 'Anywhere',
    keyDocs: [
      {
        keys: ['/'],
        tip: 'focus on the issue search field',
      },
      {
        keys: ['c'],
        tip: 'compose a new issue',
      },
      {
        keys: ['s'],
        tip: 'star the current issue',
      },
      {
        keys: ['?'],
        tip: 'show this help dialog',
      },
    ],
  },
];

/**
 * `<mr-keystrokes>`
 *
 * Adds keybindings for Monorail, including a dialog for showing keystrokes.
 * @extends {LitElement}
 */
export class MrKeystrokes extends connectStore(LitElement) {
  /** @override */
  static get styles() {
    return css`
      h2 {
        margin-top: 0;
        display: flex;
        justify-content: space-between;
        font-weight: normal;
        border-bottom: 2px solid white;
        font-size: var(--chops-large-font-size);
        padding-bottom: 0.5em;
      }
      .close-button {
        border: 0;
        background: 0;
        text-decoration: underline;
        cursor: pointer;
      }
      .keyboard-help {
        display: flex;
        align-items: flex-start;
        justify-content: space-around;
        flex-direction: row;
        border-bottom: 2px solid white;
        flex-wrap: wrap;
      }
      .keyboard-help-section {
        width: 32%;
        display: grid;
        grid-template-columns: 40% 60%;
        padding-bottom: 1em;
        grid-gap: 4px;
        min-width: 300px;
      }
      .help-title {
        font-weight: bold;
      }
      .key-shortcut {
        text-align: right;
        padding-right: 8px;
        font-weight: bold;
        margin: 2px;
      }
      kbd {
        background: var(--chops-gray-200);
        padding: 2px 8px;
        border-radius: 2px;
        min-width: 28px;
      }
    `;
  }

  /** @override */
  render() {
    return html`
      <chops-dialog ?opened=${this._opened}>
        <h2>
          Issue tracker keyboard shortcuts
          <button class="close-button" @click=${this._closeDialog}>
            Close
          </button>
        </h2>
        <div class="keyboard-help">
          ${this._shortcutDocGroups.map((group) => html`
            <div class="keyboard-help-section">
              <span></span><span class="help-title">${group.title}</span>
              ${group.keyDocs.map((keyDoc) => html`
                <span class="key-shortcut">
                  ${keyDoc.keys.map((key, i) => html`
                    <kbd>${key}</kbd>
                    <span
                      class="key-separator"
                      ?hidden=${i === keyDoc.keys.length - 1}
                    > / </span>
                  `)}:
                </span>
                <span class="key-tip">${keyDoc.tip}</span>
              `)}
            </div>
          `)}
        </div>
        <p>
          Note: Only signed in users can star issues or add comments, and
          only project members can select issues for bulk edits.
        </p>
      </chops-dialog>
    `;
  }

  /** @override */
  static get properties() {
    return {
      issueEntryUrl: {type: String},
      issueId: {type: Number},
      _projectName: {type: String},
      queryParams: {type: Object},
      _fetchingIsStarred: {type: Boolean},
      _isStarred: {type: Boolean},
      _issuePermissions: {type: Array},
      _opened: {type: Boolean},
      _shortcutDocGroups: {type: Array},
      _starringIssues: {type: Object},
    };
  }

  /** @override */
  constructor() {
    super();

    this._shortcutDocGroups = SHORTCUT_DOC_GROUPS;
    this._opened = false;
    this._starringIssues = new Map();
    this._projectName = undefined;
    this._issuePermissions = [];
    this.issueId = undefined;
    this.queryParams = undefined;
    this.issueEntryUrl = undefined;

    this._page = page;
  }

  /** @override */
  stateChanged(state) {
    this._projectName = projectV0.viewedProjectName(state);
    this._issuePermissions = issueV0.permissions(state);

    const starredIssues = issueV0.starredIssues(state);
    this._isStarred = starredIssues.has(issueRefToString(this._issueRef));
    this._fetchingIsStarred = issueV0.requests(state).fetchIsStarred.requesting;
    this._starringIssues = issueV0.starringIssues(state);
  }

  /** @override */
  updated(changedProperties) {
    if (changedProperties.has('_projectName') ||
        changedProperties.has('issueEntryUrl')) {
      this._bindProjectKeys(this._projectName, this.issueEntryUrl);
    }
    if (changedProperties.has('_projectName') ||
        changedProperties.has('issueId') ||
        changedProperties.has('_issuePermissions') ||
        changedProperties.has('queryParams')) {
      this._bindIssueDetailKeys(this._projectName, this.issueId,
          this._issuePermissions, this.queryParams);
    }
  }

  /** @override */
  disconnectedCallback() {
    super.disconnectedCallback();
    this._unbindProjectKeys();
    this._unbindIssueDetailKeys();
  }

  /** @private */
  get _isStarring() {
    const requestKey = issueRefToString(this._issueRef);
    if (this._starringIssues.has(requestKey)) {
      return this._starringIssues.get(requestKey).requesting;
    }
    return false;
  }

  /** @private */
  get _issueRef() {
    return {
      projectName: this._projectName,
      localId: this.issueId,
    };
  }

  /** @private */
  _toggleDialog() {
    this._opened = !this._opened;
  }

  /** @private */
  _openDialog() {
    this._opened = true;
  }

  /** @private */
  _closeDialog() {
    this._opened = false;
  }

  /**
   * @param {string} projectName
   * @param {string} issueEntryUrl
   * @fires CustomEvent#focus-search
   * @private
   */
  _bindProjectKeys(projectName, issueEntryUrl) {
    this._unbindProjectKeys();

    if (!projectName) return;

    issueEntryUrl = issueEntryUrl || `/p/${projectName}/issues/entry`;

    Mousetrap.bind('/', (e) => {
      e.preventDefault();
      // Focus search.
      this.dispatchEvent(new CustomEvent('focus-search',
          {composed: true, bubbles: true}));
    });

    Mousetrap.bind('?', () => {
      // Toggle key help.
      this._toggleDialog();
    });

    Mousetrap.bind('esc', () => {
      // Close key help dialog if open.
      this._closeDialog();
    });

    Mousetrap.bind('c', () => this._page(issueEntryUrl));
  }

  /** @private */
  _unbindProjectKeys() {
    Mousetrap.unbind('/');
    Mousetrap.unbind('?');
    Mousetrap.unbind('esc');
    Mousetrap.unbind('c');
  }

  /**
   * @param {string} projectName
   * @param {string} issueId
   * @param {Array<string>} issuePermissions
   * @param {Object} queryParams
   * @private
   */
  _bindIssueDetailKeys(projectName, issueId, issuePermissions, queryParams) {
    this._unbindIssueDetailKeys();

    if (!projectName || !issueId) return;

    const projectHomeUrl = `/p/${projectName}`;

    const queryString = qs.stringify(queryParams);

    // TODO(zhangtiff): Update these links when mr-flipper's async request
    // finishes.
    const prevUrl = `${projectHomeUrl}/issues/detail/previous?${queryString}`;
    const nextUrl = `${projectHomeUrl}/issues/detail/next?${queryString}`;
    const canComment = issuePermissions.includes('addissuecomment');
    const canStar = issuePermissions.includes('setstar');

    // Previous issue in list.
    Mousetrap.bind('k', () => this._page(prevUrl));

    // Next issue in list.
    Mousetrap.bind('j', () => this._page(nextUrl));

    // Back to list.
    Mousetrap.bind('u', () => this._backToList());

    if (canComment) {
      // Navigate to the form to make changes.
      Mousetrap.bind('r', () => this._jumpToEditForm());
    }

    if (canStar) {
      Mousetrap.bind('s', () => this._starIssue());
    }
  }

  /**
   * Navigates back to the issue list page.
   * @private
   */
  _backToList() {
    const params = {...this.queryParams,
      cursor: issueRefToString(this._issueRef)};
    const queryString = qs.stringify(params);
    if (params['hotlist_id']) {
      // Because hotlist URLs require a server look up to be built from a
      // hotlist ID, we have to route the request through an extra endpoint
      // that redirects to the appropriate hotlist.
      const listUrl = `/p/${this._projectName}/issues/detail/list?${
        queryString}`;
      this._page(listUrl);

      // TODO(crbug.com/monorail/6341): Switch to using the new hotlist URL once
      // hotlists have migrated.
      // this._page(`/hotlists/${params['hotlist_id']}`);
    } else {
      delete params.id;
      const listUrl = `/p/${this._projectName}/issues/list?${queryString}`;
      this._page(listUrl);
    }
  }

  /**
   * Scrolls the user to the issue editing form when they press
   * the 'r' key.
   * @private
   */
  _jumpToEditForm() {
    // Force a hash change even the hash is already makechanges.
    if (window.location.hash.toLowerCase() === '#makechanges') {
      window.location.hash = ' ';
    }
    window.location.hash = '#makechanges';
  }

  /**
   * Stars the current issue the user is viewing on the issue detail page.
   * @private
   */
  _starIssue() {
    if (!this._fetchingIsStarred && !this._isStarring) {
      const newIsStarred = !this._isStarred;

      store.dispatch(issueV0.star(this._issueRef, newIsStarred));
    }
  }


  /** @private */
  _unbindIssueDetailKeys() {
    Mousetrap.unbind('k');
    Mousetrap.unbind('j');
    Mousetrap.unbind('u');
    Mousetrap.unbind('r');
    Mousetrap.unbind('s');
  }
}

customElements.define('mr-keystrokes', MrKeystrokes);
