/**
 * @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 { html } from 'lit-html';
import { define } from '../../../elements-sk/modules/define';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';
import { $$ } from '../../../infra-sk/modules/dom';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { SoundMap } from '../audio';
import { LottieAnimation } from '../types';

const DEFAULT_SIZE = 128;

const BACKGROUND_VALUES = {
  TRANSPARENT: 'rgba(0,0,0,0)',
  LIGHT: '#FFFFFF',
  DARK: '#000000',
};

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

export interface SkottieConfigState {
  assets?: Record<string, ArrayBuffer>;
  filename: string;
  lottie: LottieAnimation | null;
  assetsZip: string;
  assetsFilename: string;
  w?: number;
  h?: number;
  soundMap?: SoundMap;
}

export interface SkottieConfigEventDetail {
  state: SkottieConfigState;
  fileChanged: boolean;
  width: number;
  height: number;
  fps: number;
  backgroundColor: string;
}

export class SkottieConfigSk extends ElementSk {
  private static template = (ele: SkottieConfigSk) => 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="button-like"
      >Lottie file to upload
      <input type="file" name="file" id="file" @change=${ele.onFileChange} />
    </label>
    <div class="filename input-like ${ele._state.filename ? '' : 'empty'}">
      ${ele._state.filename ? ele._state.filename : 'No file selected.'}
    </div>
    <label class="button-like" ?hidden=${!allowZips}
      >Optional Asset Folder (.zip)
      <input
        type="file"
        name="folder"
        id="folder"
        @change=${ele.onFolderChange} />
    </label>
    <div
      class="filename input-like ${ele._state.assetsFilename ? '' : 'empty'}"
      ?hidden=${!allowZips}>
      ${ele._state.assetsFilename
        ? ele._state.assetsFilename
        : 'No asset folder selected.'}
    </div>
    <label class="number">
      Background Color
      <select id="backgroundColor">
        <option
          value=${BACKGROUND_VALUES.TRANSPARENT}
          ?selected=${ele._backgroundColor === BACKGROUND_VALUES.TRANSPARENT}>
          Transparent
        </option>
        <option
          value=${BACKGROUND_VALUES.LIGHT}
          ?selected=${ele._backgroundColor === BACKGROUND_VALUES.LIGHT}>
          Light
        </option>
        <option
          value=${BACKGROUND_VALUES.DARK}
          ?selected=${ele._backgroundColor === BACKGROUND_VALUES.DARK}>
          Dark
        </option>
      </select>
    </label>
    <checkbox-sk
      label="Lock aspect ratio"
      ?checked=${ele._isRatioLocked}
      @click=${ele.toggleRatioLock}>
    </checkbox-sk>
    <label class="number">
      <input
        type="number"
        id="width"
        @change=${ele.onWidthInput}
        .value=${ele._width}
        required />
      Width (px)
    </label>
    <label class="number">
      <input
        type="number"
        id="height"
        @change=${ele.onHeightInput}
        .value=${ele._height}
        required />
      Height (px)
    </label>
    <label class="number">
      <input type="number" id="fps" .value=${ele._fps} required /> FPS
    </label>
    <div>
      0 for width/height means use the default from the animation. For FPS, 0
      means "as smooth as possible" and -1 means "use what the animation says".
    </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=${() => ele.rescale(1024)}>Rescale to 1024</button>
        <button @click=${() => ele.rescale(512)}>Rescale to 512</button>
        <button @click=${() => ele.rescale(128)}>Rescale to 128</button>
      </div>
    </div>
    <div id="dialog-buttons">
      ${ele.cancelButton()}
      <button class="action" ?disabled=${ele.readyToGo()} @click=${ele.go}>
        Go
      </button>
    </div>
  `;

  private cancelButton = () => {
    if (this.hasCancel()) {
      return html`<button id="cancel" @click=${this.cancel}>Cancel</button>`;
    }
    return html``;
  };

  private _state: SkottieConfigState = {
    filename: '',
    lottie: null,
    assetsZip: '',
    assetsFilename: '',
  };

  private _isRatioLocked: boolean = false;

  private _ratio: number = 0;

  private _width: number = DEFAULT_SIZE;

  private _height: number = DEFAULT_SIZE;

  private _fps: number = 0;

  private _backgroundColor: string = BACKGROUND_VALUES.TRANSPARENT;

  private _fileChanged: boolean = false;

  constructor() {
    super(SkottieConfigSk.template);
  }

  connectedCallback(): void {
    super.connectedCallback();
    this._render();
    this.addEventListener('input', this.inputEvent);
  }

  disconnectedCallback(): void {
    super.disconnectedCallback();
    this.removeEventListener('input', this.inputEvent);
  }

  get height(): number {
    return this._height;
  }

  set height(val: number) {
    this._height = val;
    this._render();
  }

  get state(): SkottieConfigState {
    return this._state;
  }

  set state(val: SkottieConfigState) {
    this._state = Object.assign({}, val); // make a copy of passed in state.
    this._render();
  }

  get fps(): number {
    return this._fps;
  }

  set fps(val: number) {
    this._fps = +val;
    this._render();
  }

  get width(): number {
    return this._width;
  }

  set width(val: number) {
    this._width = +val;
    this._render();
  }

  get backgroundColor(): string {
    return this._backgroundColor;
  }

  set backgroundColor(val: string) {
    this._backgroundColor = val;
    this._render();
  }

  private hasCancel(): boolean {
    return !!this._state.lottie;
  }

  private readyToGo(): boolean {
    return (
      !this._state.filename && (!!this._state.lottie || !!this._state.assetsZip)
    );
  }

  private onFileChange(e: Event): void {
    const files = (e.target as HTMLInputElement).files!;
    this._fileChanged = true;
    const toLoad = files[0];
    const reader = new FileReader();
    if (toLoad.name.endsWith('.json')) {
      reader.addEventListener('load', () => {
        let parsed: LottieAnimation;
        try {
          parsed = JSON.parse(reader.result as string) as LottieAnimation;
        } 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 = null;
        this._state.assetsZip = reader.result as string;
        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 = null;
    }
  }

  private onFolderChange(e: Event): void {
    const files = (e.target as HTMLInputElement).files!;
    this._fileChanged = true;
    const toLoad = files[0];
    const reader = new FileReader();
    reader.addEventListener('load', () => {
      this._state.assetsZip = reader.result as string;
      this._state.assetsFilename = toLoad.name;
      this._render();
    });
    reader.addEventListener('error', () => {
      errorMessage(`Failed to load ${toLoad.name}`);
    });
    reader.readAsDataURL(toLoad);
  }

  private toggleRatioLock(e: Event): void {
    e.preventDefault();
    this._isRatioLocked = !this._isRatioLocked;
    this._ratio = this._isRatioLocked ? this._width / this._height : 0;
    this._render();
  }

  private onWidthInput(): void {
    if (this._isRatioLocked) {
      this._height = Math.floor(this._width / this._ratio);
      this._render();
    }
  }

  private onHeightInput(): void {
    if (this._isRatioLocked) {
      this._width = Math.floor(this._height * this._ratio);
      this._render();
    }
  }

  private rescale(n: number): void {
    const 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();
  }

  private warningHidden(): boolean {
    return this._width <= 1024 && this._width <= 1024;
  }

  private updateState(): void {
    this._width = +$$<HTMLInputElement>('#width', this)!.value;
    this._height = +$$<HTMLInputElement>('#height', this)!.value;
    this._fps = +$$<HTMLInputElement>('#fps', this)!.value;
    this._backgroundColor = $$<HTMLInputElement>(
      '#backgroundColor',
      this
    )!.value;
  }

  private go(): void {
    this.updateState();
    this.dispatchEvent(
      new CustomEvent<SkottieConfigEventDetail>('skottie-selected', {
        detail: {
          state: this._state,
          fileChanged: this._fileChanged,
          width: this._width,
          height: this._height,
          fps: this._fps,
          backgroundColor: this._backgroundColor,
        },
        bubbles: true,
      })
    );
  }

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

  private inputEvent(): void {
    this.updateState();
    this._render();
  }
}

define('skottie-config-sk', SkottieConfigSk);
