// 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 {html, css} from 'lit-element';
import deepEqual from 'deep-equal';

import 'elements/chops/chops-checkbox/chops-checkbox.js';
import {store} from 'reducers/base.js';
import * as issueV0 from 'reducers/issueV0.js';
import * as userV0 from 'reducers/userV0.js';
import {prpcClient} from 'prpc-client-instance.js';
import {MrIssueHotlistsDialog} from './mr-issue-hotlists-dialog';

/**
 * `<mr-update-issue-hotlists-dialog>`
 *
 * Displays a dialog with the current hotlists's issues allowing the user to
 * update which hotlists the issues are a member of.
 */
export class MrUpdateIssueDialog extends MrIssueHotlistsDialog {
  /** @override */
  static get styles() {
    return [
      ...super.styles,
      css`
        input[type="checkbox"] {
          width: auto;
          height: auto;
        }
        button.toggle {
          background: none;
          color: hsl(240, 100%, 40%);
          border: 0;
          width: 100%;
          padding: 0.25em 0;
          text-align: left;
        }
        button.toggle:hover {
          cursor: pointer;
          text-decoration: underline;
        }
        label, chops-checkbox {
          display: flex;
          line-height: 200%;
          align-items: center;
          width: 100%;
          text-align: left;
          font-weight: normal;
          padding: 0.25em 8px;
          box-sizing: border-box;
        }
        label input[type="checkbox"] {
          margin-right: 8px;
        }
        .discard-button {
          margin-right: 16px;
        }
        .edit-actions {
          width: 100%;
          margin: 0.5em 0;
          text-align: right;
        }
        .input-grid {
          align-items: center;
        }
        .input-grid > input {
          width: 200px;
          max-width: 100%;
        }
      `,
    ];
  }

  /** @override */
  renderHeader() {
    return html`
      <h3 class="medium-heading">Add issue to hotlists</h3>
    `;
  }

  /** @override */
  renderContent() {
    return html`
      ${this.renderFilter()}
      <form id="issueHotlistsForm">
        ${this.renderHotlists()}
        <h3 class="medium-heading">Create new hotlist</h3>
        <div class="input-grid">
          <label for="newHotlistName">New hotlist name:</label>
          <input type="text" name="newHotlistName">
        </div>
        ${this.renderError()}
        <div class="edit-actions">
          <chops-button
            class="de-emphasized discard-button"
            ?disabled=${this.disabled}
            @click=${this.discard}
          >
            Discard
          </chops-button>
          <chops-button
            class="emphasized"
            ?disabled=${this.disabled}
            @click=${this.save}
          >
            Save changes
          </chops-button>
        </div>
      </form>
    `;
  }

  /** @override */
  renderFilteredHotlist(hotlist) {
    return html`
      <chops-checkbox
        class="hotlist"
        title=${this._checkboxTitle(hotlist, this.issueHotlists)}
        data-hotlist-name="${hotlist.name}"
        ?checked=${this.hotlistsToAdd.has(hotlist.name)}
        @checked-change=${this._targetHotlistChecked}
      >
        ${hotlist.name}
      </chops-checkbox>`;
  }

  /** @override */
  static get properties() {
    return {
      ...super.properties,
      viewedIssueRef: {type: Object},
      issueHotlists: {type: Array},
      user: {type: Object},
      hotlistsToAdd: {
        type: Object,
        hasChanged(newVal, oldVal) {
          return !deepEqual(newVal, oldVal);
        },
      },
    };
  }

  /** @override */
  stateChanged(state) {
    super.stateChanged(state);
    this.viewedIssueRef = issueV0.viewedIssueRef(state);
    this.user = userV0.currentUser(state);
  }

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

    /** The list of Hotlists attached to the issueRefs. */
    this.issueHotlists = [];

    /** The Set of Hotlist names that the Issues will be added to. */
    this.hotlistsToAdd = this._initializeHotlistsToAdd();
  }

  /** @override */
  reset() {
    const form = this.shadowRoot.querySelector('#issueHotlistsForm');
    form.reset();
    // LitElement's hasChanged needs an assignment to verify Set objects.
    // https://lit-element.polymer-project.org/guide/properties#haschanged
    this.hotlistsToAdd = this._initializeHotlistsToAdd();
    super.reset();
  }

  /**
   * An alias to the close method.
   */
  discard() {
    this.close();
  }

  /**
   * Saves all changes that were found in the dialog and issues async requests
   * to update the issues.
   * @fires Event#saveSuccess
   */
  async save() {
    const changes = this.changes;
    const issueRefs = this.issueRefs;
    const viewedRef = this.viewedIssueRef;

    if (!issueRefs || !changes) return;

    // TODO(https://crbug.com/monorail/7778): Use action creators.
    const promises = [];
    if (changes.added && changes.added.length) {
      promises.push(prpcClient.call(
          'monorail.Features', 'AddIssuesToHotlists', {
            hotlistRefs: changes.added,
            issueRefs,
          },
      ));
    }
    if (changes.removed && changes.removed.length) {
      promises.push(prpcClient.call(
          'monorail.Features', 'RemoveIssuesFromHotlists', {
            hotlistRefs: changes.removed,
            issueRefs,
          },
      ));
    }
    if (changes.created) {
      promises.push(prpcClient.call(
          'monorail.Features', 'CreateHotlist', {
            name: changes.created.name,
            summary: changes.created.summary,
            issueRefs,
          },
      ));
    }

    try {
      await Promise.all(promises);

      // Refresh the viewed issue's hotlists only if there is a viewed issue.
      if (viewedRef) {
        const viewedIssueWasUpdated = issueRefs.find((ref) =>
          ref.projectName === viewedRef.projectName &&
          ref.localId === viewedRef.localId);
        if (viewedIssueWasUpdated) {
          store.dispatch(issueV0.fetchHotlists(viewedRef));
        }
      }
      store.dispatch(userV0.fetchHotlists({userId: this.user.userId}));
      this.dispatchEvent(new Event('saveSuccess'));
      this.close();
    } catch (error) {
      this.error = error.description;
    }
  }

  /**
   * Returns whether a given hotlist matches any of the given issue's hotlists.
   * @param {Hotlist} hotlist Hotlist to look for.
   * @param {Array<Hotlist>} issueHotlists Issue's hotlists to compare to.
   * @return {boolean}
   */
  _issueInHotlist(hotlist, issueHotlists) {
    return issueHotlists.some((issueHotlist) => {
      // TODO(https://crbug.com/monorail/7451): use `===`.
      return (hotlist.ownerRef.userId == issueHotlist.ownerRef.userId &&
        hotlist.name === issueHotlist.name);
    });
  }

  /**
   * Get a Set of Hotlists to add the Issues to based on the
   * Get the initial Set of Hotlists that Issues will be added to. Calculated
   * using userHotlists and issueHotlists.
   * @return {!Set<string>}
   */
  _initializeHotlistsToAdd() {
    const userHotlistsInIssueHotlists = this.userHotlists.reduce(
        (acc, hotlist) => {
          if (this._issueInHotlist(hotlist, this.issueHotlists)) {
            acc.push(hotlist.name);
          }
          return acc;
        }, []);
    return new Set(userHotlistsInIssueHotlists);
  }

  /**
   * Gets the checkbox title, depending on the checked state.
   * @param {boolean} isChecked Whether the input is checked.
   * @return {string}
   */
  _getCheckboxTitle(isChecked) {
    return (isChecked ? 'Remove issue from' : 'Add issue to') + ' this hotlist';
  }

  /**
   * The checkbox title for the issue, shown on hover and for a11y.
   * @param {Hotlist} hotlist Hotlist to look for.
   * @param {Array<Hotlist>} issueHotlists Issue's hotlists to compare to.
   * @return {string}
   */
  _checkboxTitle(hotlist, issueHotlists) {
    return this._getCheckboxTitle(this._issueInHotlist(hotlist, issueHotlists));
  }

  /**
   * Handles when the target Hotlist chops-checkbox has been checked.
   * @param {Event} e
   */
  _targetHotlistChecked(e) {
    const hotlistName = e.target.dataset.hotlistName;
    const currentHotlistsToAdd = new Set(this.hotlistsToAdd);
    if (hotlistName && e.detail.checked) {
      currentHotlistsToAdd.add(hotlistName);
    } else {
      currentHotlistsToAdd.delete(hotlistName);
    }
    // LitElement's hasChanged needs an assignment to verify Set objects.
    // https://lit-element.polymer-project.org/guide/properties#haschanged
    this.hotlistsToAdd = currentHotlistsToAdd;
    e.target.title = this._getCheckboxTitle(e.target.checked);
  }

  /**
   * Gets the changes between the added, removed, and created hotlists .
   */
  get changes() {
    const changes = {
      added: [],
      removed: [],
    };
    const form = this.shadowRoot.querySelector('#issueHotlistsForm');
    this.userHotlists.forEach((hotlist) => {
      const issueInHotlist = this._issueInHotlist(hotlist, this.issueHotlists);
      if (issueInHotlist && !this.hotlistsToAdd.has(hotlist.name)) {
        changes.removed.push({
          name: hotlist.name,
          owner: hotlist.ownerRef,
        });
      } else if (!issueInHotlist && this.hotlistsToAdd.has(hotlist.name)) {
        changes.added.push({
          name: hotlist.name,
          owner: hotlist.ownerRef,
        });
      }
    });
    if (form.newHotlistName.value) {
      changes.created = {
        name: form.newHotlistName.value,
        summary: 'Hotlist created from issue.',
      };
    }
    return changes;
  }
}

customElements.define('mr-update-issue-hotlists-dialog', MrUpdateIssueDialog);
