import { Player } from '../Player.js';

export class GameScene extends Phaser.Scene {
    constructor() {
        super({ key: 'GameScene' });
        
        // Game objects references
        this.player = null;
        this.enemies = null;
        this.bullets = null;

        // Enemy bullets group
        this.enemyBullets = null;
        
        // Game state
        this.score = 0;
        this.gameOver = false;
        
        // Mouse reticle
        this.reticle = null;
        
        // Wave system
        this.waveTimer = 0;
        this.currentWave = 0;
    }

    preload() {
        // Load assets here (will be implemented in a later step)
        console.log('Loading assets...');

         // Load reticle image
        this.load.image('reticle', 'assets/reticle.png');

        // Load background images
        this.load.image('bg-layer1', 'assets/neon-city-bg.png');
        //this.load.image('bg-layer2', 'assets/bg-layer2.png');
        //this.load.image('bg-layer3', 'assets/bg-layer3.png');

        // Load Sprites
        this.load.spritesheet('player-sprite', 'assets/player-sprite.png', {
            frameWidth: 48,
            frameHeight: 48
        });
        this.load.spritesheet('enemy-sprite', 'assets/enemy-sprite.png', {
            frameWidth: 48,
            frameHeight: 48
        });

        // Load background music and sounds
        this.load.audio('bgm', 'assets/music/NeonPulse.mp3');
        this.load.audio('main-gun', 'assets/sounds/main-gun.mp3');
        this.load.audio('enemy-kill', 'assets/sounds/enemy-kill.mp3');
        this.load.audio('enemy-shoot', 'assets/sounds/enemy-shoot.mp3');
        this.load.audio('player-death', 'assets/sounds/player-death.mp3');
        this.load.audio('enemy-shoot', 'assets/sounds/enemy-shoot.mp3');
        this.load.audio('next-wave', 'assets/sounds/next-wave.mp3');
        
        // Create simple placeholder graphics for now
        this.createPlaceholderGraphics();
    }

    create() {
        // Set background color
        this.cameras.main.setBackgroundColor('#0a0a2a');
        
        // Create parallax backgrounds
        this.createBackgrounds();

        // Create player instance
        this.player = new Player(this);
        const { aKey, dKey } = this.player.create();
        
        // Create groups for bullets and enemies
        this.bullets = this.physics.add.group();
        this.enemyBullets = this.physics.add.group();
        this.enemies = this.physics.add.group();
        
        // Setup collision detection
        this.physics.add.overlap(this.bullets, this.enemies, this.hitEnemy, null, this);
        this.physics.add.overlap(this.player.sprite, this.enemies, this.hitPlayer, null, this);
        this.physics.add.overlap(this.player.sprite, this.enemyBullets, this.hitPlayer, null, this);
        
        // Start enemy spawning
        this.time.addEvent({
            delay: 1000,
            callback: this.spawnEnemy,
            callbackScope: this,
            loop: true
        });
        
        // Create UI elements
        this.createUI();
        
        // Setup mouse input for shooting and reticle
        this.setupMouseInput();

        // Play background music
        this.bgMusic = this.sound.add('bgm', { loop: true });
        this.bgMusic.play();
    }

    createBackgrounds() {
        // Create multiple background layers with different speeds
        this.bgLayer1 = this.add.image(280, 30, 'bg-layer1').setOrigin(0.5);
        //this.bgLayer2 = this.add.image(400, 300, 'bg-layer2').setOrigin(0.5);
        //this.bgLayer3 = this.add.image(400, 300, 'bg-layer3').setOrigin(0.5);
        
        // Set different speeds for parallax effect (smaller = slower)
        this.bgSpeed1 = 0.2;
        //this.bgSpeed2 = 0.5;
        //this.bgSpeed3 = 0.8;
    }

    update(time, delta) {
        if (this.gameOver) return;
        
        // Update background positions for parallax effect
        this.updateBackgrounds();
        
        // Update wave timer
        this.waveTimer += delta;

        // Check for wave changes every 30 seconds (30,000 milliseconds)
        if (this.waveTimer >= 30000 && this.currentWave === 0) {
            this.startWave(1);
        } else if (this.waveTimer >= 60000 && this.currentWave === 1) {
            this.startWave(2);
        }
        
        // Get A/D keys for player movement
        const aKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);
        const dKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);
        
        // Update player with A/D controls
        this.player.update(aKey, dKey);

        // Check if enemies are off-screen and destroy them
        this.checkEnemiesOffScreen();
    }

    updateBackgrounds() {
        // Move background layers at different speeds
        this.bgLayer1.y += this.bgSpeed1;
        //this.bgLayer2.x -= this.bgSpeed2;
        //this.bgLayer3.x -= this.bgSpeed3;
        
        // Reset positions to create continuous scrolling effect
        if (this.bgLayer1.y > 736) {
            this.bgLayer1.y = 30; // Width of game + layer width
        }
        // if (this.bgLayer2.x < -400) {
        //     this.bgLayer2.x = 1200;
        // }
        // if (this.bgLayer3.x < -400) {
        //     this.bgLayer3.x = 1200;
        // }
    }

    setupMouseInput() {
        // Create mouse reticle as sprite (replacing the circle)
        this.reticle = this.add.sprite(0, 0, 'reticle');
        this.reticle.setOrigin(0.5);
        this.reticle.preFX.addGlow(0x00ffcc, .7);
        
        // Update reticle position with mouse
        this.input.on('pointermove', (pointer) => {
            if (this.gameOver) return;
            
            this.reticle.x = pointer.x;
            this.reticle.y = pointer.y;
        });
        
        // Shooting with left mouse button
        this.input.on('pointerdown', (pointer) => {
            if (this.gameOver) return;
            
            if (pointer.leftButtonReleased()) {
                this.shoot(pointer);
            }
        });
    }

    createPlaceholderGraphics() {
        // Create simple placeholder graphics for player, bullets and enemies
        const canvas = document.createElement('canvas');
        canvas.width = 32;
        canvas.height = 32;
        
        // Enemy (square)
        const enemyCanvas = document.createElement('canvas');
        enemyCanvas.width = 24;
        enemyCanvas.height = 24;
        
        const eCtx = enemyCanvas.getContext('2d');
        eCtx.fillStyle = '#ff3366';
        eCtx.fillRect(0, 0, 24, 24);
        
        this.textures.addCanvas('enemy', enemyCanvas);
        
        // Bullet (small circle)
        const bulletCanvas = document.createElement('canvas');
        bulletCanvas.width = 8;
        bulletCanvas.height = 8;
        
        const bCtx = bulletCanvas.getContext('2d');
        bCtx.fillStyle = '#ffff00';
        bCtx.beginPath();
        bCtx.arc(4, 4, 3, 0, Math.PI * 2);
        bCtx.fill();
        
        this.textures.addCanvas('bullet', bulletCanvas);

        // Enemy Bullet (small circle)
        const enemyBulletCanvas = document.createElement('canvas');
        enemyBulletCanvas.width = 8;
        enemyBulletCanvas.height = 8;
        
        const ebCtx = enemyBulletCanvas.getContext('2d');
        ebCtx.fillStyle = '#00ffcc';
        ebCtx.beginPath();
        ebCtx.arc(4, 4, 3, 0, Math.PI * 2);
        ebCtx.fill();
        
        this.textures.addCanvas('enemyBullet', enemyBulletCanvas);
    }

    createUI() {
        // Create score text
        this.scoreText = this.add.text(16, 16, 'Score: 0', { 
            fontSize: '28px', 
            fill: '#ffffff',
            fontFamily: 'Arial'
        });
        
        // Create game title
        this.titleText = this.add.text(300, 50, 'Zenith Vector', { 
            fontSize: '40px', 
            fill: '#00ffcc',
            fontFamily: 'Arial',
            align: 'center'
        });
        this.titleText.setOrigin(0.5);
    }

    shoot(pointer) {
        // Calculate angle between player and mouse
        const angle = Phaser.Math.Angle.Between(
            this.player.sprite.x,
            this.player.sprite.y,
            pointer.x,
            pointer.y
        );
        
        // Create bullet at player position
        const bullet = this.bullets.create(this.player.sprite.x, this.player.sprite.y, 'bullet');
        
        // Set velocity based on angle and speed
        const speed = 400;
        bullet.setVelocityX(Math.cos(angle) * speed);
        bullet.setVelocityY(Math.sin(angle) * speed);
        
        // Scale bullet
        bullet.setScale(1.5);

        // Sound Effects
        this.sound.play('main-gun');
    }

    spawnEnemy() {
        // Spawn enemies at random x position within game width (800px)
        const x = Phaser.Math.Between(20, 580);

        // Calculate texture range with minimum of 0
        const minTexture = Math.max(0, this.currentWave - 2);
        const maxTexture = this.currentWave;
        
        // Ensure we don't get negative values
        const texture = Phaser.Math.Between(minTexture, maxTexture);

        const enemy = this.enemies.create(x, 0, 'enemy-sprite', texture);
        
        // Randomize enemy speed
        const speed = Phaser.Math.Between(50, 150);
        enemy.setVelocityY(speed);
        
        // Add some rotation for visual effect
        //enemy.setRotation(Phaser.Math.FloatBetween(-0.2, 0.2));
        
        // Apply wave-specific properties
        this.applyWaveProperties(enemy, texture);
    }

    applyWaveProperties(enemy, texture) {
        // Set the current wave number on the enemy
        enemy.waveNumber = this.currentWave;
        
        // Wave 1: Basic enemies (no shooting)
        if (this.currentWave === 0) {
            enemy.canShoot = false;
            if (enemy.shootTimer) {
                enemy.shootTimer.remove();
                enemy.shootTimer = null;
            }
        } 
        // Wave 2: Enemies that can shoot
        else if (this.currentWave >= 1 && texture > 0) {
            enemy.canShoot = true;
            // Only set up shooting timer if it doesn't exist yet
            if (!enemy.shootTimer) {
                enemy.shootTimer = this.time.addEvent({
                    delay: Phaser.Math.Between(1000, 3000),
                    callback: () => this.enemyShoot(enemy, texture),
                    callbackScope: this,
                    loop: true
                });
            }
        }
    }

    hitEnemy(bullet, enemy) {
        bullet.destroy();
        enemy.destroy();
        this.sound.play('enemy-kill');
        
        this.score += 10;
        this.scoreText.setText('Score: ' + this.score);
    }

    hitPlayer(player, enemy) {
        // Create explosion at player's position
        const explosion = this.add.sprite(this.player.sprite.x, this.player.sprite.y, 'player-sprite', 3);
        const explosion2 = this.add.sprite(this.player.sprite.x, this.player.sprite.y, 'player-sprite', 3);
        
        // Add rotation and scaling animation
        this.tweens.add({
            targets: explosion,
            scale: 3, // Scale up to 3x
            rotation: Math.PI * 2, // Full rotation
            alpha: 0.5, // Fade out slightly
            duration: 1000,
            ease: 'Power2',
            onComplete: () => {
                explosion.destroy();
            }
        });
        this.tweens.add({
            targets: explosion2,
            scale: 3, // Scale up to 3x
            rotation: -Math.PI * 2, // Full rotation
            alpha: 0.5, // Fade out slightly
            duration: 1000,
            ease: 'Power2',
            onComplete: () => {
                explosion2.destroy();
            }
        });
        
        player.destroy();
        enemy.destroy();
        this.sound.play('player-death');
        
        this.gameOver = true;
        
        // Show game over text
        const gameOverText = this.add.text(300, 400, 'GAME OVER', { 
            fontSize: '54px', 
            fill: '#ff3366',
            fontFamily: 'Arial'
        });
        gameOverText.setOrigin(0.5);
        
        // Restart game after delay
        // this.time.delayedCall(2000, () => {
        //     this.scene.restart();
        // });
    }

    startWave(waveNumber) {
        this.currentWave = waveNumber;
        this.sound.play('next-wave');
        
        // Add wave indicator text
        const waveText = this.add.text(300, 150, `WAVE ${waveNumber + 1}`, { 
            fontSize: '48px', 
            fill: '#ffff00',
            fontFamily: 'Arial'
        });
        waveText.setOrigin(0.5);
        
        // Add scaling animation
        this.tweens.add({
            targets: waveText,
            scale: 2, // Grow to double size
            duration: 1000,
            ease: 'Elastic.out', // Elastic easing for bouncy effect
            yoyo: true, // Scale back and forth
            repeat: 1 // Do the animation twice (total of 3 states)
        });
        
        // Remove text after delay
        this.time.delayedCall(2000, () => {
            waveText.destroy();
        });
        
        // Apply wave properties to all existing enemies
        this.enemies.children.iterate((enemy) => {
            this.applyWaveProperties(enemy);
        });
    }
    
    enemyShoot(enemy, texture) {
        // Only shoot if enemy can shoot and isn't destroyed
        if (!enemy.canShoot || !enemy.active) return;
        
        console.log(texture);
        // Check if this is wave 3 and enemy has texture 2 (special shooting)
        if (this.currentWave >= 2 && enemy.waveNumber >= 2 && texture >= 2) {
            // Shoot toward player
            const angle = Phaser.Math.Angle.Between(
                enemy.x,
                enemy.y,
                this.player.sprite.x,
                this.player.sprite.y
            );
            
            const bullet = this.enemyBullets.create(enemy.x, enemy.y, 'enemyBullet');
            const speed = 200;
            bullet.setVelocityX(Math.cos(angle) * speed);
            bullet.setVelocityY(Math.sin(angle) * speed);
            bullet.setScale(1.5);
        } else {
            // Regular straight-down shooting
            const bullet = this.enemyBullets.create(enemy.x, enemy.y, 'enemyBullet');
            bullet.setVelocityY(300); // Move straight down at 200px/s
            bullet.setScale(1.5);
        }
        
        // Sound effect for enemy shooting
        this.sound.play('enemy-shoot');
    }

    checkEnemiesOffScreen() {
        // Destroy enemies that have gone below the screen
        this.enemies.children.iterate((enemy) => {
            if (enemy && enemy.y > 800) { // Adjust 600 to your game height as needed
                enemy.destroy();
            }
        });
    }
}