// 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 {SHARED_STYLES} from 'shared/shared-styles.js';

/**
 * `<mr-upload>`
 *
 * A file uploading widget for use in adding attachments and similar things.
 *
 */
export class MrUpload extends LitElement {
  /** @override */
  static get styles() {
    return [
      SHARED_STYLES,
      css`
        :host {
          display: block;
          width: 100%;
          padding: 0.25em 4px;
          border: 1px dashed var(--chops-gray-300);
          box-sizing: border-box;
          border-radius: 8px;
          transition: background 0.2s ease-in-out,
            border-color 0.2s ease-in-out;
        }
        :host([hidden]) {
          display: none;
        }
        :host([expanded]) {
          /* Expand the drag and drop area when a file is being dragged. */
          min-height: 120px;
        }
        :host([highlighted]) {
          border-color: var(--chops-primary-accent-color);
          background: var(--chops-active-choice-bg);
        }
        input[type="file"] {
          /* We need the file uploader to be hidden but still accessible. */
          opacity: 0;
          width: 0;
          height: 0;
          position: absolute;
          top: -9999;
          left: -9999;
        }
        input[type="file"]:focus + label {
          /* TODO(zhangtiff): Find a way to either mimic native browser focus
           * styles or make focus styles more consistent. */
          box-shadow: 0 0 3px 1px hsl(193, 82%, 63%);
        }
        label.button {
          margin-right: 8px;
          padding: 0.1em 4px;
          display: inline-flex;
          width: auto;
          cursor: pointer;
          border: var(--chops-normal-border);
          margin-left: 0;
        }
        label.button i.material-icons {
          font-size: var(--chops-icon-font-size);
        }
        ul {
          display: flex;
          align-items: flex-start;
          justify-content: flex-start;
          flex-direction: column;
        }
        ul[hidden] {
          display: none;
        }
        li {
          display: inline-flex;
          align-items: center;
        }
        li i.material-icons {
          font-size: 14px;
          margin: 0;
        }
        /* TODO(zhangtiff): Create a shared Material icon button component. */
        button {
          border-radius: 50%;
          cursor: pointer;
          background: 0;
          border: 0;
          padding: 0.25em;
          margin-left: 4px;
          display: inline-flex;
          align-items: center;
          justify-content: center;
          transition: background 0.2s ease-in-out;
        }
        button:hover {
          background: var(--chops-gray-200);
        }
        .controls {
          display: flex;
          flex-direction: row;
          align-items: center;
          justify-content: flex-start;
          width: 100%;
        }
      `,
    ];
  }

  /** @override */
  render() {
    return html`
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons"
            rel="stylesheet">
      <div class="controls">
        <input id="file-uploader" type="file" multiple @change=${this._filesChanged}>
        <label class="button" for="file-uploader">
          <i class="material-icons" role="presentation">attach_file</i>Add attachments
        </label>
        Drop files here to add them (Max: 10.0 MB per comment)
      </div>
      <ul ?hidden=${!this.files || !this.files.length}>
        ${this.files.map((file, i) => html`
          <li>
            ${file.name}
            <button data-index=${i} @click=${this._removeFile}>
              <i class="material-icons">clear</i>
            </button>
          </li>
        `)}
      </ul>
    `;
  }

  /** @override */
  static get properties() {
    return {
      files: {type: Array},
      highlighted: {
        type: Boolean,
        reflect: true,
      },
      expanded: {
        type: Boolean,
        reflect: true,
      },
      _boundOnDragIntoWindow: {type: Object},
      _boundOnDragOutOfWindow: {type: Object},
      _boundOnDragInto: {type: Object},
      _boundOnDragLeave: {type: Object},
      _boundOnDrop: {type: Object},
    };
  }

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

    this.expanded = false;
    this.highlighted = false;
    this.files = [];
    this._boundOnDragIntoWindow = this._onDragIntoWindow.bind(this);
    this._boundOnDragOutOfWindow = this._onDragOutOfWindow.bind(this);
    this._boundOnDragInto = this._onDragInto.bind(this);
    this._boundOnDragLeave = this._onDragLeave.bind(this);
    this._boundOnDrop = this._onDrop.bind(this);
  }

  /** @override */
  connectedCallback() {
    super.connectedCallback();
    this.addEventListener('dragenter', this._boundOnDragInto);
    this.addEventListener('dragover', this._boundOnDragInto);

    this.addEventListener('dragleave', this._boundOnDragLeave);
    this.addEventListener('drop', this._boundOnDrop);

    window.addEventListener('dragenter', this._boundOnDragIntoWindow);
    window.addEventListener('dragover', this._boundOnDragIntoWindow);
    window.addEventListener('dragleave', this._boundOnDragOutOfWindow);
    window.addEventListener('drop', this._boundOnDragOutOfWindow);
  }

  /** @override */
  disconnectedCallback() {
    super.disconnectedCallback();

    window.removeEventListener('dragenter', this._boundOnDragIntoWindow);
    window.removeEventListener('dragover', this._boundOnDragIntoWindow);
    window.removeEventListener('dragleave', this._boundOnDragOutOfWindow);
    window.removeEventListener('drop', this._boundOnDragOutOfWindow);
  }

  reset() {
    this.files = [];
  }

  get hasAttachments() {
    return this.files.length !== 0;
  }

  async loadFiles() {
    // TODO(zhangtiff): Add preloading of files on change.
    if (!this.files || !this.files.length) return [];
    const loads = this.files.map(this._loadLocalFile);
    return await Promise.all(loads);
  }

  _onDragInto(e) {
    // Combined event handler for dragenter and dragover.
    if (!this._eventGetFiles(e).length) return;
    e.preventDefault();
    this.highlighted = true;
  }

  _onDragLeave(e) {
    // Unhighlight the drop area when the user undrops the component.
    if (!this._eventGetFiles(e).length) return;
    e.preventDefault();
    this.highlighted = false;
  }

  _onDrop(e) {
    // Add the files the user is dragging when dragging into the component.
    const files = this._eventGetFiles(e);
    if (!files.length) return;
    e.preventDefault();
    this.highlighted = false;
    this._addFiles(files);
  }

  _onDragIntoWindow(e) {
    // Expand the drop area when any file is being dragged in the window.
    if (!this._eventGetFiles(e).length) return;
    e.preventDefault();
    this.expanded = true;
  }

  _onDragOutOfWindow(e) {
    // Unexpand the component when a file is no longer being dragged.
    if (!this._eventGetFiles(e).length) return;
    e.preventDefault();
    this.expanded = false;
  }

  _eventGetFiles(e) {
    if (!e || !e.dataTransfer) return [];
    const dt = e.dataTransfer;

    if (dt.items && dt.items.length) {
      const filteredItems = [...dt.items].filter(
          (item) => item.kind === 'file');
      return filteredItems.map((item) => item.getAsFile());
    }

    return [...dt.files];
  }

  _loadLocalFile(f) {
    // The FileReader API only accepts callbacks for asynchronous handling,
    // so it's easier to use Promises here. But by wrapping this logic
    // in a Promise, we can use async/await in outer code.
    return new Promise((resolve, reject) => {
      const r = new FileReader();
      r.onloadend = () => {
        resolve({filename: f.name, content: btoa(r.result)});
      };
      r.onerror = () => {
        reject(r.error);
      };

      r.readAsBinaryString(f);
    });
  }

  /**
   * @param {Event} e
   * @fires CustomEvent#change
   * @private
   */
  _filesChanged(e) {
    const input = e.currentTarget;
    if (!input.files) return;
    this._addFiles(input.files);
    this.dispatchEvent(new CustomEvent('change'));
  }

  _addFiles(newFiles) {
    if (!newFiles) return;
    // Spread files to convert it from a FileList to an Array.
    const files = [...newFiles].filter((f1) => {
      const matchingFile = this.files.some((f2) => this._filesMatch(f1, f2));
      return !matchingFile;
    });

    this.files = this.files.concat(files);
  }

  _filesMatch(a, b) {
    // NOTE: This function could return a false positive if two files have the
    // exact same name, lastModified time, size, and type but different
    // content. This is extremely unlikely, however.
    return a.name === b.name && a.lastModified === b.lastModified &&
      a.size === b.size && a.type === b.type;
  }

  _removeFile(e) {
    const target = e.currentTarget;

    // This should always be an int.
    const index = Number.parseInt(target.dataset.index);
    if (index < 0 || index >= this.files.length) return;

    this.files.splice(index, 1);

    // Trigger an update.
    this.files = [...this.files];
  }
}
customElements.define('mr-upload', MrUpload);
