/**
 * @module skottie-gif-exporter
 * @description <h2><code>skottie-gif-exporter</code></h2>
 *
 * <p>
 *   A skottie gif exporter
 * </p>
 *
 * @evt start - This event is generated when the saving process starts.
 *
 */
import { html } from 'lit-html';
import { define } from '../../../elements-sk/modules/define';
import '../../../elements-sk/modules/select-sk';
import { bytes, diffDate } from '../../../infra-sk/modules/human';
import { SelectSkSelectionChangedEventDetail } from '../../../elements-sk/modules/select-sk/select-sk';
import gifStorage from '../helpers/gifStorage';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { SkottiePlayerSk } from '../skottie-player-sk/skottie-player-sk';

interface GIFLibraryOptions {
  workerScript?: string;
  workers?: number;
  repeat?: number;
  background?: string;
  quality?: number;
  width?: number;
  height?: number;
  transparent?: number | null;
  debug?: boolean;
  dither?: boolean | string;
}

interface GIFLibrary {
  abort(): unknown;
  addFrame(
    canvasElement: HTMLCanvasElement | ImageData | CanvasRenderingContext2D,
    options: { delay: number; copy: boolean }
  ): void;
  on(event: string, callback: (_: unknown) => void): void;
  render(): unknown;
}

interface BackgroundOption {
  id: string;
  label: string;
  color: string;
}

declare const GIF: new (_: GIFLibraryOptions) => GIFLibrary;

const QUALITY_SCRUBBER_RANGE = 50;

const WORKERS_COUNT = 4;

const ditherOptions = [
  'FloydSteinberg',
  'FalseFloydSteinberg',
  'Stucki',
  'Atkinson',
];

const backgroundOptions: BackgroundOption[] = [
  {
    id: '1',
    label: 'White',
    color: '#ffffff',
  },
  {
    id: '2',
    label: 'Black',
    color: '#000000',
  },
];

type ExportState = 'idle' | 'gif processing' | 'image processing' | 'complete';

const renderRepeatsLabel = (val: number) => {
  switch (val) {
    case -1:
      return 'No repeats';
    case 0:
      return 'Infinite repeats';
    case 1:
      return `${val} Repeat`;
    default:
      return `${val} Repeats`;
  }
};

export class SkottieGifExporterSk extends ElementSk {
  private static template = (ele: SkottieGifExporterSk) => html`
    <div>
      <header class="editor-header">
        <div class="editor-header-title">Gif Exporter</div>
        <div class="editor-header-separator"></div>
        ${ele.renderHeader()}
      </header>
      <section class="main">${ele.renderMain()}</section>
    </div>
  `;

  private renderMain = () => {
    switch (this.state) {
      default:
      case 'idle':
        return this.renderIdle();
      case 'image processing':
        return this.renderImage();
      case 'gif processing':
        return this.renderGif();
      case 'complete':
        return this.renderComplete();
    }
  };

  private renderIdle = () => html`
    <div class="form">
      <div class="form-elem">
        <div>Sample (${this.quality})</div>
        <input
          id="sampleScrub"
          type="range"
          min="1"
          max=${QUALITY_SCRUBBER_RANGE}
          step="1"
          @input=${this.updateQuality}
          @change=${this.updateQuality}
          .value=${this.quality} />
      </div>
      <div class="form-elem">
        <label class="number">
          <input
            type="number"
            id="repeats"
            .value=${this.repeat}
            min="-1"
            @input=${this.onRepeatChange}
            @change=${this.onRepeatChange} />
          Repeats (${renderRepeatsLabel(this.repeat)})
        </label>
      </div>
      <div class="form-elem">
        <checkbox-sk
          label="Dither"
          ?checked=${this.dither}
          @click=${this.toggleDither}>
        </checkbox-sk>
        ${this.renderDither()}
      </div>
      <div class="form-elem">
        <checkbox-sk
          label="Include Transparent Background"
          ?checked=${this.transparent}
          @click=${this.toggleTransparent}>
        </checkbox-sk>
      </div>
      <div class="form-elem">
        <div class="form-elem-label">
          Select Background Color to compose on Transparent
        </div>
        ${this.renderBackgroundSelect()}
      </div>
    </div>
  `;

  private renderImage = () => html`
    <section class="exporting">
      <div>Creating snapshots: ${this.progress}%</div>
    </section>
  `;

  private renderGif = () => html`
    <section class="exporting">
      <div>Creating GIF: ${this.progress}%</div>
    </section>
  `;

  renderComplete = () => html`
    <section class="complete">
      <div class="export-info">
        <div class="export-info-row">Render Complete</div>
        <div class="export-info-row">
          Export Duration: ${this.exportDuration}
        </div>
        <div class="export-info-row">
          File size: ${bytes(this.blob ? this.blob.size : 0)}
        </div>
      </div>
      <a
        class="download"
        href=${this.blobURL}
        download=${this.getDownloadFileName()}>
        Download
      </a>
    </section>
  `;

  private renderHeader = () => {
    if (this.state === 'idle') {
      return html`
        <button class="editor-header-save-button" @click=${this.save}>
          Save
        </button>
      `;
    }
    if (this.state === 'complete') {
      return html`
        <button class="editor-header-save-button" @click=${this.cancel}>
          Back
        </button>
      `;
    }
    return html`
      <button class="editor-header-save-button" @click=${this.cancel}>
        Cancel
      </button>
    `;
  };

  private renderDither = () => {
    if (this.dither) {
      return html`
        <select-sk role="listbox" @selection-changed=${this.ditherOptionChange}>
          ${ditherOptions.map((item: string, index: number) =>
            this.renderOption(item, index)
          )}
        </select-sk>
      `;
    }
    return null;
  };

  private renderOption = (item: string, index: number) => html`
    <div role="option" ?selected=${this.ditherValue === index}>${item}</div>
  `;

  private renderBackgroundOption = (item: BackgroundOption) => html`
    <div role="option" ?selected=${this.backgroundValue.id === item.id}>
      ${item.label}
    </div>
  `;

  private renderBackgroundSelect = () => html`
    <select-sk role="listbox" @selection-changed=${this.backgroundOptionChange}>
      ${backgroundOptions.map((item: BackgroundOption) =>
        this.renderBackgroundOption(item)
      )}
    </select-sk>
  `;

  private backgroundValue: BackgroundOption = backgroundOptions[0];

  private backgroundValueIndex: number = 0;

  private blob: Blob | null = null;

  private dither: boolean | string = false;

  private ditherValue: number = 0;

  private exportDuration: string = '';

  private gif: GIFLibrary | null = null;

  private progress: number = 0;

  private quality: number = 0;

  private repeat: number = 0;

  private state: ExportState = 'idle';

  private transparent: boolean = false;

  private startTime: number = 0;

  private blobURL: string = '';

  private _player: SkottiePlayerSk | null = null;

  constructor() {
    super(SkottieGifExporterSk.template);
    this.repeat = gifStorage.get('repeat', 0);
    this.quality = gifStorage.get('quality', 50);
    this.backgroundValueIndex = gifStorage.get('backgroundIndex', 0);
    this.transparent = gifStorage.get('transparent', true);
    this.dither = gifStorage.get('dither', false);
    this.ditherValue = gifStorage.get('ditherValue', 0);
    this.backgroundValue = backgroundOptions[this.backgroundValueIndex];
  }

  connectedCallback() {
    super.connectedCallback();
    this._render();
  }

  private delay(time: number) {
    return new Promise((resolve) => setTimeout(resolve, time));
  }

  private updateQuality(ev: Event): void {
    this.quality = +(ev.target as HTMLInputElement).value;
    gifStorage.set('quality', this.quality);
    this._render();
  }

  private onRepeatChange(ev: Event) {
    this.repeat = +(ev.target as HTMLInputElement).value;
    gifStorage.set('repeat', this.repeat);
    this._render();
  }

  private toggleDither(e: Event) {
    e.preventDefault();
    this.dither = !this.dither;
    gifStorage.set('dither', this.dither);
    this._render();
  }

  private toggleTransparent(e: Event) {
    e.preventDefault();
    this.transparent = !this.transparent;
    gifStorage.set('transparent', this.transparent);
    this._render();
  }

  private ditherOptionChange(
    e: CustomEvent<SelectSkSelectionChangedEventDetail>
  ) {
    e.preventDefault();
    this.ditherValue = e.detail.selection;
    gifStorage.set('ditherValue', this.ditherValue);
    this._render();
  }

  private backgroundOptionChange(
    e: CustomEvent<SelectSkSelectionChangedEventDetail>
  ) {
    e.preventDefault();
    this.backgroundValue = backgroundOptions[e.detail.selection];
    gifStorage.set('backgroundIndex', e.detail.selection);
    this._render();
  }

  private getDownloadFileName() {
    return this.player?.animationName() || 'animation.gif';
  }

  /*
   *
   * This method takes care of traversing all frames from the passed animation
   * it adds all frames to the gif instance with a 1 ms delay between frames
   * to prevent blocking the main thread.
   */
  private async processFrames() {
    const fps = this.player.fps();
    const duration = this.player.duration();
    const canvasElement = this.player.canvas();
    let currentTime = 0;
    const increment = 1000 / fps;
    this.state = 'image processing';
    this._render();
    while (currentTime < duration) {
      if (this.state !== 'image processing') {
        return;
      }
      await this.delay(1); // eslint-disable-line no-await-in-loop
      this.player.seek(currentTime / duration, true);
      this.gif!.addFrame(canvasElement!, { delay: increment, copy: true });
      this.progress = Math.round((currentTime / duration) * 100);
      currentTime += increment;
      this._render();
    }
    this.state = 'gif processing';
    // Note: this render method belongs to the gif.js library, not the html-lit
    this.gif!.render();
  }

  private cancel() {
    if (this.state === 'gif processing') {
      this.gif!.abort();
    }
    this.state = 'idle';
    this._render();
  }

  private createGifExporter() {
    this.gif = new GIF({
      workers: WORKERS_COUNT,
      quality: this.quality,
      repeat: this.repeat,
      dither: this.dither ? ditherOptions[this.ditherValue] : false,
      transparent: this.transparent ? 0x00000000 : undefined,
      background: this.backgroundValue.color,
      workerScript: '/static/gif.worker.js',
    });
    this.gif.on('finished', (blob: unknown) => {
      this.state = 'complete';
      this.blob = blob as Blob;
      this.exportDuration = diffDate(this.startTime);
      this.blobURL = URL.createObjectURL(this.blob);
      this._render();
    });
    this.gif.on('progress', (value: unknown) => {
      this.progress = Math.round((value as number) * 100);
      this._render();
    });
  }

  private start() {
    this.progress = 0;
    this.startTime = Date.now();
    this.dispatchEvent(new CustomEvent('start'));
  }

  private async save(): Promise<void> {
    this.start();
    this.createGifExporter();
    await this.processFrames();
  }

  get player(): SkottiePlayerSk {
    return this._player!;
  }

  set player(val: SkottiePlayerSk) {
    this._player = val;
  }
}

define('skottie-gif-exporter-sk', SkottieGifExporterSk);
