export class Player extends Phaser.GameObjects.Sprite {
    constructor(scene, x, y, texture, frame) {
        super(scene, x, y, 'player-tiles');

        scene.add.existing(this);
        scene.physics.world.enable(this);
        this.body.setSize(50,100);

        // Initialize variables
        this.pauseMove = false;
        this.isTakingDamage = false;
        this.showHealth = false;
        this.healthText;
        this.healthImages;
        this.numHearts = scene.game.globalState.hearts;
        this.maxHearts = scene.game.globalState.maxHearts;
        this.normalVelocityX = 260;
        this.inventory = [];
        this.facing = 'south';
        this.isAttacking = false;
        this.isFiring = false;
        this.axe;
        this.bullet;
        this.texturePlus = 24;

        // Create animations
        this.anims.create({
            key: 'north',
            frames: this.anims.generateFrameNumbers('player-tiles', { start: 0+this.texturePlus, end: 1+this.texturePlus }),
            frameRate: 5,
            repeat: -1
        });

        this.anims.create({
            key: 'side',
            frames: this.anims.generateFrameNumbers('player-tiles', { start: 8+this.texturePlus, end: 9+this.texturePlus }),
            frameRate: 5,
            repeat: -1
        });

        this.anims.create({
            key: 'south',
            frames: this.anims.generateFrameNumbers('player-tiles', { start: 16+this.texturePlus, end: 17+this.texturePlus }),
            frameRate: 5,
            repeat: -1
        });

        this.anims.create({
            key: 'idle',
            frames: [
                { key: 'player-tiles', frame: 0+this.texturePlus }
            ],
            frameRate: 5,
            duration: 1500,
            repeat: -1
        });

        this.anims.create({
            key: 'death',
            frames: [
                { key: 'player-tiles', frame: 3+this.texturePlus }
            ],
            frameRate: 5,
            duration: 1500,
            repeat: -1
        });

        this.anims.create({
            key: 'death2',
            frames: [
                { key: 'player-tiles', frame: 4+this.texturePlus }
            ],
            frameRate: 5,
            duration: 1500,
            repeat: -1
        });

        this.scene.input.keyboard.on('keydown-A', this.attack, this);
    }

    update() {
        // Movement Debug:
        // console.log(this.body.x + " " + this.body.y);

        if (this.pauseMove === true) {
            this.body.setVelocity(0);
        } else {
            // Movement: Up/Down:
            if (this.scene.cursors.up.isDown) {
                this.body.setVelocityY(-200);
                this.anims.play('south', true);
                this.facing = 'south';
            } else if (this.scene.cursors.down.isDown) {
                this.body.setVelocityY(200);
                this.anims.play('north', true);
                this.facing = 'north';
            } else {
                this.body.setVelocityY(0);
            }

            // Movement: Left/Right:
            if (this.scene.cursors.left.isDown) {
                this.body.setVelocityX(-200);
                this.setFlipX(false);
                this.anims.play('side', true);
                this.facing = 'west';
            } else if (this.scene.cursors.right.isDown) {
                this.body.setVelocityX(200);
                this.setFlipX(true);
                this.anims.play('side', true);
                this.facing = 'east';
            } else {
                this.body.setVelocityX(0);
            }

            // Idle
            if (this.body.velocity.x === 0 && this.body.velocity.y === 0) {
                this.anims.play('idle', true);
            }
        }        
    }

    attack() {
        if (this.isAttacking === true) {
            return;
        }

        let axeAngle = this.body.angle

        this.isAttacking = true;
        this.pauseMove = true;

        // Determine the direction the player is facing
        let offsetX = 0;
        let offsetY = 0;
        let flip = false;
        let rotate = 0;
        let direction = 360;
        let velocX = 0;
        let velocY = 0;


        if (this.facing === 'west') {
            offsetX = -100;
            flip = true; 
            direction = -360;
            velocX = -1500;
        } else if (this.facing === 'east') {
            offsetX = +100;
            velocX = 1500;
        } else if (this.facing === 'north') {
            offsetY = +100;
            rotate = 90;
            velocY = 1500;
        } else if (this.facing === 'south') {
            offsetY = -100;
            rotate = 9;
            velocY = -1500;
        }

        // Create a rectangle for the attack area in front of the player
        const attackArea = new Phaser.Geom.Rectangle(
            this.x + offsetX,
            this.y + offsetY,
            100, // width
            100  // height
        );

        // Add Axe
        this.axe = this.scene.physics.add.sprite(attackArea.x, attackArea.y, 'player-tiles', 2);
        this.scene.axes.add(this.axe);
        this.axe.setFlipX(flip);
        this.axe.setAngle(rotate);
        this.axe.setVelocity(velocX / 4, velocY / 4);
        this.scene.tweens.add({
            targets: this.axe,
            scale: 1, // 110% of original size
            angle: direction+rotate, // Spin clockwise once (360 degrees)
            duration: 1000,
            ease: 'Power2'
        });
        this.scene.sound.play('axeThrow');

        // Add Bullet if hearts are full
        if (this.numHearts >= 3 && this.isFiring === false) {
            this.bullet = this.scene.physics.add.sprite(attackArea.x, attackArea.y, 'player-tiles', 10);
            this.scene.bullets.add(this.bullet)
            this.bullet.setFlip(flip);
            this.bullet.setAngle(rotate);
            this.bullet.setVelocity(velocX, velocY);
            this.scene.sound.play('gunShot');
            this.isFiring = true;
            this.scene.physics.world.enable(this.bullet);
            
        }

        // Reset attack ability after a delay
        this.scene.time.delayedCall(500, () => {
            this.pauseMove = false;
            this.axe.destroy();
            this.isAttacking = false;
            if (this.bullet) {
                this.bullet.destroy();
            }
        });
        if (this.isFiring === true) {
            this.scene.time.delayedCall(2000, () => {
                this.isFiring = false;
            });
        }
    }

    healthBars(showHealth, Hearts, Lives) {
        this.showHealth = showHealth;
        if (this.showHealth === true) {
            this.healthText = this.scene.add.text(16, 16, 'Health: ', { fontSize: '36px', fill: '#FFF' })
                .setShadow(3,3, '#333', 5)
                .setScrollFactor(0);
            this.updateHealth();
            
        }
    }

    takeDamage(fromObject) {
        if (this.isTakingDamage) {
            return;
        }

        this.isTakingDamage = true;
        this.scene.sound.play('player-damage');
        this.scene.tweens.add({
            targets: this,
            tint: 0xaaaaff,
            duration: 1000,
            repeat: 0,
            yoyo: true,
            ease: 'Power1'
        });

        this.numHearts -= 1;
        if (this.numHearts > 0) {
            this.updateHealth();
        } else {
            this.updateHealth();
            this.pauseMove = true;
            this.anims.play('death');
            this.body.enable = false;
            this.scene.tweens.add({
                targets: this,
                angle: 720, // Spin clockwise once (360 degrees)
                duration: 1500,
                ease: 'Power2',
                onComplete: () => {
                    this.anims.play('death2');
                    // Add animation to lower player by 20px
                    this.scene.tweens.add({
                        targets: this,
                        y: '+=20',
                        duration: 1000,
                        ease: 'Power1'
                    });
                    // Fade out the camera and restart the scene
                    this.scene.cameras.main.fade(1500, 0, 0, 0, true);
                    this.scene.time.delayedCall(1500, () => {
                        this.scene.bgMusic.stop();
                        this.scene.scene.restart();
                    });
                }
            });
        }

        // Knockback

        // Reset taking damage state after a delay
        this.scene.time.delayedCall(1000, () => {
            this.isTakingDamage = false;
            this.pauseMove = false;
        });
    }

    addHealth(amount) {
        // this.maxHearts ++;
        // this.scene.game.playerData.maxHearts = this.maxHearts;
        if (this.numHearts < this.maxHearts) {
            this.numHearts += 1;
            this.updateHealth();
            this.scene.sound.play('health-pickup');
        }
    }

    updateHealth() {
        if (!this.showHealth) {
            return;
        }
        if (this.healthImages) {
            this.healthImages.destroy(true);
        }
        
        this.healthImages = this.scene.add.group();
        let startX = 170;
        
        // Add full hearts
        for (let i = 0; i < this.numHearts; i++) {
            this.healthImages.add(this.scene.add.image(startX, 15, 'heart-full').setOrigin(0, 0).setScale(.5).setScrollFactor(0));
            startX += 48;
        }

        // Add empty hearts for the remaining slots
        for (let i = this.numHearts; i < this.maxHearts; i++) {
            this.healthImages.add(this.scene.add.image(startX, 15, 'heart-empty').setOrigin(0, 0).setScale(.5).setScrollFactor(0));
            startX += 48;
        }
    }

    addItemToInventory(itemKey) {
        if (!this.inventory[itemKey]) {
            this.inventory[itemKey] = 1; // Create the item with a quantity of 1
        } else {
            this.inventory[itemKey]++; // Increment the quantity if it already exists
        }
    }

    removeItemFromInventory(itemKey) {
        if (this.inventory[itemKey]) {
            this.inventory[itemKey]--;
            if (this.inventory[itemKey] <= 0) {
                delete this.inventory[itemKey]; // Remove the item if its quantity is zero or less
            }
        }
    }

    hasItem(itemKey) {
        return this.inventory[itemKey] && this.inventory[itemKey] > 0;
    }

    getInventory() {
        return this.inventory; // Return a copy of the inventory to prevent direct modification
    }
}