/**
 * @module particles-sk
 * @description <h2><code>particles-player-sk</code></h2>
 *
 * <p>
 *   Handles the bulk of the work displaying Particles.
 * </p>
 *
 */
import { $$ } from 'common-sk/modules/dom';
import { define } from 'elements-sk/define';
import { errorMessage } from 'elements-sk/errorMessage';
import { html, TemplateResult } from 'lit-html';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import type {
  Particles, CanvasKit, Surface, Canvas,
} from '../../build/canvaskit/canvaskit.js';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const CanvasKitInit = require('../../build/canvaskit/canvaskit.js');

const DEFAULT_SIZE = 256;
const ZOOM_IN_FACTOR = 1.1; // 10%
const ZOOM_OUT_FACTOR = 1 / ZOOM_IN_FACTOR;

export interface PlayerConfig {
  body: any;
  width: number;
  height: number;
}

// This element might be loaded from a different site, and that means we need
// to be careful about how we construct the URL back to the canvas.wasm file.
// Start by recording the script origin.
const scriptOrigin = new URL((document!.currentScript as HTMLScriptElement).src).origin;
const kitReady = CanvasKitInit({
  locateFile: (file: any) => `${scriptOrigin}/dist/${file}`,
});

/**
 * Information needed to construct a single HTML control for a uniform. Note
 * that some uniforms actually represent more than one control, such as a
 * 'float3', in which case code will need to create three instances of
 * UniformControl.
*/
interface UniformControl {
  id: string;
  uniformSlot: number;
}

interface Point {
  x: number;
  y: number;
}

export function floatSlider(uniform: UniformControl | null): TemplateResult {
  if (!uniform) {
    return html``;
  }
  return html` <div class="widget">
    <input
      name=${uniform.id}
      id=${uniform.id}
      min="0"
      max="1"
      step="0.00001"
      type="range"
    />
    <label for=${uniform.id}>${uniform.id}</label>
  </div>`;
}

export class ParticlesPlayerSk extends ElementSk {
  private sliders: UniformControl[] = [];

  private zoomLevel: number = 1.0;

  private kit: CanvasKit | null = null; // CanvasKit instance

  private context: number = -1; // CanvasKit context.

  private animation: Particles | null = null; // Particles instance

  private surface: Surface | null = null; // Surface

  private canvas: Canvas | null = null; // Cached Canvas (surface.getCanvas()).

  private time: number = 0;

  private lastTime: number = 0;

  private lastDrag: Point | null = null;

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

  private static template = (ele: ParticlesPlayerSk) => html`
    <div class="container">
      ${ele.sliders.map(floatSlider)}
      <canvas
        id="player"
        @wheel=${ele.wheelHandler}
        @mousemove=${ele.dragHandler}
        width=${ele.width * window.devicePixelRatio}
        height=${ele.height * window.devicePixelRatio}
        style="width: ${ele.width}px; height: ${ele.height}px;"
      >
        Your browser does not support the canvas tag.
      </canvas>
    </div>`;


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

  attributeChangedCallback(): void {
    this._render();
  }

  initialize(config: PlayerConfig): Promise<void> {
    this.width = config.width;
    this.height = config.height;
    this._render();

    return kitReady.then((ck: CanvasKit) => {
      this.kit = ck;
      try {
        this._initializeParticles(config.body);
      } catch (error) {
        errorMessage(error);
      }
      this._render();
    });
  }

  isPlaying(): boolean {
    return !this.paused;
  }

  play(): void {
    if (!this.isPlaying()) {
      this.paused = false;
    }
    this._render();
  }

  pause(): void {
    if (this.isPlaying()) {
      this.paused = true;
    }
  }

  resetView(): void {
    const ck = this.kit;
    const canvas = this.canvas;
    // Reset to identity
    const tt = canvas!.getTotalMatrix();
    const itt = ck!.Matrix.invert(tt)!;
    canvas!.concat(itt);
    // Zoom to the middle of the animation
    canvas!.translate(this.width / 2, this.height / 2);
    this.zoomLevel = 1.0;
  }

  restartAnimation(): void {
    this.time = 0;
    this.lastTime = 0;
  }

  private dragHandler(e: MouseEvent) {
    if (!e.buttons) {
      this.lastDrag = null;
      return;
    }
    if (this.lastDrag) {
      const dx = e.clientX - this.lastDrag.x;
      const dy = e.clientY - this.lastDrag.y;

      this.canvas!.translate(dx / this.zoomLevel, dy / this.zoomLevel);
    }
    this.lastDrag = {
      x: e.clientX,
      y: e.clientY,
    };
  }

  private drawFrame() {
    if (!this.animation || !this.canvas) {
      return;
    }

    // Go through all the sliders on the page that we created and poll those inputs for their
    // value. Plug those values (range [0.0, 1.0]) into the uniforms.
    const uniforms = this.animation.uniforms();
    this.sliders.forEach((slider) => {
      const s = $$<HTMLInputElement>(`input#${slider.id}`, this);
      if (!s) {
        return;
      }
      uniforms[slider.uniformSlot] = s.valueAsNumber;
    });
    window.requestAnimationFrame(() => this.drawFrame());
    if (!this.lastTime) {
      this.animation.start(0, true);
      this.lastTime = Date.now();
    }

    if (this.isPlaying()) {
      this.time += Date.now() - this.lastTime;
    }
    this.lastTime = Date.now();

    this.kit!.setCurrentContext(this.context);
    this.canvas.clear(this.kit!.BLACK);
    this.animation.update(this.time / 1000.0);
    this.animation.draw(this.canvas);
    this.surface!.flush();
  }

  private _initializeParticles(particlesJSON: any) {
    // Rebuild the surface only if needed.
    if (
      !this.surface
      || (this.surface!.width() !== this.width)
      || (this.surface!.height() !== this.height)
    ) {
      this._render();

      // eslint-disable-next-line no-unused-expressions
      this.surface?.delete();
      const canvasEle = $$<HTMLCanvasElement>('#player', this)!;
      this.surface = this.kit!.MakeCanvasSurface(canvasEle);
      if (!this.surface) {
        throw new Error('Could not make SkSurface.');
      }
      // We don't need to call .delete() on the canvas because
      // the parent surface will do that for us.
      this.canvas = this.surface.getCanvas();
      this.context = this.kit!.currentContext();
    }

    // eslint-disable-next-line no-unused-expressions
    this.animation?.delete();

    this.animation = this.kit!.MakeParticles(
      JSON.stringify(particlesJSON),
    );
    if (!this.animation) {
      throw new Error('Could not parse Particles JSON.');
    }

    // Go through all uniforms this animation has and look for those with the
    // prefix 'slider_' For those uniforms, we will make a slider on the UI and
    // then every frame, we will poll those inputs for their value and plug the
    // values into the uniforms. The sliders will be in range [0.0, 1.0]. Note
    // that the matrices are column major.

    // TODO(jcgregorio) Group rows together on the display so matrices look like
    // matrices.

    // TODO(jgrergorio) If the name contains "color" then either display a color
    // picker or at the very least change the postfixes to _r, _g_, and _b.

    // TODO(jcgregorio) Break out the uniforms handling into its own element
    // to be re-used on shaders.skia.org.
    this.sliders = [];
    const an = this.animation;
    for (let i = 0; i < an.getUniformCount(); i++) {
      const name = an.getUniformName(i);
      if (name.startsWith('slider_')) {
        const uniform = an.getUniform(i);
        for (let row = 0; row < uniform.rows; row++) {
          for (let col = 0; col < uniform.columns; col++) {
            let id = `${name.substring('slider_'.length)}`;
            if (uniform.rows > 1) {
              id += `_${row}`;
            }
            if (uniform.columns > 1) {
              id += `_${col}`;
            }
            this.sliders.push({
              id: id,
              uniformSlot: uniform.slot + row + col * uniform.rows,
            });
          }
        }
      }
    }

    this._render();
    this.canvas!.clear(this.kit!.BLACK);
    this.resetView();
    this.restartAnimation();
    this.drawFrame();
  }

  private wheelHandler(e: WheelEvent) {
    e.preventDefault();
    e.stopPropagation();

    let zoom = 0;
    if (e.deltaY < 0) {
      zoom = ZOOM_IN_FACTOR;
    } else {
      zoom = ZOOM_OUT_FACTOR;
    }
    this.zoomLevel *= zoom;
    const ck = this.kit;
    const canvas = this.canvas;

    const tt = canvas!.getTotalMatrix();
    const itt = ck!.Matrix.invert(tt)!;
    const pts = [e.clientX, e.clientY];
    ck!.Matrix.mapPoints(itt, pts); // Transform DOM pts into canvas space

    const matr = ck!.Matrix.scaled(zoom, zoom, pts[0], pts[1]);
    canvas!.concat(matr);
  }

  static get observedAttributes(): string[] {
    return ['width', 'height', 'paused'];
  }

  get width(): number { return +(this.getAttribute('width') || DEFAULT_SIZE); }

  set width(val: number) { this.setAttribute('width', val.toFixed(0)); }

  get height(): number { return +(this.getAttribute('height') || DEFAULT_SIZE); }

  set height(val: number) { this.setAttribute('height', val.toFixed(0)); }

  get paused(): boolean { return this.hasAttribute('paused'); }

  set paused(val: boolean) {
    if (val) {
      this.setAttribute('paused', '');
    } else {
      this.removeAttribute('paused');
    }
  }
}

define('particles-player-sk', ParticlesPlayerSk);
