import Phaser from "phaser";
import Graphics from "../assets/Graphics";

const attackSpeed = 500;
const attackDuration = 165;
const attackCooldown = attackDuration * 2;

interface Keys {
  up: Phaser.Input.Keyboard.Key;
  down: Phaser.Input.Keyboard.Key;
  left: Phaser.Input.Keyboard.Key;
  right: Phaser.Input.Keyboard.Key;
  space: Phaser.Input.Keyboard.Key;
  w: Phaser.Input.Keyboard.Key;
  a: Phaser.Input.Keyboard.Key;
  s: Phaser.Input.Keyboard.Key;
  d: Phaser.Input.Keyboard.Key;
}

export default class Player {
  public sprite: Phaser.Physics.Arcade.Sprite;
  private keys: Keys;

  private attackUntil: number;
  private attackLockedUntil: number;
  private emitter: Phaser.GameObjects.Particles.ParticleEmitter;
  private body: Phaser.Physics.Arcade.Body;

  constructor(x: number, y: number, scene: Phaser.Scene) {
	this.damage = +localStorage.playerDamage;
    this.sprite = scene.physics.add.sprite(x, y, Graphics.player.name, 0);
    this.sprite.setSize(8, 8);
    this.sprite.setOffset(12, 20);
    this.sprite.anims.play(Graphics.player.animations.idle.name);
	this.hp = +localStorage.playerHp;
	this.maxhp = +localStorage.playerMaxHp;
	this.alive = true;
	this.speed = +localStorage.playerSpeed;

    this.keys = scene.input.keyboard.addKeys({
      up: Phaser.Input.Keyboard.KeyCodes.UP,
      down: Phaser.Input.Keyboard.KeyCodes.DOWN,
      left: Phaser.Input.Keyboard.KeyCodes.LEFT,
      right: Phaser.Input.Keyboard.KeyCodes.RIGHT,
      space: Phaser.Input.Keyboard.KeyCodes.SPACE,
      w: "w",
      a: "a",
      s: "s",
      d: "d"
    }) as Keys;

    this.attackUntil = 0;
    this.attackLockedUntil = 0;
    const particles = scene.add.particles(Graphics.player.name);
    this.emitter = particles.createEmitter({
      alpha: { start: 0.7, end: 0, ease: "Cubic.easeOut" },
      follow: this.sprite,
      quantity: 1,
      lifespan: 200,
      blendMode: Phaser.BlendModes.ADD,
      scaleX: () => (this.sprite.flipX ? -1 : 1),
      emitCallback: (particle: Phaser.GameObjects.Particles.Particle) => {
        particle.frame = this.sprite.frame;
      }
    });
    this.emitter.stop();

    this.body = <Phaser.Physics.Arcade.Body>this.sprite.body;
  }

  update(time: number) {
	var speed = this.speed;
    const keys = this.keys;
    let attackAnim = "";
    let moveAnim = "";

    if (time < this.attackUntil) {
      return;
    }
    this.body.setVelocity(0);

    const left = keys.left.isDown || keys.a.isDown;
    const right = keys.right.isDown || keys.d.isDown;
    const up = keys.up.isDown || keys.w.isDown;
    const down = keys.down.isDown || keys.s.isDown;
	
	if (keys.space.isDown) {
		window.dialogOpen = false;
		window.synth.play();
	}
	
	if (window.dialogOpen) {
		return;
	}

	if (this.hp > 0) {
		if (!this.body.blocked.left && left) {
		  this.body.setVelocityX(-speed);
		  this.sprite.setFlipX(true);
		} else if (!this.body.blocked.right && right) {
		  this.body.setVelocityX(speed);
		  this.sprite.setFlipX(false);
		}

		if (!this.body.blocked.up && up) {
		  this.body.setVelocityY(-speed);
		} else if (!this.body.blocked.down && down) {
		  this.body.setVelocityY(speed);
		}

		if (left || right) {
		  moveAnim = Graphics.player.animations.walk.name;
		  attackAnim = Graphics.player.animations.slash.name;
		} else if (down) {
		  moveAnim = Graphics.player.animations.walk.name;
		  attackAnim = Graphics.player.animations.slashDown.name;
		} else if (up) {
		  moveAnim = Graphics.player.animations.walkBack.name;
		  attackAnim = Graphics.player.animations.slashUp.name;
		} else {
		  moveAnim = Graphics.player.animations.idle.name;
		}

		if (time > this.attackLockedUntil && keys.space!.isDown && this.body.velocity.length() > 0) {
			this.attackUntil = time + attackDuration;
			this.attackLockedUntil = time + attackDuration + attackCooldown;
			window.dash.play();
			this.body.velocity.normalize().scale(attackSpeed);
			this.sprite.anims.play(attackAnim, true);
			this.emitter.start();
			this.sprite.setBlendMode(Phaser.BlendModes.ADD);
		} else if (time > this.attackLockedUntil && this.body.world.scene.game.input.activePointer.isDown) {
			this.attackUntil = time + attackDuration;
			this.attackLockedUntil = time + attackDuration + attackCooldown;
			this.body.velocity.normalize().scale(speed);
			this.sprite.setBlendMode(Phaser.BlendModes.NORMAL);
			if (this.emitter.on) {
				this.emitter.stop();
			}
			attackAnim = Graphics.player.animations.attack.name;
			this.sprite.anims.play(attackAnim, true);
			for (var i = 0; i < window.enemy1.length; ++i) {
				var enemy = window.enemy1[i];
				if (enemy.alive && Phaser.Math.Distance.Between(enemy.sprite.x, enemy.sprite.y, this.sprite.x, this.sprite.y) < 25) {
					window.hit.play();
					this.body.setVelocity(0);
					enemy.sprite.setTint(0x000000);
					enemy.hp = enemy.hp - this.damage;
					clearTimeout(enemy.timeoutRed);
					var curEnemy = enemy;
					enemy.timeoutRed = setTimeout(function() {
						curEnemy.sprite.setTint(0xffffff);
					}, 100);
				}
			}
		} else {
			this.sprite.anims.play(moveAnim, true);
			this.body.velocity.normalize().scale(speed);
			this.sprite.setBlendMode(Phaser.BlendModes.NORMAL);
			if (this.emitter.on) {
				this.emitter.stop();
			}
		}
	} else {
		if (this.alive) {
			this.alive = false;
			
			if(localStorage.deaths === undefined) {
				localStorage.deaths = "1";
			} else {
				window.deaths = localStorage.deaths;
				window.deaths++;
				localStorage.deaths = window.deaths;
			}
			console.log("localStorage.deaths: "+localStorage.deaths);
			console.log("window.deaths: "+window.deaths);
			localStorage.playerHp = 50;
			moveAnim = Graphics.player.animations.death.name;
			this.body.setVelocity(0);
			this.sprite.setBlendMode(Phaser.BlendModes.NORMAL);
			if (this.emitter.on) {
				this.emitter.stop();
			}
			this.sprite.anims.play(moveAnim, true);
		}
	}
	this.sprite.depth = this.sprite.y;
  }
}
