/**
 * @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.js';
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);
