import Cog from "@robotical/webapp-types/dist-types/src/application/RAFTs/Cog/Cog";
import { getConnectedCog } from "../../utils/CogManager";
import PlayScene from "../scenes/PlayScene";

export class Player extends Phaser.Physics.Arcade.Sprite {
  scene: PlayScene;
  jumpSound: Phaser.Sound.HTML5AudioSound | undefined;
  hitSound: Phaser.Sound.HTML5AudioSound | undefined;

  constructor(scene: PlayScene) {
    const x = 0;
    const y = 0;
    super(scene, x, y, "marty-waist");
    this.scene = scene;

    this.anims.create({
      key: 'run',
      frames: [
        { key: 'marty-waist', duration: 100 },
        { key: 'marty-running', duration: 100 },
      ],
      frameRate: 24, // adjust as needed for the desired speed
      repeat: -1
    });

    scene.add.existing(this);
    scene.physics.add.existing(this);

    this.init();
    this.scene.events.on(Phaser.Scenes.Events.UPDATE, this.update, this);
  }

  init() {
    if (!this.scene.input.keyboard) return;
    const gravity = 2000 * (this.scene.sky?.scaleFactors.height || 1);
    this
      .setOrigin(0.5, 1)  // Origin at the bottom center of the player
      .setGravityY(gravity)
      .setCollideWorldBounds(true)
      .setBodySize(90, 140)
      .setOffset(35, 20)
      .setDepth(4);

    this.registerSounds();

    // Handle resizing
    this.scene.scale.on('resize', this.scaleToFit, this);
    this.scene.scale.on('resize', this.positionOnSky, this);

    this.scaleToFit();
    this.positionOnSky();
  }

  positionOnSky() {
    const gameHeight = this.scene.scale.height;

    // Position player at the bottom of the scaled background
    const skyHeight = this.scene.scale.height;
    const y = gameHeight - (gameHeight - skyHeight); // Slight offset for alignment
    this.setY(y - 10);
    this.setX(100 * (this.scene.sky?.scaleFactors.width || 1));
  }

  scaleToFit() {
    // Use the scale factor from the Sky class to maintain consistency
    const scaleFactor = this.scene.sky?.scaleFactors.height || 1;
    const width = 185;
    const height = 185;

    // Apply the scale factor to the player
    this.setDisplaySize(width * scaleFactor, height * scaleFactor);
  }

  getStartTrigger(): boolean {
    /* If the player is connected to a cog, use the cog's buttonClick state to determine if the player should jump / start the game */
    /* Otherwise, use the space key to determine if the player should jump / start the game */
    const connectedCog = getConnectedCog();
    if (connectedCog) {
      return (connectedCog as Cog).publishedDataAnalyser.cogState.buttonClick === "click";
    } else {
      return false; // remove this line and comment in below if you want to use the space key to jump when not connected to a cog
      // if (!this.scene.cursors) return false;
      // const { space } = this.scene.cursors;
      // const isSpaceJustDown = Phaser.Input.Keyboard.JustDown(space);
      // return isSpaceJustDown;
    }
  }

  actionDecider(isCogsButtonClickedOrSpaceDown: boolean, onFloor: boolean) {
    if (!isCogsButtonClickedOrSpaceDown) return;
    if (this.scene.currentlySectedBlock?.block === "moveforward") {
      this.moveForward();
    } else if (this.scene.currentlySectedBlock?.block === "movebackward") {
      this.moveBackward();
    } else if (this.scene.currentlySectedBlock?.block === "jump") {
      this.jump(onFloor);
    }
  }

  async moveBackward() {
    const move = 10;
    for (let i = 0; i < move; i++) {
      this.setX(this.x - 1);
      await new Promise((resolve) => setTimeout(resolve, 10));
    }
  }

  async moveForward() {
    const move = 10;
    for (let i = 0; i < move; i++) {
      this.setX(this.x + 1);
      await new Promise((resolve) => setTimeout(resolve, 10));
    }
  }

  jump(onFloor: boolean) {
    if (onFloor) {
      const jumpVelocity = -1200 * (this.scene.sky?.scaleFactors.height || 1);
      this.setVelocityY(jumpVelocity);
      this.jumpSound?.play();
      this.setTexture("marty-jump");
    }

  }

  update() {
    const isCogsButtonClickedOrSpaceDown = this.getStartTrigger();

    // if (isCogsButtonClickedOrSpaceDown && !this.scene.isGameRunning && !this.scene.isGameOverVisible) {
    //   this.scene.handleGameStart();
    // }

    if (!this.scene.isGameRunning) {
      this.anims.pause();
      return;
    }

    
    const onFloor = (this.body as Phaser.Physics.Arcade.Body).onFloor();
    this.actionDecider(isCogsButtonClickedOrSpaceDown, onFloor);

    // Play proper animation based on state
    if (onFloor) {
      // Play the running animation if not already playing.
      // Make sure an animation with key "run" is defined in your scene.
      if (!this.anims.isPlaying || this.anims.currentAnim?.key !== 'run') {
        this.anims.play('run', true);
      }
    } else {
      // If in the air, display the jump texture.
      this.setTexture("marty-jump");
    }
  }

  registerSounds() {
    this.jumpSound = this.scene.sound.add("jump", { volume: 0.3 }) as Phaser.Sound.HTML5AudioSound;
    this.hitSound = this.scene.sound.add("hit", { volume: 0.4 }) as Phaser.Sound.HTML5AudioSound;
  }

  die() {
    this.anims.pause();
    this.setTexture("marty-hurt");
    this.hitSound?.play();
  }
}
