import { Player } from '../characters/player.js';
import { Camera } from '../misc/cameras.js';
import { NNBoy } from '../characters/99boy.js';
import { Interface } from '../interface.js';
 
export class NNDungeon extends Phaser.Scene {

    constructor() {
        super({ key: 'NNDungeon' });

        this.cameras;
        this.player;
        this.cursors = null;
        this.wide = 1600;
        this.tall = 900;
        this.topBound = 1100;
        this.leftBound = 800;
    }

    preload() {
        this.load.image('dungeon-tiles', 'assets/dungeon-tiles.png');
        this.load.image('heart-full', 'assets/heart-full.png');  
        this.load.image('heart-empty', 'assets/heart-empty.png');
        this.load.image('heart-upgrade', 'assets/heart-upgrade.png');    
        this.load.image('proEdgeKey', 'assets/proEdgeKey.png');  
        this.load.tilemapTiledJSON('NNDungeonMap', 'assets/NNDungeon.json'); 
        this.load.spritesheet('player-tiles', 'assets/player-tiles.png', {
            frameWidth: 100, 
            frameHeight: 100 
        });
        this.load.spritesheet('99boy-tiles', 'assets/99boy-tiles.png', {
            frameWidth: 100, 
            frameHeight: 100 
        });
        this.load.spritesheet('boss-tiles', 'assets/boss-tiles.png', {
            frameWidth: 200, 
            frameHeight: 200 
        });
        this.load.spritesheet('99Dungeon-tiles', 'assets/dungeon-tiles.png', {
            frameWidth: 100, 
            frameHeight: 100 
        });

        this.load.audio('dungeonMusic', 'assets/music/99Dungeon.mp3');
        this.load.audio('gunShot', 'assets/sounds/gun-shot.mp3');
        this.load.audio('axeThrow', 'assets/sounds/axe.mp3');
        this.load.audio('health-pickup', 'assets/sounds/health-pickup.mp3');
        this.load.audio('player-damage', 'assets/sounds/player-damage.mp3');
        // 99 Boy Sounds
        this.load.audio('99boy-defeat-0', 'assets/sounds/zombie-death-1.mp3');
        this.load.audio('99boy-defeat-1', 'assets/sounds/zombie-death-2.mp3');
        this.load.audio('99boy-defeat-2', 'assets/sounds/zombie-death-3.mp3');
        this.load.audio('crumple', 'assets/sounds/crumple.mp3');
        this.load.audio('glass-break', 'assets/sounds/glass-break.mp3');
        this.load.audio('swoosh', 'assets/sounds/swoosh.mp3');
    }

    create() {                
        // Load the map and tileset
        const NNDungeonMap = this.make.tilemap({ key: 'NNDungeonMap' });
        const dungeonTiles = NNDungeonMap.addTilesetImage('dungeon-tiles', 'dungeon-tiles');
        const NNTiles = NNDungeonMap.addTilesetImage('99boy-tiles', '99boy-tiles');
        const mainLayer = NNDungeonMap.createLayer('main', dungeonTiles, 0, 0)
            .setCollisionByProperty({ collides: true });
        const objectsLayer = NNDungeonMap.createLayer('objects', dungeonTiles, 0, 0)
            .setCollisionByProperty({ collides: true });
        const enemiesLayer = NNDungeonMap.getObjectLayer('enemies');
        const interactiveLayer = NNDungeonMap.getObjectLayer('interactive');
        const zoneLayer = NNDungeonMap.getObjectLayer('zones');

        // Show Score
        this.interface = new Interface(this);
        this.interface.showScore();

        // Add a player
        this.player = new Player(this, this.game.globalState.startNNX, this.game.globalState.startNNY);
        //this.player = new Player(this, 3550, 350);
        this.player.healthBars(true, 1, 3);

        // Set the exit back to the gulch
        this.game.globalState.startGulchX = 5500;
        this.game.globalState.startGulchY = 1600;

        zoneLayer.objects.forEach(object => {
            if (object.name === 'gulchExit') {
                const Gulch = this.add.rectangle(object.x, object.y, object.width, object.height);
                this.Gulch = this.physics.add.existing(Gulch);
            }
            if (object.name === 'bossSave') {
                const bossSave = this.add.rectangle(object.x, object.y, object.width, object.height);
                this.bossSave = this.physics.add.existing(bossSave);
            }
        });

        // Add Interactive
        this.interactive = this.physics.add.group();
        interactiveLayer.objects.forEach(object => {
            if (object.gid) {
                let inter = this.interactive.create(object.x+50, object.y-50, '99Dungeon-tiles', object.gid-1);
                inter.properties = object.properties;
            } else {
                let inter = this.physics.add.existing(this.add.rectangle(object.x, object.y, object.width, object.height));
                this.interactive.add(inter);
                if (object.properties) {
                    inter.properties = object.properties;
                }
            }
        });

        // Add Enemies
        this.enemies = this.physics.add.group({
            classType: NNBoy,
            runChildUpdate: true
        });
        enemiesLayer.objects.forEach(object => {
            let a99Boy;
            if (object.gid > 300) {
                a99Boy = this.enemies.create(object.x-50, object.y-50, 'boss-tiles', object.gid-301);
            } else {
                a99Boy = this.enemies.create(object.x-50, object.y-50, '99boy-tiles', object.gid-201);
            }
            if (object.properties) {
                object.properties.forEach(prop => {
                    if (prop.name === 'patrolX') {
                        let to = object.x + prop.value;
                        if (to < object.x) {
                            a99Boy.setPatrolX(to, object.x);
                        } else {
                            a99Boy.setPatrolX(object.x, to);
                        }
                    }
                    if (prop.name === 'patrolY') {
                        let to = object.y + prop.value;
                        if (to < object.y) {
                            a99Boy.setPatrolY(to-100, object.y-100);
                        } else {
                            a99Boy.setPatrolY(object.y-100, to-100);
                        }
                    }
                    if (prop.name === 'fire') {
                        a99Boy.shoots = true;
                        a99Boy.bottleReload = prop.value;
                    }
                    if (prop.name === 'speed') {
                        a99Boy.speed = prop.value;
                    }
                    if (prop.name === 'garbage') {
                        a99Boy.garbage = prop.value;
                    }
                    if (prop.name === 'fastShot' && prop.value === true) {
                        a99Boy.bottleReload = 2000;
                        a99Boy.bottleReloadVariance = 500;
                    }
                    if (prop.name === 'NNBoss' && prop.value === true) {
                        a99Boy.boss = true;
                    }
                    if (prop.name === 'health') {
                        a99Boy.health = prop.value;
                    }
                });
            }
        });

        // Create a group for bullets
        this.bullets = this.physics.add.group();
        this.bottles = this.physics.add.group();
        this.axes = this.physics.add.group();
        this.hearts = this.physics.add.group();

        // Input
        this.cursors = this.input.keyboard.createCursorKeys();

        this.physics.add.collider(this.player, mainLayer);
        this.physics.add.collider(this.player, objectsLayer);
        this.physics.add.collider(this.enemies, mainLayer);
        this.physics.add.collider(this.enemies, objectsLayer);
        this.physics.add.collider(this.player, this.interactive, touchInteractive);
        this.physics.add.collider(this.player, this.enemies, (player, enemy) => {
            player.takeDamage();
        });
        this.physics.add.collider(this.player, this.Gulch, (player, zone) => {
            this.game.globalState.startNNX = 2400;
            this.game.globalState.startNNY = 3350;
            this.bgMusic.stop();
            this.scene.start('Gulch');
        });
        this.physics.add.collider(this.player, this.bossSave, (player, zone) => {
            this.game.globalState.startNNX = 2350;
            this.game.globalState.startNNY = 550;
        });

        function touchInteractive(player, interactive) {
            interactive.properties.forEach(prop => {
                if (prop.name === 'key' && prop.value === true) {
                    player.addItemToInventory('key');
                    interactive.destroy();
                }
                if (prop.name === 'lock' && prop.value === true) {
                    if (player.hasItem('key')) {
                        player.removeItemFromInventory('key');
                        let checkTiles = objectsLayer.getTilesWithin(interactive.x/100-5, interactive.y/100-5, 15, 15);
                        checkTiles.forEach(frameTile => {
                            if (frameTile.properties.lockedDoor === true) {
                                objectsLayer.removeTileAt(frameTile.x, frameTile.y);
                            }
                            interactive.destroy();
                        });
                    }
                }
            });
        };

        // Collision between bullets and enemies
        this.physics.add.collider(this.bullets, this.enemies, (bullet, enemy) => {
            // Handle collision here (e.g., damage the enemy or destroy the bullet)
            bullet.destroy();
            enemy.takeDamage(1); // Assuming your NNBoy class has a takeDamage function
        });

        this.physics.add.overlap(this.axes, this.enemies, (axe, enemy) => {
            // Handle collision here (e.g., damage the enemy or destroy the bullet)
            axe.destroy();
            enemy.takeDamage(1); // Assuming your NNBoy class has a takeDamage function
        });

        this.physics.add.collider(this.player, this.bottles, (player, bottle) => {
            player.takeDamage(bottle);
            bottle.destroy();
        });

        this.physics.add.collider(this.player, this.hearts, (player, heart) => {
            player.addHealth(1);
            heart.destroy();
        });

        // Add level heart upgrade
        if (this.game.globalState.hasInventory('99-heart') === 0) {
            this.upgrade = this.physics.add.image(5600, 500, 'heart-upgrade').setScale(0.2);
            this.physics.add.collider(this.player, this.upgrade, (player, upgrade) => {
                this.game.globalState.addToInventory('99-heart', 1);
                this.player.maxHearts ++;
                this.player.numHearts ++;
                this.game.globalState.maxHearts = this.player.maxHearts;
                this.game.globalState.hearts = this.player.numHearts;
                this.player.updateHealth();
                upgrade.destroy();                
            });
        }

        // Add Fat Hawk
        if (this.game.globalState.hasInventory('fatHawk') === 0) {
            this.tiedHawk = this.physics.add.sprite(5950, 300, 'player-tiles', 51);
            this.fatHawk = this.physics.add.collider(this.player, this.tiedHawk, (player, upgrade) => {
                this.fatHawk.destroy();
                this.anims.create({
                    key: 'fatFly',
                    frames: this.anims.generateFrameNumbers('player-tiles', { start: 48, end: 50 }),
                    frameRate: 5,
                    repeat: -1
                });
                this.tiedHawk.setFrame(48);
                this.tiedHawk.anims.play('fatFly');
                // Animate the tiedHawk to move to position (5150, 500)
                this.tweens.add({
                    targets: this.tiedHawk,
                    x: 6150,
                    y: 500,
                    duration: 3000,
                    ease: 'Linear',
                    onComplete: () => {
                        this.tiedHawk.anims.stop();
                        this.tiedHawk.setVelocity(0, 0);
                        this.proEdgeKey = this. physics.add.image(6150, 500, 'proEdgeKey').setScale(.1);
                        this.tweens.add({
                            targets: this.proEdgeKey,
                            x: 5950,
                            y: 650,
                            duration: 1500,
                            ease: 'Bounce'
                        });
                        this.keyCollider = this.physics.add.collider(this.player, this.proEdgeKey, (player, key) => {
                            this.keyCollider.destroy();
                            this.proEdgeKey.destroy();
                            this.game.globalState.addToInventory('fatHawk', 1);
                            this.game.globalState.addToInventory('proEdgeKey', 1);
                            this.cameras.main.fade(1500, 0, 0, 0, true);
                            this.time.delayedCall(1500, () => {
                                this.bgMusic.stop();
                                this.scene.start('Gulch');
                            });
                        });
                    }
                });
            });
        }

        //this.cameras.main.setScroll(800, 1100);
        this.cameras.main.setBounds(1600, 2700, 1600, 900);
        
        // Background Music
        this.bgMusic = this.sound.add('dungeonMusic', { volume: 0.5 });
        this.bgMusic.loop = true;
        this.bgMusic.play();
    }

    update(time, delta) {
        this.player.update();

        const onBounds = this.cameras.main.getBounds();
        if (this.player.body.y <= onBounds.y) {
            this.cameras.main.setBounds(onBounds.x, onBounds.y-900, 1600, 900);
        }
        if (this.player.body.y >= onBounds.y+900) {
            this.cameras.main.setBounds(onBounds.x, onBounds.y+900, 1600, 900);
        }
        if (this.player.body.x <= onBounds.x) {
            this.cameras.main.setBounds(onBounds.x-1600, onBounds.y, 1600, 900);
        }
        if (this.player.body.x >= onBounds.x+1600) {
            this.cameras.main.setBounds(onBounds.x+1600, onBounds.y, 1600, 900);
        }
    }
}