/**
 * @module skottie-sk
 * @description <h2><code>skottie-sk</code></h2>
 *
 * <p>
 *   The main application element for skottie.
 * </p>
 *
 */
import '../skottie-config-sk'
import '../skottie-player-sk'
import 'elements-sk/collapse-sk'
import 'elements-sk/error-toast-sk'
import { $$ } from 'common-sk/modules/dom'
import { SKIA_VERSION } from '../../build/version.js'
import { errorMessage } from 'elements-sk/errorMessage'
import { html, render } from 'lit-html'
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow'
import { setupListeners, onUserEdit, reannotate} from '../lottie-annotations'

const JSONEditor = require('jsoneditor/dist/jsoneditor-minimalist.js');
const bodymovin = require('lottie-web/build/player/lottie.min.js');

const DIALOG_MODE = 1;
const LOADING_MODE = 2;
const LOADED_MODE = 3;

const displayDialog = (ele) => html`
<skottie-config-sk state=${ele._state}></skottie-config-sk>
`;

const skottiePlayer = (ele) => html`
<skottie-player-sk paused width=${ele._state.width} height=${ele._state.height}>
</skottie-player-sk>

<figcaption>
  skottie-wasm
</figcaption>`;

const livePreview = (ele) => {
  if (ele._hasEdits) {
    return html`
<figure>
  <div id=live title=live-preview
       style='width: ${ele._state.width}px; height: ${ele._state.height}px'></div>
  <figcaption>Preview [lottie-web]</figcaption>
</figure>`;
  } else {
    return '';
  }
}

const iframeDirections = (ele) => {
  return `<iframe width="${ele._state.width}" height="${ele._state.height}" src="${window.location.origin}/e/${ele._hash}" scrolling=no>`;
}

const inlineDirections = (ele) => {
  return `<skottie-inline-sk width="${ele._state.width}" height="${ele._state.height}" src="${window.location.origin}/_/j/${ele._hash}"></skottie-inline-sk>`;
}

const displayLoaded = (ele) => html`
<button class=edit-config @click=${ ele._startEdit}>${ele._state.filename} ${ele._state.width}x${ele._state.height} ${ele._state.fps} fps ...</button>
<button @click=${ele._rewind}>Rewind</button>
<button id=playpause @click=${ele._playpause}>Pause</button>
<button ?hidden=${!ele._hasEdits} @click=${ele._applyEdits}>Apply Edits</button>
<div class=download>
  <a target=_blank download=${ele._state.filename} href=${ele._downloadUrl}>
    JSON
  </a>
  ${ele._hasEdits? '(without edits)': ''}
</div>
<button @click=${ele._toggleEmbed}>Embed</button>
<collapse-sk id=embed closed>
  <p>
    <label>Embed using an iframe: <input size=120 value="${iframeDirections(ele)}" scrolling=no></label>
  </p>
  <p>
    <label>Embed on skia.org: <input size=140 value="${inlineDirections(ele)}" scrolling=no></label>
  </p>
</collapse-sk>
<section class=figures>
  <figure>
    ${skottiePlayer(ele)}
  </figure>
  <figure>
    <div id=container title=lottie-web
         style='width: ${ele._state.width}px; height: ${ele._state.height}px'></div>
    <figcaption>lottie-web (${bodymovin.version})</figcaption>
  </figure>
  ${livePreview(ele)}
</section>

<section class=editor>
  <div id=json_editor></div>
</section>
`;

const displayLoading = (ele) => html`
  <div class=loading>
    <spinner-sk active></spinner-sk><span>Loading...</span>
  </div>
`;

// pick the right part of the UI to display based on ele._ui.
const pick = (ele) => {
  switch (ele._ui) {
    case DIALOG_MODE:
      return displayDialog(ele);
    case LOADING_MODE:
      return displayLoading(ele);
    case LOADED_MODE:
      return displayLoaded(ele);
  }
};

const redir = (ele) => {
  if (window.location.hostname != 'skottie-internal.skia.org') {
    return html`<div>Googlers should use <a href="https://skottie-internal.skia.org">skottie-internal.skia.org</a>.</div>`;
  } else {
    return html``;
  }
};

const template = (ele) => html`
<header>
  <h2>Skottie</h2><span><a href='https://skia.googlesource.com/skia/+/${SKIA_VERSION}'>${SKIA_VERSION.slice(0, 7)}</a></span>
</header>
<main>
  ${pick(ele)}
</main>
<footer>
  <error-toast-sk></error-toast-sk>
  ${redir(ele)}
</footer>
`;

window.customElements.define('skottie-sk', class extends HTMLElement {
  constructor() {
    super();
    this._state = {
      filename: '',
      lottie: null,
      width: 256,
      height: 256,
      fps: 30,
    };
    // One of 'dialog', 'loading', or 'loaded'
    this._ui = DIALOG_MODE;
    this._hash = '';
    this._lottie = null;
    this._live = null;
    this._playing = true;
    this._downloadUrl = null; // The URL to download the lottie JSON from.
    this._editor = null;
    this._editorLoaded = false;
    this._hasEdits = false;

    this._duration = 0; // _duration = 0 is a sentinel value for "player not loaded yet"

    // The wasm animation computes how long it has been since it started and
    // use arithmetic to figure out where to seek (i.e. which frame to draw).
    this._firstFrameTime = null;
     // used for remembering where we were in the animation when paused.
    this._wasmTimePassed = 0;
  }

  connectedCallback() {
    this._reflectFromURL();
    this.addEventListener('skottie-selected', this)
    this.addEventListener('cancelled', this)
    window.addEventListener('popstate', this)
    this._render();

    // Start a continous animation loop.
    const drawFrame = () => {
      window.requestAnimationFrame(drawFrame);

      // Elsewhere, the _firstFrameTime is set to null to restart
      // the animation. If null, we assume the user hit re-wind
      // and restart both the Skottie animation and the lottie-web one.
      // This avoids the (small) boot-up lag while we wait for the
      // skottie animation to be parsed and loaded.
      if (!this._firstFrameTime && this._playing) {
        this._firstFrameTime = Date.now();
      }
      if (this._playing && this._duration > 0) {
        let progress = (Date.now() - this._firstFrameTime) % this._duration;

        // If we want to have synchronized playing, it's best to force
        // all players to draw the same frame rather than letting them play
        // on their own timeline.
        let player = this.querySelector('skottie-player-sk');
        player && player.seek(progress / this._duration);

        this._lottie.goToAndStop(progress);
        this._live && this._live.goToAndStop(progress);
      }
    }

    window.requestAnimationFrame(drawFrame);
  }

  disconnectedCallback() {
    this.removeEventListener('skottie-selected', this)
    this.removeEventListener('cancelled', this)
  }

  attributeChangedCallback(name, oldValue, newValue) {
    this._render();
  }

  _initializePlayer() {
    let player = this.querySelector('skottie-player-sk');
    player.initialize({
                        width:  this._state.width,
                        height: this._state.height,
                        lottie: this._state.lottie,
                      }).then(() => {
                        this._duration = player.duration();
                      });
  }

  _reflectFromURL() {
    // Check URL.
    let match = window.location.pathname.match(/\/([a-zA-Z0-9]+)/);
    if (!match) {
      // Make this the hash of the lottie file you want to play on startup.
      this._hash = '1112d01d28a776d777cebcd0632da15b'; // gear.json
    } else {
      this._hash = match[1];
    }
    this._ui = LOADING_MODE;
    this._render();
    // Run this on the next micro-task to allow mocks to be set up if needed.
    setTimeout(() => {
      fetch(`/_/j/${this._hash}`, {
        credentials: 'include',
      }).then(jsonOrThrow).then(json => {
        this._state = json;
        this._ui = LOADED_MODE;
        this._render();
        this._initializePlayer();
      }).catch((msg) => {
        errorMessage(msg);
        window.history.pushState(null, '', '/');
        this._ui = DIALOG_MODE;
        this._render();
      });
    });

  }

  _applyEdits() {
    if (!this._editor || !this._editorLoaded || !this._hasEdits) {
      return;
    }
    this._state.lottie = this._editor.get();
    this._upload();
  }

  _startEdit() {
    this._ui = DIALOG_MODE;
    this._render();
  }

  _upload() {
    // POST the JSON along with options to /_/upload
    this._hash = '';
    this._hasEdits = false;
    this._editorLoaded = false;
    this._editor = null;
    // Clean up the old animation and other wasm objects
    this._render();
    fetch('/_/upload', {
      credentials: 'include',
      body: JSON.stringify(this._state),
      headers: {
        'Content-Type': 'application/json'
      },
      method: 'POST',
    }).then(jsonOrThrow).then(json => {
      // Should return with the hash.
      this._ui = LOADED_MODE;
      this._hash = json.hash;
      window.history.pushState(null, '', '/' + this._hash);
      this._render();
      this._initializePlayer();

      // Re-sync all players
      this._rewind();
    }).catch(msg => {
      errorMessage(msg);
      window.history.pushState(null, '', '/');
      this._ui = DIALOG_MODE;
      this._render();
    });
    this._ui = LOADED_MODE;
    this._render();
  }

  _playpause() {
    if (this._playing) {
      this._wasmTimePassed = Date.now() - this._firstFrameTime;
      this._lottie.pause();
      this._live && this._live.pause();
      $$("#playpause").textContent = 'Play';
    } else {
      this._lottie.play();
      this._live && this._live.play();
      this._firstFrameTime = Date.now() - (this._wasmTimePassed || 0);
      $$("#playpause").textContent = 'Pause';
    }
    this._playing = !this._playing;
  }

  _rewind(e) {
    // Handle rewinding when paused.
    this._wasmTimePassed = 0;
    if (!this._playing) {
      this._live && this._live.goToAndStop(0);
      this._lottie.goToAndStop(0);
      this._firstFrameTime = null;
      this.querySelector('skottie-player-sk').seek(0);
    } else {
      this._live && this._live.goToAndPlay(0);
      this._lottie.goToAndPlay(0);
      this._firstFrameTime = null;
    }
  }

  _render() {
    if (this._downloadUrl)  {
      URL.revokeObjectURL(this._downloadUrl);
    }
    this._downloadUrl = URL.createObjectURL(new Blob([JSON.stringify(this._state.lottie, null, '  ')]));
    render(template(this), this, {eventContext: this});
    if (this._ui == LOADED_MODE) {
      // Don't re-start the animation while the user edits.
      if (!this._hasEdits) {
        $$('#container').innerHTML = '';
        this._lottie = bodymovin.loadAnimation({
          container: $$('#container'),
          renderer: 'svg',
          loop: true,
          autoplay: this._playing,
          // Apparently the lottie player modifies the data as it runs?
          animationData: JSON.parse(JSON.stringify(this._state.lottie)),
          rendererSettings: {
            preserveAspectRatio:'xMidYMid meet'
          },
        });
        this._live = null;
      } else {
        // we have edits, update the live preview version.
        // It will re-start from the very beginning, but the user can
        // hit "rewind" to re-sync them.
        $$('#live').innerHTML = '';
        this._live = bodymovin.loadAnimation({
          container: $$('#live'),
          renderer: 'svg',
          loop: true,
          autoplay: this._playing,
          // Apparently the lottie player modifies the data as it runs?
          animationData: JSON.parse(JSON.stringify(this._editor.get())),
          rendererSettings: {
            preserveAspectRatio:'xMidYMid meet'
          },
        });
      }

      let editorContainer = $$('#json_editor');
      // See https://github.com/josdejong/jsoneditor/blob/master/docs/api.md
      // for documentation on this editor.
      let editorOptions = {
        sortObjectKeys: true,
        // There are sometimes a few onChange events that happen
        // during the initial .set(), so we have a safety variable
        // _editorLoaded to prevent a bunch of recursion
        onChange: () => {
          if (!this._editorLoaded) {
            return;
          }
          this._hasEdits = true;
          onUserEdit(editorContainer, this._editor.get());
          this._render();
        }
      };

      if (!this._editor) {
        this._editorLoaded = false;
        editorContainer.innerHTML = '';
        this._editor = new JSONEditor(editorContainer, editorOptions);
        setupListeners(editorContainer);
      }
      if (!this._hasEdits) {
        this._editorLoaded = false;
        // Only set the JSON when it is loaded, either because it's
        // the first time we got it from the server or because the user
        // hit applyEdits.
        this._editor.set(this._state.lottie);
      }
      reannotate(editorContainer, this._state.lottie);
      // We are now pretty confident that the onChange events will only be
      // when the user modifies the JSON.
      this._editorLoaded = true;
    }
  }

  _toggleEmbed() {
    let collapse = $$('#embed', this);
    collapse.closed = !collapse.closed;
  }

  handleEvent(e) {
    if (e.type == 'skottie-selected') {
      this._state = e.detail;
      this._upload();
    } else if (e.type == 'cancelled') {
      this._ui = LOADED_MODE;
      this._editor = null;
      this._render();
    } else if (e.type == 'popstate') {
      this._reflectFromURL();
    }
  }

});
