import React from 'react';
import { observer } from 'mobx-react';
import './GamePage.less';
import { Button } from "@grace/ui";

import { Application, Assets, Texture, TextureGCSystem, TexturePool, Ticker } from "pixi.js";
import { Tween } from "./tween";

import { initBundle } from "@/pages/GamePage/Helper.ts";
import MusicBtn from "@/core/components/MusicBtn/MusicBtn.tsx";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
import { Game } from "@/pages/GamePage/Game.ts";
import { winSize } from "@/pages/GamePage/config/Config.ts";

import { Stats } from 'pixi-stats';

import { System } from 'detect-collisions';
import gameStore from "@/store/gameStore.ts";
import { prefixInteger } from "@/utils/utils.ts";
import { ModalCtrl } from "@/core/ctrls/ModalCtrl.tsx";
import BackPanel from "@/panels/BackPanel/BackPanel.tsx";
import { SvgaPlayer } from "@grace/svgaplayer";


import preCd from "./../../assets/GamePage/5倒计时.svga";

export const collisionSys: System = new System();
const DEBUG = true ;


let gameCanvas: HTMLCanvasElement = null;

export function getApp(): Application {
  return window["__app"];
}

@observer
class GamePage extends React.Component {

  gameOver: boolean = false;

  state = {
    showPreCd: true,
  }

  gameDiv: HTMLDivElement = null;

  debugCanvas: HTMLCanvasElement = null;
  debugCtx: CanvasRenderingContext2D = null;

  app: Application = null;
  game: Game = null;
  interval: any = 0;

  paused: boolean = true;

  async componentDidMount() {
    gameStore.reset();

    await initBundle();

    this.initEvent();

    if (DEBUG) {
      this.debugCtx = this.debugCanvas.getContext("2d");
      this.debugCanvas.width = winSize.width;
      this.debugCanvas.height = winSize.height;
    }

    await this.initStage();

    this.startCd();

    this.setState({ showPreCd: true });

  }

  startCd = () => {
    this.interval = setInterval(() => {
      if (this.paused) return;

      gameStore.gameInfo.cd -= 1;
      if (gameStore.gameInfo.cd <= 0) {
        clearInterval(this.interval);
        gameStore.gameInfo.cd = 0;
        this.gameOver = true;
        gameStore.submit();
      }
    }, 1000);
  }

  initEvent() {
  }

  componentWillUnmount() {
    this.gameDiv.removeChild(gameCanvas);

    collisionSys.clear();
    Tween.removeAllTweens();

    this.app.ticker.remove(this.onUpdate);
    this.game.removeFromParent();
    this.game.destroy();
  }

  async initStage() {

    if (!gameCanvas) {
      gameCanvas = document.createElement("canvas");
      gameCanvas.className = "gameCanvas";
    }

    this.gameDiv.appendChild(gameCanvas);

    if (!window["__app"]) {
      const app = window["__app"] = new Application();
      await app.init({
        canvas: gameCanvas,
        backgroundColor: 0xffffff,
        width: winSize.width,
        height: winSize.height,
        powerPreference: "high-performance",
        // resolution: Math.min(window.devicePixelRatio, 2) || 1,
        resolution: 1,
        preference: "webgl",
        webgl: {
          // preserveDrawingBuffer: true,
          // antialias: true,
        },
        eventMode: "static",
      });

      app.renderer.accessibility.destroy();
    }

    const app = this.app = window["__app"];

    if (DEBUG) {
      const stats = new Stats(app.renderer);
    }

    await Assets.loadBundle("Game");

    this.app.ticker.add(this.onUpdate);

    this.game = app.stage.addChild(new Game());

  }

  onUpdate = (time: Ticker) => {
    if (this.gameOver) return;
    if (this.paused) return;

    Tween.flush();
    this.game.onUpdate(time);
    collisionSys.update();

    if (DEBUG) {
      this.debugCtx.clearRect(0, 0, winSize.width, winSize.height);
      this.debugCtx.strokeStyle = "#FF0000";
      this.debugCtx.beginPath();
      collisionSys.draw(this.debugCtx);
      collisionSys.drawBVH(this.debugCtx);
      this.debugCtx.stroke();
    }

  };

  /**
   * 点击返回
   */
  clickBack = () => {
    this.gameOver = true;
    ModalCtrl.showModal(BackPanel, {
      cancel: () => {
        this.gameOver = false;
      },
      ok: () => {
        this.gameOver = false;
        clearInterval(this.interval);
        PageCtrl.backPage();
      },
    });
  }

  onPreCdEnd = () => {
    this.paused = false;
    this.setState({
      showPreCd: false,
    })
  }

  render() {

    const { showPreCd } = this.state;
    const { score, cd } = gameStore.gameInfo;

    const min = prefixInteger(Math.floor(cd / 60), 2);
    const sec = prefixInteger(cd % 60, 2);

    return <div className="GamePage">
      <div className="gameBg"/>
      <div className="gameDiv" ref={(el) => this.gameDiv = el}/>
      {
        DEBUG && <canvas
          className="gameCanvas debugCanvas"
          ref={(el) => this.debugCanvas = el}
        />
      }
      <div className="scoreArea">
        <div className="scoreNum">{score}</div>
      </div>
      <div className="cd">
        <div className="cdNum">{min}:{sec}</div>
      </div>
      <MusicBtn className="musicBtn"/>
      <Button className="backBtn" onClick={this.clickBack}/>
      {showPreCd && <div className="preCdBg">
        <SvgaPlayer className="preCd" loop={1} src={preCd} onEnd={this.onPreCdEnd}/>
      </div>}
    </div>;
  }
}

export default GamePage;
