import {
  buildNewSvgImages,
  buildOtherSvgImages,
  buildPlayerAvatars,
  drawAllNewCells,
  drawBackgrounds,
  drawBackgroundTopElements,
  drawFlags,
  drawNewAdditionalStuff,
  images,
} from './western-world.utils';
import { ORIGINAL_WESTERN_WORLD_HEIGHT, ORIGINAL_WESTERN_WORLD_WIDTH } from './western-world.utils.constants';
import { shouldRedraw } from './western-world.utils.helpers';

if (typeof window !== 'undefined') {
  const template = document.createElement('template');
  template.innerHTML = `
    <style>
      :host {
        display: block;
      }
      canvas {
        width: 100%;
        top: 0;
        left: 0;
        transition: filter 0.5s;
      }
    </style>

    <canvas></canvas>
  `;

  class WesternWorld extends HTMLElement {
    // Inputs:
    // game;
    // allCells;
    // myIdKey;
    // playersIconMap;
    // showWesternBackground;
    // SIZE_X_QUALITY;
    // PADDING_LEFT;
    // PADDING_RIGHT;
    // PADDING_TOP;
    // PADDING_BOTTOM;
    // language;

    // Outputs:
    // allImagesLoaded

    constructor() {
      super();
      this._shadowRoot = this.attachShadow({ mode: 'open' });
      this._shadowRoot.appendChild(template.content.cloneNode(true));
      this.$canvas = this._shadowRoot.querySelector('canvas');
    }

    areAllInitialized() {
      return this._language && this._showWesternBackground !== undefined && this._game && this._allCells;
    }

    set language(value) {
      this._language = value;
      const allInitialized = this.areAllInitialized();
      if (allInitialized) {
        this.render();
      }
    }

    set showWesternBackground(value) {
      this._showWesternBackground = value;
      const allInitialized = this.areAllInitialized();
      if (allInitialized) {
        this.render();
      }
    }

    set allCells(value) {
      this._allCells = value;
      const allInitialized = this.areAllInitialized();
      if (allInitialized) {
        this.render();
      }
    }

    set game(value) {
      const redraw = shouldRedraw(value, this._game);
      this._game = value;
      const allInitialized = this.areAllInitialized();
      if (allInitialized && redraw) {
        this.render();
      }
    }

    render() {
      this.fetchImages().then(() => this.drawWesternWorld());
    }

    fetchImages() {
      // get images from cache if exist;
      if (window.cachedImages?.[this._language]) {
        images.svgTags = { ...window.cachedImages[this._language].svgTags };
        images.svgImagesForCanvas = { ...window.cachedImages[this._language].svgImagesForCanvas };
        images.lang = this._language;
        this.dispatchEvent(new CustomEvent('allImagesLoaded', { detail: images }));
        return Promise.resolve(images);
      }

      images.allImagesProgress.resetLoadingImage();
      return Promise.all([
        buildNewSvgImages({
          allCells: this._allCells,
          language: this._language,
        }),
        buildOtherSvgImages({ language: this._language }),
        buildPlayerAvatars({ avatars: this.playersIconMap }),
      ])
        .then(() => {
          if (!window.cachedImages) {
            window.cachedImages = {};
          }
          if (!window.cachedImages[this._language]) {
            window.cachedImages[this._language] = {};
          }
          window.cachedImages[this._language].svgTags = { ...images.svgTags };
          window.cachedImages[this._language].svgImagesForCanvas = { ...images.svgImagesForCanvas };
          images.lang = this._language;
          this.dispatchEvent(new CustomEvent('allImagesLoaded', { detail: images }));
          return images;
        })
        .catch((e) => console.log('something went wrong', e));
    }

    drawWesternWorld() {
      console.log('drawWesternWorld...');

      // Background images should start before western-world starts and it should end after it ends
      // to have posibility to add stuff in the left and right free areas where no weestern space.
      // I guess 1000 additional pixels would be enough;
      const FREE_AREA = 333.33 * this.SIZE_X_QUALITY;
      const BACKGROUND_X = this.PADDING_LEFT - FREE_AREA;
      const BACKGROUND_Y = this.PADDING_TOP - FREE_AREA;
      const BACKGROUND_WIDTH = ORIGINAL_WESTERN_WORLD_WIDTH * this.SIZE_X_QUALITY + FREE_AREA * 2;
      const BACKGROUND_HEIGHT = ORIGINAL_WESTERN_WORLD_WIDTH * this.SIZE_X_QUALITY + FREE_AREA * 2;

      this.$canvas.width = ORIGINAL_WESTERN_WORLD_WIDTH * this.SIZE_X_QUALITY + this.PADDING_LEFT + this.PADDING_RIGHT;
      this.$canvas.height =
        ORIGINAL_WESTERN_WORLD_HEIGHT * this.SIZE_X_QUALITY + this.PADDING_TOP + this.PADDING_BOTTOM;
      const ctx = this.$canvas.getContext('2d');

      if (this._showWesternBackground) {
        this.$canvas.style.background = 'white';
        drawBackgrounds({
          ctx,
          BACKGROUND_X,
          BACKGROUND_Y,
          BACKGROUND_WIDTH,
          BACKGROUND_HEIGHT,
        });
      } else {
        this.$canvas.style.background = 'transparent';
      }

      // append all new images;
      drawAllNewCells({
        allCells: this._allCells,
        ctx,
        SIZE_X_QUALITY: this.SIZE_X_QUALITY,
        PADDING_LEFT: this.PADDING_LEFT,
        PADDING_TOP: this.PADDING_TOP,
      });

      if (this._showWesternBackground) {
        drawBackgroundTopElements({
          ctx,
          BACKGROUND_X,
          BACKGROUND_Y,
          BACKGROUND_WIDTH,
          BACKGROUND_HEIGHT,
        });
      }

      drawNewAdditionalStuff({
        ctx,
        SIZE_X_QUALITY: this.SIZE_X_QUALITY,
        PADDING_LEFT: this.PADDING_LEFT,
        PADDING_TOP: this.PADDING_TOP,
      });

      // draw flags;
      drawFlags({
        allCells: this._allCells,
        ctx,
        game: this._game,
        myIdKey: this.myIdKey,
        SIZE_X_QUALITY: this.SIZE_X_QUALITY,
        PADDING_LEFT: this.PADDING_LEFT,
        PADDING_TOP: this.PADDING_TOP,
      });
    }
  }

  window.customElements.define('western-world', WesternWorld);
}
