// 4. Тараканьи бега
export class TarakanyiBega extends Phaser.Scene {
    constructor() {
        super('TarakanyiBega');
        this.playerFrame = ['  O  ', ' /|\\ ', ' [ ] ', ' / \\ '];
        this.zombieFrame1 = ['\\_o/  ', '  |  ',  ' / | ', ' | | ']; // First frame of the zombie walking animation
        this.zombieFrame2 = [' \\o_/',  '  |  ',  ' | \\ ', ' | | ']; // Second frame of the zombie walking animation
        this.zombieSpeed = 5; // characters per second
        this.zombieAnimationFrame = 0; // 0 for zombieFrame1, 1 for zombieFrame2
        this.zombieAnimationTimer = 0;
        this.zombieAnimationSpeed = 700; // Milliseconds per frame
    }

    preload() {
        localStorage.setItem('Scene', this.scene.key);
        this.load.audio('zombie_roar', 'assets/sounds/zombie-growls-and-roars.ogg');
        this.load.audio('barking', 'assets/sounds/barking.ogg');
    }

    create() {
        const graphics = this.add.graphics();
        graphics.fillStyle(0x000000, 1);
        graphics.fillRect(0, 0, 1280, 720);

        this.asciiScreen = this.add.text(60, 40, '', {
            fontFamily: 'monospace',
            fontSize: '18px',
            color: '#ffffff',
            align: 'center'
        });

        this.initGame();

        this.input.keyboard.on('keydown-F', () => {
            if(this.gameOver) return;
            this.playerLane = Math.max(0, this.playerLane - 1);
        });
        this.input.keyboard.on('keydown-J', () => {
            if(this.gameOver) return;
            this.playerLane = Math.min(2, this.playerLane + 1);
        });
        
        this.input.keyboard.on('keydown', () => {
            if (this.gameOver) {
                this.initGame();
            }
        });
        
        this.add.text(40, 680, '[F] бежать левее [J] бежать правее', {
            fontFamily: 'monospace',
            fontSize: '20px',
            color: '#0000ff',
            align: 'left'
        });
    }

    initGame() {
        this.gameOver = false;
        this.zombiesDodged = 0;
        this.spawnDistance = 15;
        this.zombieAnimationFrame = 0; // Reset animation frame
        this.zombieAnimationTimer = 0; // Reset animation timer

        // Play background music
        this.sound.stopAll();
        this.sound.play('backgroundMusic_Action1', { loop: true, volume: 0.1 });

        this.worldWidth = 45;
        this.worldHeight = 30;
        this.playerLane = 1; 
        this.lanes = [Math.floor(this.worldWidth / 4), Math.floor(this.worldWidth / 2), Math.floor(this.worldWidth * 3 / 4)];
        this.zombies = [];
        
        if(this.asciiScreen) this.asciiScreen.setColor('#ffffff');
        //this.sound.stopAll();
    }

    update(time, delta) {
        if (this.gameOver || !this.scene.isActive()) return;

        const moveDistance = (this.zombieSpeed * delta) / 1000;

        this.zombies.forEach(zombie => {
            zombie.y += moveDistance;
            
            const distY = (this.worldHeight - 5) - zombie.y;
            if (distY <= 10 && distY > 0) {
                if (!zombie.sound) {
                    zombie.sound = this.sound.add('zombie_roar', { loop: true, volume: 0.5 });
                    zombie.sound.play();
                }
                zombie.sound.setVolume(1 - (distY / 5));
                const pan = (zombie.lane - this.playerLane) * 0.9;
                zombie.sound.setPan(pan);
            } else if (zombie.sound) {
                zombie.sound.stop();
                zombie.sound.destroy();
                zombie.sound = null;
            }
        });

        const initialZombieCount = this.zombies.length;
        this.zombies = this.zombies.filter(z => {
            if (z.y >= this.worldHeight) {
                if (z.sound) {
                    z.sound.stop();
                    z.sound.destroy();
                }
                return false;
            }
            return true;
        });
        const dodgedCount = initialZombieCount - this.zombies.length;
        if (dodgedCount > 0) {
            this.zombiesDodged += dodgedCount;
            this.checkStageProgress();
        }

        const lastZombie = this.zombies.reduce((prev, curr) => (prev && prev.y < curr.y ? prev : curr), null);
        let newLane = Math.floor(Math.random() * 3);
        const previousLane = lastZombie ? lastZombie.lane : -1; // -1 indicates no previous zombie for comparison

        // Ensure the new zombie does not spawn in the same lane as the previous one
        if (lastZombie) {
            while (newLane === previousLane) {
                newLane = Math.floor(Math.random() * 3);
            }
        }

        if (!lastZombie || lastZombie.y >= this.spawnDistance) {
            this.zombies.push({
                y: lastZombie ? lastZombie.y - this.spawnDistance : 0,
                lane: newLane,
                sound: null
            });
        }

        this.zombies.forEach(zombie => {
            if (zombie.lane === this.playerLane && zombie.y > this.worldHeight - 5 && zombie.y < this.worldHeight -1) {
                this.gameOver = true;
                if(zombie.sound) zombie.sound.stop();
                this.drawGameOver();
            }
        });

        this.drawScreen();

        // Update zombie animation frame
        this.zombieAnimationTimer += delta;
        if (this.zombieAnimationTimer >= this.zombieAnimationSpeed) {
            this.zombieAnimationFrame = 1 - this.zombieAnimationFrame; // Toggle between 0 and 1
            this.zombieAnimationTimer -= this.zombieAnimationSpeed;
        }
    }
    
    checkStageProgress() {
        if (this.zombiesDodged >= 20) {
            this.gameOver = true; // Prevent re-triggering
            this.sound.play('barking');
            this.time.delayedCall(3000, () => {
                this.scene.start('KtoZdesGlavny');
            });
            return;
        }

        if (this.zombiesDodged >= 15) {
            this.asciiScreen.setColor('#000000'); // Invisible
        } else if (this.zombiesDodged >= 10) {
            this.asciiScreen.setColor('#808080'); // Dim
        } else if (this.zombiesDodged >= 5) {
            this.spawnDistance = 10;
        }
    }
    
    drawScreen() {
        if (this.gameOver) return;

        let screen = Array(this.worldHeight).fill(0).map(() => Array(this.worldWidth).fill(' '));
        const playerX = this.lanes[this.playerLane] - 2;

        this.playerFrame.forEach((line, i) => {
            for(let j=0; j < line.length; j++) {
                screen[this.worldHeight - 5 + i][playerX + j] = line[j];
            }
        });

        this.zombies.forEach(zombie => {
            const zx = this.lanes[zombie.lane] - 2;
            const zy = Math.floor(zombie.y);
            const currentZombieFrame = (this.zombieAnimationFrame === 0) ? this.zombieFrame1 : this.zombieFrame2;
            currentZombieFrame.forEach((line, i) => {
                for(let j=0; j < line.length; j++) {
                    if (zy + i < this.worldHeight && zy + i >= 0) {
                        screen[zy + i][zx + j] = line[j];
                    }
                }
            });
        });

        let screenText = screen.map(row => row.join('')).join('\n');
        //screenText += `\n\nZombies Dodged: ${this.zombiesDodged} / 20`;
        this.asciiScreen.setText(screenText);
    }
    
    drawGameOver(){
        this.sound.stopAll();
        this.asciiScreen.setColor('#ff0000'); // Reset text color to white on game over
        let screenLines = this.asciiScreen.text.split('\n');
        const gameOverText = [
            '                              ',
            '                              ',
            '                              ',
            `       Будьте аккуратнее      `,
            '                              ',
            '    Попробуйте ещё раз [Any]  ',
            '                              ',
        ];

        const startY = Math.floor((this.worldHeight / 2) - 3);
        for(let i=0; i < gameOverText.length; i++){
            const y = startY + i;
            if(y < screenLines.length) {
                screenLines[y] = gameOverText[i];
            }
        }
        this.asciiScreen.setText(screenLines.join('\n'));
    }
}
