/**
 * @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: {},
 *     width: 256,
 *     height: 256,
 *     fps: 30,
 *   }
 * <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);
