/**
 * @module skottie-drive-sk
 * @description <h2><code>skottie-drive-sk</code></h2>
 *
 *    Presents a page for previewing Lottie files that are coming
 *    from Google Drive.
 *
 *    All the work in the app is done in the browser, i.e. no server side
 *    work is done. Authentication is done via the Google JS client library
 *    and rendering of the Lottie files is done using the WASM version of
 *    Skia.
 *
 *    A link from Google Drive to preview a JSON file will include a query
 *    parameter named 'state' that looks like:
 *
 *    {
 *      "ids": ["0Bz0bd"],
 *      "action":"open",
 *      "userId":"103354693083460731603"
 *    }
 *
 *    Where 'ids' is a list of Google Drive document ids that can be used
 *    via the Google Drive API to retrieve the document or metadata about
 *    the document.
 *
 */
import '../skottie-player-sk'
import 'elements-sk/error-toast-sk'
import { $$ } from 'common-sk/modules/dom'
import { SKIA_VERSION } from '../../build/version.js'
import { define } from 'elements-sk/define'
import { errorMessage } from 'elements-sk/errorMessage'
import { html, render } from 'lit-html'
import { until } from 'lit-html/directives/until.js';

// gapiLoaded is a promise that resolves when the 'gapi' JS library is
// finished loading.
let gapiLoaded = new Promise((resolve, reject) => {
  let check = () => {
    if (window.gapi !== undefined) {
      resolve();
    } else {
      setTimeout(check, 10)
    }
  }
  setTimeout(check, 10)
});

// caption returns a promise that resolves to the filename of the document
// with the given drive id.
const caption = (id) => {
  return gapiLoaded.then(() => {
    // Metadata.
    return gapi.client.drive.files.get({
      alt: 'json',
      fileId: id,
    }).then((response)  => {
      return html`<pre>${response.result.name}</pre>`;
    }).catch((response) => {
      errorMessage(response.result.error.message, 0);
    });
  });
}

// players returns one <skottie-player-sk> for each id.
const players = (ele) => ele._ids.map((id, i) => html`
<figure>
  <skottie-player-sk id="x${i}"></skottie-player-sk>
  <figcaption><p>${until(caption(id), `Loading...`)}</p><p class=errors id="errors${i}"></p></figcaption>
</figure>`);

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

define('skottie-drive-sk', class extends HTMLElement {
  constructor() {
    super();

    // The list of ids of documents to display.
    this._ids = [];
  }

  connectedCallback() {
    this._render();
    gapiLoaded.then(() => {
      // Load both the JS Apiary client library and OAuth 2 client library.
      gapi.load('client:auth2', () => { this.initClient() });
    });
  }

  initClient() {
    let postInit = () => {
      let isSignedIn = gapi.auth2.getAuthInstance().isSignedIn;
      // Listen for sign-in state changes.
      isSignedIn.listen(this.updateSigninStatus);
      // Handle the initial sign-in state.
      this.updateSigninStatus(isSignedIn.get());
    };

    gapi.client.init({
      apiKey: 'AIzaSyD2US0bcYT2VhguMezYgDa4lbZc6rIQbDg', // API Key is locked to https://skottie.skia.org, so it's safe to hardcode here.
      clientId: '145247227042-fetft5vnkf582o817e1t553cm3tjvobl.apps.googleusercontent.com', // Not protected info (clientSecret would be).
      discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'],
      scope: 'https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/drive.install',
    }).then(postInit);
  }

  // updateSigninStatus is called when the signed in status changes.
  updateSigninStatus(isSignedIn) {
    if (!isSignedIn) {
      gapi.auth2.getAuthInstance().signIn();
    } else {
      this.loadFiles();
    }
  }

  loadFiles() {
    // The state parameter is JSON that looks like:
    //
    // {
    //   "ids": ["0Bz0bd"],
    //   "action":"open",
    //   "userId":"103354693083460731603"
    // }
    //
    // See https://developers.google.com/drive/api/v3/integrate-open for more
    // details.
    let ids = ['12M0hlsK-zYCrKU6TG-Bji5Kcr9hWoyJw'];
    let stateParam = (new URL(document.location)).searchParams.get('state');
    if (stateParam) {
      ids = JSON.parse(stateParam).ids;
    }
    // Render a <skottie-player-sk> for each id.
    this._ids = ids;
    this._render();

    // Now kick off a fetch request for each player that retrieves the JSON
    // and populates the player.
    ids.forEach((id, i) => {
      // Media.
      gapi.client.drive.files.get({
        alt: 'media',
        fileId: id,
      }).then((response) => {
        if (response.headers['Content-Type'] !== 'application/json') {
          $$(`#errors${i}`, this).textContent = `Error: Not a JSON file.`;
          errorMessage("Can only process JSON files.", 0);
          return;
        }
        let lottie = response.result;
        let init = {
          width : lottie.w || 128,
          height : lottie.h || 128,
          lottie : lottie,
        }
        $$(`#x${i}`, this).initialize(init).catch((msg) => {
          $$(`#errors${i}`, this).textContent = `Error: Not a valid Lottie file.`;
          errorMessage(msg, 0);
        });
      }).catch((response) => {
        errorMessage(response.result.error.message, 0);
      });
    });
  }

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

});
