// site-reactions.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0

'use strict';

const DTP_COMPONENT = { name: 'Site Reactions', slug: 'site-reactions' };
const dtp = window.dtp = window.dtp || { }; // jshint ignore:line

import DtpLog from 'dtp/dtp-log';

class Reaction {

  constructor (container, reaction) {
    this.container = container;
    this.reaction = reaction;

    this.element = document.createElement('span');
    this.element.classList.add('reaction-icon');

    switch (this.reaction.reaction) {
      case 'clap':
        this.element.textContent = '👏';
        break;

      case 'fire':
        this.element.textContent = '🔥';
        break;

      case 'happy':
        this.element.textContent = '🤗';
        break;

      case 'laugh':
        this.element.textContent = '🤣';
        break;

      case 'angry':
        this.element.textContent = '🤬';
        break;

      case 'honk':
        this.element.textContent = '🤡';
        break;
    }

    this.position = {
      x: Math.random() * (this.container.offsetWidth - 32.0),
      y: this.container.clientHeight,
    };

    this.opacity = 1.0;
    this.moveSpeed = 150.0 + (Math.random() * 50.0);

    this.rotation = 0.0;
    this.rotationDelta = 60.0 + (Math.random() * 15.0);

    this.container.appendChild(this.element);
  }

  update (elapsed) {
    const scale = elapsed / 1000.0;
    this.position.y -= this.moveSpeed * scale;
    this.rotation += this.rotationDelta * scale;
    if (this.rotation > 30 || this.rotation < -30) {
      this.rotationDelta = -this.rotationDelta;
    }

    const adjustedY = this.position.y + this.element.offsetHeight;
    if (adjustedY > 100) {
      return;
    }
    if (adjustedY === 0) {
      this.opacity = 0.0;
      return;
    }

    this.opacity = adjustedY / 100.0;
  }

  render ( ) {
    this.element.style.left = `${this.position.x}px`;
    this.element.style.top = `${this.position.y}px`;

    if (this.opacity > 0.8) { this.opacity = 0.8; }
    this.element.style.opacity = this.opacity;

    const transform = `rotate(${this.rotation}deg)`;
    this.element.style.transform = transform;
  }

  destroy ( ) {
    this.container.removeChild(this.element);
  }
}

export default class SiteReactions {

  constructor ( ) {
    this.log = new DtpLog(DTP_COMPONENT);

    this.container = document.querySelector('#chat-reactions');
    this.reactions = [ ];

    this.updateHandler = this.onUpdate.bind(this);
  }

  create (reaction) {
    const react = new Reaction(this.container, reaction);
    this.reactions.push(react);

    if (this.reactions.length === 1) {
      this.lastUpdate = new Date();
      requestAnimationFrame(this.updateHandler);
    }
  }

  onUpdate ( ) {
    const NOW = new Date();
    const elapsed = NOW - this.lastUpdate;
    const expired = [ ];

    for (const reaction of this.reactions) {
      reaction.update(elapsed);
      if (reaction.position.y <= -(reaction.element.offsetHeight)) {
        expired.push(reaction);
      } else {
        reaction.render();
      }
    }

    expired.forEach((react) => {
      const idx = this.reactions.indexOf(react);
      if (idx === -1) {
        return;
      }
      react.destroy();
      this.reactions.splice(idx, 1);
    });

    if (this.reactions.length > 0) {
      requestAnimationFrame(this.updateHandler);
    }

    this.lastUpdate = NOW;
  }
}

dtp.SiteReactions = SiteReactions;