/**
 * @module skottie-config-sk
 * @description <h2><code>skottie-config-sk</code></h2>
 *
 * <p>
 *   A dialog for configuring how to render a lottie file.
 * </p>
 *
 * <p>
 *   The form of the 'state' property looks like a serialized UploadRequest:
 * </p>
 * <pre>
 *   {
 *     filename: 'foo.json',
 *     lottie: {},
 *     assetsZip: 'data:application/zip;base64,...'
 *     assetsFileName: 'assets.zip'
 *   }
 * <pre>
 *
 * @evt skottie-selected - This event is generated when the user presses Go.
 *         The updated state, width, and height is available in the event detail.
 *         There is also an indication if the lottie file was changed.
 *
 * @evt cancelled - This event is generated when the user presses Cancel.
 *
 */
import 'elements-sk/styles/buttons'
import { errorMessage } from 'elements-sk/errorMessage'
import { html, render } from 'lit-html'
import { $$ } from 'common-sk/modules/dom'

const DEFAULT_SIZE = 128;

const allowZips = window.location.hostname === "skottie-internal.skia.org" ||
                  window.location.hostname === "localhost";

const cancelButton = (ele) => ele._hasCancel() ? html`<button id=cancel @click=${ele._cancel}>Cancel</button>` : '';

const template = (ele) => html`
  <div ?hidden=${!allowZips}>
    We support 3 types of uploads:
    <ul>
      <li>A plain JSON file.</li>
      <li>A JSON file with a zip file of assets (e.g. images) used by the animation.</li>
      <li>
        A zip file produced by lottiefiles.com
        (<a href="https://lottiefiles.com/1187-puppy-run">example</a>)
        with a JSON file in the top level and an images/ directory.
      </li>
    </ul>
  </div>
  <label class=file>Lottie file to upload
    <input type=file name=file id=file @change=${ele._onFileChange}/>
  </label>
  <div class="filename ${ele._state.filename ? '' : 'empty'}">
    ${ele._state.filename ? ele._state.filename : 'No file selected.'}
  </div>
  <label class=file ?hidden=${!allowZips}>Optional Asset Folder (.zip)
    <input type=file name=folder id=folder @change=${ele._onFolderChange}/>
  </label>
  <div class="filename ${ele._state.assetsFilename ? '' : 'empty'}" ?hidden=${!allowZips}>
    ${ele._state.assetsFilename ? ele._state.assetsFilename : 'No asset folder selected.'}
  </div>
  <label class=number>
    <input type=number id=width .value=${ele._width} required /> Width (px)
  </label>
  <label class=number>
    <input type=number id=height .value=${ele._height} required /> Height (px)
  </label>
  <div>
    0 for width/height means use the default from the animation
  </div>
  <div class=warning ?hidden=${ele._warningHidden()}>
    <p>
    The width or height of your file exceeds 1024, which may not fit on the screen.
    Press a 'Rescale' button to fix the dimensions while preserving the aspect ratio.
    </p>
    <div>
      <button @click=${(e) => ele._rescale(1024)}>Rescale to 1024</button>
      <button @click=${(e) => ele._rescale(512)}>Rescale to 512</button>
      <button @click=${(e) => ele._rescale(128)}>Rescale to 128</button>
    </div>
  </div>
  <div id=dialog-buttons>
    ${cancelButton(ele)}
    <button class=action ?disabled=${ele._readyToGo()} @click=${ele._go}>Go</button>
  </div>
`;

class SkottieConfigSk extends HTMLElement {
  constructor() {
    super();
    this._state = {
      filename: '',
      lottie: null,
      assetsZip: '',
      assetsFileName: '',
    };
    this._width = DEFAULT_SIZE;
    this._height = DEFAULT_SIZE;
    this._fileChanged = false;
    this._starting_state = Object.assign({}, this._state);
  }

  connectedCallback() {
    this._render();
    this.addEventListener('input', this._inputEvent);
  }

  disconnectedCallback() {
    this.removeEventListener('input', this._inputEvent);
  }

  /** @prop height {Number} Selected height for animation. */
  get height() { return this._height; }
  set height(val) {
    this._height= +val;
    this._render();
  }

  /** @prop state {string} Object that describes the state of the config dialog. */
  get state() { return this._state; }
  set state(val) {
    this._state = Object.assign({}, val);
    this._starting_state = Object.assign({}, this._state);
    this._render();
  }

  /** @prop width {Number} Selected width for animation. */
  get width() { return this._width; }
  set width(val) {
    this._width = +val;
    this._render();
  }

  _hasCancel() {
     return !!this._starting_state.lottie;
  }

  _readyToGo() {
    return !this._state.filename && (this._state.lottie || this._state.assetsZip);
  }

  _onFileChange(e) {
    this._fileChanged = true;
    const toLoad = e.target.files[0];
    const reader = new FileReader();
    if (toLoad.name.endsWith('.json')) {
      reader.addEventListener('load', () => {
        let parsed = {};
        try {
          parsed = JSON.parse(reader.result);
        }
        catch(error) {
          errorMessage(`Not a valid JSON file: ${error}`);
          return;
        }
        this._state.lottie = parsed;
        this._state.filename = toLoad.name;
        this._width = parsed.w || DEFAULT_SIZE;
        this._height = parsed.h || DEFAULT_SIZE;
        this._render();
      });
      reader.addEventListener('error', () => {
        errorMessage('Failed to load.');
      });
      reader.readAsText(toLoad);
    } else if (allowZips && toLoad.name.endsWith('.zip')) {
      reader.addEventListener('load', () => {
        this._state.lottie = '';
        this._state.assetsZip = reader.result;
        this._state.filename = toLoad.name;

        this._width = DEFAULT_SIZE;
        this._height = DEFAULT_SIZE;
        this._render();
      });
      reader.addEventListener('error', () => {
        errorMessage('Failed to load '+ toLoad.name);
      });
      reader.readAsDataURL(toLoad);
    } else {
      let msg = `Bad file type ${toLoad.name}, only .json and .zip supported`;
      if (!allowZips) {
        msg = `Bad file type ${toLoad.name}, only .json supported`;
      }
      errorMessage(msg);
      this._state.filename = '';
      this._state.lottie = '';
    }
  }

  _onFolderChange(e) {
    this._fileChanged = true;
    const toLoad = e.target.files[0];
    const reader = new FileReader();
    reader.addEventListener('load', () => {
      this._state.assetsZip = reader.result;
      this._state.assetsFilename = toLoad.name;
      this._render();
    });
    reader.addEventListener('error', () => {
      errorMessage('Failed to load '+ toLoad.name);
    });
    reader.readAsDataURL(toLoad);
  }

  _rescale(n) {
    let max = Math.max(this._width, this._height);
    if (max <= n) {
      return
    }
    this._width = Math.floor(this._width * n / max);
    this._height = Math.floor(this._height * n / max);
    this._render();
  }

  _warningHidden() {
    return this._width <= 1024 && this._width <= 1024;
  }

  _updateState() {
    this._width = +$$('#width', this).value;
    this._height = +$$('#height', this).value;
  }

  _go() {
    this._updateState();
    this.dispatchEvent(new CustomEvent('skottie-selected', { detail: {
      'state' : this._state,
      'fileChanged': this._fileChanged,
      'width' : this._width,
      'height': this._height,
    }, bubbles: true }));
  }

  _cancel() {
    this.dispatchEvent(new CustomEvent('cancelled', { bubbles: true }));
  }

  _inputEvent() {
    this._updateState();
    this._render();
  }

  _render() {
    render(template(this), this, {eventContext: this});
  }
};

window.customElements.define('skottie-config-sk', SkottieConfigSk);
