<template>
  <div id="phaser-container"></div>
</template>

<script lang="ts">
import 'phaser';
// import 'phaser3-rex-plugins/templates/ui/ui-plugin';
// import 'phaser3-rex-plugins/templates/ui/ui-components';
import CreateMoreScrollablePanels from '../../kanbans/CreateScrollablePanel';
import { useKanvasoStore } from '../../../stores/kanvaso';
import { mapActions, mapState } from 'pinia';
// import PreloadScene from './PreloadScene';
// import BootScene from './BootScene';
import { KanvasojKanvaso } from '../../../types/stores/kanvaso';
import CreateMainMenu from '../../main-menu/MainMenu';
import { Router } from 'vue-router';
import UIPlugin from 'phaser3-rex-plugins/templates/ui/ui-plugin';
import { getPhaserConfig } from './PhaserConfig';

import { LoadingResources } from '../../resources/LoadingResources';
import CreateToolbar from 'src/apps/toolbar/CreateToolbar';
declare const window: {
  router: Router;
} & Window;

const CreateDOM = function (scene: EndlessCanvas, content: string) {
  //@ts-ignore
  var dom = scene.add.dom().createFromHTML(content);
  //@ts-ignore
  dom.node.style.width = '400px';
  dom.updateSize();
  return dom;
};

class EndlessCanvas extends Phaser.Scene {
  private isDragging: boolean;
  private isSpaceDown: boolean; // Добавлено новое свойство для отслеживания состояния клавиши пробела
  private dragStartPoint: { x: number; y: number; };
  private uiCamera: Phaser.Cameras.Scene2D.Camera;
  rexUI: UIPlugin;
  registry: Phaser.Data.DataManager;
  toolbarWidth: number;
  mainMenuHeight: number;
  store: any;
  router: Router;
  objectFields: string[];
  isDark: boolean;
  constructor() {
    super({
      key: 'endless-canvas',
    });
    this.store = useKanvasoStore();
    this.router = window.router;
    this.objectFields = [
      'name',
      'isPublished',
      'isDeleted',
      'description',
      'id',
      'type',
      'typeId',
      'parentUuid',
      'hasParent',
    ];
    this.isDark = false;
    this.isDragging = false;
    this.dragStartPoint = { x: 0, y: 0 };
    this.toolbarWidth = 50;
    this.mainMenuHeight = 48;
  }

  preload() {
    this.load.scenePlugin(
      'rexuiplugin',
      'rexuiplugin.min.js',
      'rexUI',
      'rexUI',
    );
    // вынес загрузку ресурсов в отдельный файл
    LoadingResources(this);

    //@ts-ignore
    this.load.rexAwait(function (successCallback, failureCallback) {
      setTimeout(successCallback, 4500);
    });
    //Обьявляем закрытие
    this.plugins
      .get('rexLoadingAnimationScene')
      //@ts-ignore
      .startScene(
        this,
        'loading-animation',
        function (successCallback, animationScene) {
          animationScene.onClose(successCallback);
        },
      );
  }

  create(): void {
    const scene = this;
    const buttonArray = [
      {
        image: 'logo',
        callback: function () {
          scene.router.push('/projects');
        }
      },
      // {
      //   image: 'universo',
      //   callback: function () { }
      // },
    ];
    const toolbarButtons = [

      {
        image: this.isDark ? 'toolbar_1b' : 'toolbar_1c',
        imageHover: 'toolbar_1a',
        callback: function () {
          // scene.router.push('/projects');
        }
      },
      {
        image: this.isDark ? 'toolbar_2b' : 'toolbar_2c',
        imageHover: 'toolbar_2a',
        callback: function () {
          // scene.router.push('/projects');
        }
      },
      {
        image: this.isDark ? 'toolbar_3b' : 'toolbar_3c',
        imageHover: 'toolbar_3a',
        callback: function () {
          // scene.router.push('/projects');
        }
      },
      {
        image: this.isDark ? 'toolbar_4b' : 'toolbar_4c',
        imageHover: 'toolbar_4a',
        callback: function () {
          // scene.router.push('/projects');
        }
      },



    ];
    const content = 'Phaser is a fast, free, and fun open source HTML5 game framework that offers WebGL and Canvas rendering across desktop and mobile web browsers. Games can be compiled to iOS, Android and native apps by using 3rd party tools. You can use JavaScript or TypeScript for development.';

    //@ts-ignore
    //const toolbar = CreateToolbar(scene, scene.router);
    // const back = this.add
    //   .text(0, 0, '<<', {
    //     fontSize: '24px',
    //     backgroundColor: '#000',
    //     color: '#fff',
    //   })
    //   .setDepth(20);
    // back.setInteractive();
    // back.on('pointerdown', () => {
    //   this.router.push('/projects');
    // });
    scene.cameras.main.setBackgroundColor('#abcdef');

    // Скрываем экран загрузки здесь, потому что на этом этапе preload уже завершен
    // document.getElementById('loading-screen').style.display = 'none';
    let parent = scene.sys.game.canvas.parentElement;
    let parentWidth = parent.offsetWidth;
    let parentHeight = parent.offsetHeight;
    const numberOfPanels = scene.store.getTree.length;
    let panelWidth = parentWidth;
    let panelHeight = (parentHeight - scene.mainMenuHeight) / numberOfPanels;

    let topPanelsArr = CreateMoreScrollablePanels(
      //@ts-ignore
      scene,
      this.store.getTree,
    );
    for (let i = 0; i < topPanelsArr.length; i++) {
      topPanelsArr[i]
        .setPosition(
          parentWidth / 2,
          panelHeight / 2 + i * panelHeight + scene.mainMenuHeight,
        )
        .layout();
    }
    // .drawBounds(this.add.graphics(), 0xff0000)}
    scene.registry.events.on(
      'changedata',
      (parent, key, data, previousData) => { },
    );
    // Обработчик событий клавиатуры для клавиши пробела
    this.input.keyboard.on('keydown-SPACE', () => {
      this.isSpaceDown = true; // Клавиша пробела зажата
      this.input.setDefaultCursor('grab'); // Меняем курсор на "Рука"
    });

    this.input.keyboard.on('keyup-SPACE', () => {
      this.isSpaceDown = false; // Клавиша пробела отпущена
      this.input.setDefaultCursor('default'); // Возвращаем стандартный курсор
      this.isDragging = false; // Отключаем перетаскивание
    });

    // Включаем интерактивность сцены
    this.input.on('pointerdown', (pointer) => {
      if (!this.isSpaceDown) return; // Проверяем, зажата ли клавиша пробела
      this.dragStartPoint = { x: pointer.x, y: pointer.y };
      this.isDragging = true;
    });

    this.input.on('pointermove', (pointer) => {
      if (!this.isDragging) return;
      const dragX = pointer.x - this.dragStartPoint.x;
      const dragY = pointer.y - this.dragStartPoint.y;
      this.cameras.main.scrollX -= dragX;
      this.cameras.main.scrollY -= dragY;
      this.dragStartPoint = { x: pointer.x, y: pointer.y };
    });

    this.input.on('pointerup', () => {
      this.isDragging = false;
    });

    // Создаем отдельную камеру для UI, которая не будет двигаться
    this.uiCamera = this.cameras.add(0, 0, 150, this.game.scale.height); // 150 - это ширина Toolbar
    this.uiCamera.setScroll(0, 0); // Фиксируем положение камеры для UI
    this.uiCamera.ignore(this.children.list); // Игнорируем все объекты сцены для этой камеры
    //@ts-ignore
    const mainMenu = CreateMainMenu(scene, buttonArray);//toolbar находится здесь потому что он должен создаваться после инициализации UI камеры
    //@ts-ignore
    const toolbar = CreateToolbar(scene, toolbarButtons);
    const Dom = CreateDOM(scene, content);
    Dom.setPosition(500, 500);
    // Dom.setDepth(1000);

    // const Dom2 = this.rexUI.add.sizer({
    //   x: 400, y: 300,
    //   width: 400, height: 40,
    //   orientation: 'y',
    // })
    //   .addBackground(
    //     this.rexUI.add.roundRectangle(0, 0, 1, 1, 0, 0x4e342e)
    //   )
    //   .add(this.add.text(0, 0, 'Header'))
    //   .add(Dom)
    //   .add(this.add.text(0, 0, 'Footer'))
    //   .layout();

    this.cameras.main.ignore(mainMenu);
    this.cameras.main.ignore(toolbar);
    //this.cameras.main.ignore([Dom]);


  }
}


//Создаем анимацию загрузки канваса
class LoadingAnimation extends Phaser.Scene {
  private sprites: Phaser.GameObjects.Sprite[] = [];
  private currentIndex: number = 0;

  constructor() {
    super({
      key: 'loading-animation',
    });
  }

  preload() {
    //Фоновый цвет
    this.cameras.main.setBackgroundColor('#c5d0e6');
    //Спрайты
    this.load.image('sprite1', 'sprite/Sp1.png');
    this.load.image('sprite2', 'sprite/Sp2.png');
    this.load.image('sprite3', 'sprite/Sp3.png');
    this.load.image('sprite4', 'sprite/Sp4.png');
    this.load.image('sprite5', 'sprite/Sp5.png');
    this.load.image('sprite6', 'sprite/Sp6.png');
    this.load.image('sprite7', 'sprite/Sp7.png');
  }

  create() {
    //Используем закрытие
    var scene = this;
    //@ts-ignore
    this.onClose = function (onComplete) {
      scene.tweens.add({
        targets: this.sprites[0],
        scale: 0,
        duration: 1000,
        onComplete: onComplete
      });
    };
    // Создание спрайтов и добавление их в сцену
    this.sprites = Array.from({ length: 7 }, (_, i) =>
      this.add.sprite(window.innerWidth / 2, window.innerHeight / 2, `sprite${i + 1}`).setVisible(false).setScale(0.4)
    );
    // Запуск циклической смены спрайтов
    this.nextSprite();
  }

  nextSprite() {
    const currentSprite = this.sprites[this.currentIndex];
    const nextIndex = (this.currentIndex + 2) % this.sprites.length;
    const nextSprite = this.sprites[nextIndex];

    // Анимация появления следующего спрайта
    this.tweens.add({
      targets: currentSprite,
      scale: 0.4,
      //scaleX: { start: 0, to: 1 },
      //scaleY: { start: 0, to: 1 },
      duration: 100,
      onComplete: () => {
        currentSprite.setVisible(false);
        nextSprite.setVisible(true);
        this.tweens.add({
          targets: nextSprite,
          duration: 200,
          onComplete: () => {
            // Переход к следующему спрайту после завершения анимации
            this.currentIndex = nextIndex;
            this.nextSprite();
          },
        });
      },
    });
  }
}
const config = getPhaserConfig([EndlessCanvas, LoadingAnimation]);


export default {
  name: 'EndlessCanvas',
  data() {
    return {
      wsSubscribe: null,
      game: null,
    };
  },
  computed: {
    ...mapState(useKanvasoStore, {
      project: 'getKanvaso',
    }),
    currentProject() {
      return this.project ? this.project[0]?.node : null;
    },
    projectUuid() {
      return this.$route?.params?.uuid || '';
    },
  },

  methods: {
    ...mapActions(useKanvasoStore, [
      'onGetKanvasoFull',
      'onEditKanvasoObjekto',
      'onEditKanvaso',
      'onEditKanvasoLigilo',
      'onGetKanvasoObjekto',
      'onKanvasoSubscribe',
    ]),
    resizeHandler() {
      const container = document.getElementById('phaser-container');
      container.style.width = window.innerWidth + 'px';
      container.style.height = window.innerHeight + 'px';
      const canvas = container.querySelector('canvas');
      canvas.style.width = window.innerWidth + 'px';
      canvas.style.height = window.innerHeight + 'px';
      //FIXME: Ещё можно способом ниже изменять напрямую размеры холста, но это не даёт нужного результата. Размер меняется, но по краям появляются чёрные полосы :(
      // //@ts-ignore
      // canvas.attributes.width.value = window.innerWidth;
      // //@ts-ignore
      // canvas.attributes.height.value = window.innerHeight;

      // console.log(
      this.game.scale.resize(window.innerWidth, window.innerHeight);
      // );
    },
  },
  async mounted() {
    interface KanvasojKanvasoResult {
      data?: {
        kanvasojKanvaso?: KanvasojKanvaso;
      };
    }
    document.getElementsByTagName('body')[0].style.overflow = 'hidden';

    await this.onGetKanvasoFull({ uuid: this.projectUuid })
      .then((result: KanvasojKanvasoResult) => {
        if (!result.data.kanvasojKanvaso.edges.length) {
          throw new Error(result.toString());
        }
        this.onKanvasoSubscribe({
          kanvasoj: [this.currentProject.objId],
        }).then((data: any) => {
          this.wsSubscribe = data;
        });
      })
      .catch((err: any) => {
        console.log('error get kanvaso full :>> ', err);
        this.$router.replace({ name: 'projects' });
      });
    await this.onGetKanvasoObjekto({ kanvaso_Uuid: this.projectUuid });

    window.addEventListener('resize', this.resizeHandler);
    window.router = this.$router;
    this.game = new Phaser.Game(config);
    // window.addEventListener('resize', function (event) {
    //   console.log('resize');
    //   game.scale.resize(
    //     window.innerWidth < 600 ? window.innerWidth : window.innerWidth - 205,
    //     window.innerWidth < 600
    //       ? window.innerHeight - 51
    //       : window.innerHeight - 10,
    //   );
    // });
    // setInterval(() => {
    //   game.scale.resize(
    //     window.innerWidth < 600 ? window.innerWidth : window.innerWidth - 205,
    //     window.innerWidth < 600
    //       ? window.innerHeight - 51
    //       : window.innerHeight - 10,
    //   );
    // }, 100);
  },
  beforeUnmount() {
    this.wsSubscribe.unsubscribe();
    document.getElementsByTagName('body')[0].style.overflow = 'auto';
    this.game.destroy();
    delete window.router;
  },
};
</script>
<style>
#phaser-container>canvas {
  margin-top: 0 !important;
}
</style>
