text: import Creature from "./Creature";
  import { getLootTypeByName } from "../constants/lootTypes";
  
  const PLAYER_SPEED = 250;
  
  export default class Hero extends Creature {
      constructor(scene, position, properties, attributes) {
          super(scene, 'hero', position, properties, attributes);
  
          this.currentXP = 0;
          this.level = 1;
          this.isAmuletHealing = true;
          this.isFighting = false;
  
          this.play('heroRun');
          this.initAnimationEvents();
  
          this.scene.physics.add.collider(this, this.scene.enemy, this.fight, null, this);
  
          this.blockText = this.scene.add.text(this.x + this.body.width / 2, this.y, 'блок', {
              fontSize: 48,
              fontStyle: 'bold'
          })
              .setScrollFactor(0)
              .setOrigin(0.5)
              .setAlpha(0);
          this.blockTween = this.scene.tweens.add({
              targets: this.blockText,
              x: '+=0',
              y: '-=50',
              alpha: { start: 1, to: 0 },
              repeat: 0,
              duration: 600,
              ease: 'easeInExpo',
              paused: true
          });
  
          this.lifeStealText = this.scene.add.text(this.x + this.body.width / 2, this.y, '', {
              fontSize: 54,
              color: '#00FF00',
              stroke: '#000000',
              strokeThickness: 2,
          })
              .setScrollFactor(0)
              .setOrigin(0.5)
              .setAlpha(0);
          this.lifeStealTween = this.scene.tweens.add({
              targets: this.lifeStealText,
              x: '+=0',
              y: '-=50',
              alpha: { start: 1, to: 0 },
              repeat: 0,
              duration: 250,
              ease: 'easeInExpo',
              paused: true
          });
  
          this.healText = this.scene.add.text(this.x + this.body.width / 2, this.y, '+1', {
              fontSize: 54,
              color: '#00FF00',
              stroke: '#000000',
              strokeThickness: 2,
          })
              .setScrollFactor(0)
              .setOrigin(0.5)
              .setAlpha(0);
          this.healTween = this.scene.tweens.add({
              targets: this.healText,
              y: this.y - 50,
              alpha: { start: 1, to: 0 },
              loop: -1,
              duration: 1000,
              ease: 'easeInExpo',
              paused: true,
              onActive: () => {
                  this.healFromAmulet();
              },
              onLoop: () => {
                  if (!this.isAmuletHealing) {
                      this.healTween.stop();
                      this.healText.text = '';
                      return;
                  }
  
                  this.healFromAmulet();
              }
          });
  
          this.healFromPotionText = this.scene.add.text(this.x + this.body.width / 2, this.y, '', {
              fontSize: 54,
              color: '#00FF00',
              stroke: '#000000',
              strokeThickness: 2,
          })
              .setScrollFactor(0)
              .setOrigin(0.5)
              .setAlpha(0);
          this.healFromPotionTween = this.scene.tweens.add({
              targets: this.healFromPotionText,
              y: this.y - 50,
              alpha: { start: 1, to: 0 },
              repeat: 0,
              duration: 250,
              ease: 'easeInExpo'
          });
  
          this.damageText.setScrollFactor(0);
  
          this.scene.events.on('enemyIsDied', () => {
              this.currentXP += 25;
              this.scene.events.emit('updateExperienceBar');
  
              this.scene.physics.world.enableBody(this);
              this.play('heroRun');
  
              if (this.scene.character.items[getLootTypeByName.AMULET]) this.startHealing();
          });
  
          this.scene.events.on('heroBlocked', () => {
              this.blockTween.play();
          });
      }
  
      update() {
          this.body.setVelocityX(PLAYER_SPEED);
      }
  
      fight() {
          this.isAmuletHealing = false;
          this.isFighting = true;
          this.play('heroAttack');
          this.scene.enemy.play(this.scene.enemy.name + 'Attack');
          this.scene.physics.world.disableBody(this.body);
          this.scene.physics.world.disableBody(this.scene.enemy.body);
      }
  
      initAnimationEvents() {
          this.on('animationrepeat', currentAnimation => {
              if (currentAnimation.key === 'heroAttack') {
                  const damage = this.calculateDamage();
                  this.doDamage(this.scene.enemy, damage);
  
                  if (this.scene.character.items[getLootTypeByName.RING] && (this.healthPoints < this.maxHealthPoints)) this.stealLife(damage);
              }
          });
  
          this.on('animationcomplete', currentAnimation => {
              if (currentAnimation.key === 'heroDeath') {
                  // hero is died
              }
          });
      }
  
      calculateDamage() {
          const leftHandSword = this.scene.character.items[getLootTypeByName.TWO_HANDED_SWORD];
          const rightHandSword = this.scene.character.items[getLootTypeByName.SHIELD];
          
          let modificatorLeftHand = 1;
          if (leftHandSword && this.scene.enemy.weakness.includes(leftHandSword.getId())) modificatorLeftHand = 1.5;
          let modificatorRightHand = 1;
          if (rightHandSword && this.scene.enemy.weakness.includes(rightHandSword.getId())) modificatorLeftHand = 1.5;
  
          let damage = Phaser.Math.Between(
              (leftHandSword ? leftHandSword.properties.attack.min + leftHandSword.level * 3 : 0)
              *
              modificatorLeftHand
              + 
              (rightHandSword ? rightHandSword.properties.attack.min + rightHandSword.level * 3 : 0)
              *
              modificatorRightHand,
              (leftHandSword ? leftHandSword.properties.attack.max + leftHandSword.level * 4 : 0)
              *
              modificatorLeftHand
              + 
              (rightHandSword ? rightHandSword.properties.attack.max + rightHandSword.level * 4 : 0)
              *
              modificatorRightHand
          );
  
          return damage;
      }
  
      stealLife(damage) {
          const stoleHealthPoints = Math.round(damage * this.scene.character.items[getLootTypeByName.RING].level * 0.02);
  
          if (stoleHealthPoints) {
              this.healthPoints = Phaser.Math.Clamp(this.healthPoints + stoleHealthPoints, 0, this.maxHealthPoints);
              this.scene.events.emit('updateHealthBar');
              this.lifeStealText.text = '+' + stoleHealthPoints;
              this.lifeStealTween.play();
          }
      }
  
      healFromAmulet() {
          this.healthPoints = Phaser.Math.Clamp(this.healthPoints + this.scene.character.items[getLootTypeByName.AMULET].level, 0, this.maxHealthPoints);
          this.scene.events.emit('updateHealthBar');
      }
  
      startHealing() {
          this.healText.text = '+' + this.scene.character.items[getLootTypeByName.AMULET].level;
          this.isAmuletHealing = true;
          this.healTween.play();
      }
  
      changeSpeedAttack(sword = this.scene.character.items[getLootTypeByName.TWO_HANDED_SWORD], belt = this.scene.character.items[getLootTypeByName.BELT]) {
          const calculatedSpeedAttack = this.calculateSpeedAttack(sword, belt);
  
          if (calculatedSpeedAttack !== this.anims.anims.entries.heroAttack.frameRate) {
              this.anims.remove('heroAttack');
  
              this.anims.create({
                  key: 'heroAttack',
                  frames: this.anims.generateFrameNumbers('hero_attack'),
                  frameRate: calculatedSpeedAttack,
                  repeat: -1
              });
  
              if (this.isFighting) this.play('heroAttack');
          }
      }
  
      calculateSpeedAttack(sword, belt) {
          const swordSpeedPoints = sword ? (sword.lootType === getLootTypeByName.TWO_HANDED_SWORD ? 2 : 4) : (this.scene.character.items[getLootTypeByName.SHIELD] ? 4 : 0);
          const beltSpeedPoints = belt ? belt.level * .2 : 0;
  
          return swordSpeedPoints + beltSpeedPoints;
      }
  
      drinkHealthPotion(healthPotion) {
          const healValue = healthPotion.level * 25;
          this.healFromPotionText.text = healValue;
          this.healFromPotionTween.play();
          this.healthPoints = Phaser.Math.Clamp(this.healthPoints + healValue, 0, this.maxHealthPoints);
          this.scene.events.emit('updateHealthBar');
      }
  }
  