// 6. Последний бой
export class PosledniyBoy extends Phaser.Scene {
    constructor() {
        super('PosledniyBoy');

        this.playerReadyFrame = [
            '         ',
            '    O    ',
            '   /|\\   ',
            '  / | \\  ',
            '    |    ',
            '   -|-   ',
            '  / | \\  ',
            ' | / \\ | ',
            ' |_| |_| ',
        ];
        this.playerAttackUL = [
            '*\\       ',
            '  \\O     ',
            '   |\\    ',
            '   | \\   ',
            '   |     ',
            '   -|-   ',
            '  / | \\  ',
            ' | / \\ | ',
            ' |_| |_| ',
        ];
        this.playerAttackL = [
            '         ',
            '   O    ',
            '*-=|\   ',
            '   | \  ',
            '   |     ',
            '   -|-   ',
            '  / | \\  ',
            ' | / \\ | ',
            ' |_| |_| ',
        ];
        this.playerAttackUR = [
            '       /*',
            '     O/  ',
            '    /|   ',
            '   / |   ',
            '     |   ',
            '   -|-   ',
            '  / | \\  ',
            ' | / \\ | ',
            ' |_| |_| ',
        ];
        this.playerAttackR = [
            '         ',
            '     O   ',
            '    /|=-*',
            '   / |   ',
            '     |   ',
            '   -|-   ',
            '  / | \\  ',
            ' | / \\ | ',
            ' |_| |_| ',
        ];
        this.ghostFrame = [
            '  /|  |\\ ',
            ' |.-~~-.|',
            ' /     \\ ',
            '|  o o  |',
            '|   W   |',
            ' \\     / ',
            '  `---`  ',
            '   U U   ',
            '         ',
        ];
        //</editor-fold>

        this.GHOST_SPEED = 8; // positions per second
        this.STRIKE_DISTANCE = 8;
        this.ATTACK_DURATION = 250; // ms
    }

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

    create() {
        this.background = this.add.tileSprite(640, 360, 1280, 720, 'background');

        this.graphics = this.add.graphics();
        this.graphics.fillStyle(0x000000, 0.8);
        this.graphics.fillRect(0, 0, 1280, 720);

        this.asciiScreen = this.add.text(10, 5, '', { fontFamily: 'monospace', fontSize: '16px', color: '#FFF' });

        this.initGame();

        this.input.keyboard.on('keydown-R', () => this.handleAttack('UL'));
        this.input.keyboard.on('keydown-F', () => this.handleAttack('L'));
        this.input.keyboard.on('keydown-I', () => this.handleAttack('UR'));
        this.input.keyboard.on('keydown-J', () => this.handleAttack('R'));
        this.input.keyboard.on('keydown', () => { if (this.gameOver) this.initGame(); });
        
        this.add.text(40, 680, '[R] удар влево-вверх [I] удар вправо-вверх\n[F] удар влево       [J] удар вправо      ', {
            fontFamily: 'monospace',
            fontSize: '20px',
            color: '#0000ff',
            align: 'left'
        });
    }

    initGame() {
        this.gameOver = false;
        this.score = 0;

        // Play background music
        this.sound.stopAll();
        this.sound.play('backgroundMusic_Action1', { loop: true, volume: 0.1 });
        
        this.worldWidth = 70;
        this.worldHeight = 35;
        this.playerPos = { y: Math.floor(this.worldHeight * 3 / 4) - 4, x: Math.floor(this.worldWidth / 2) - 4 };

        this.playerState = 'ready';
        this.playerAttackTimer = 0;
        
        this.ghosts = [];
        this.ghostSpawner = { timer: 2000, interval: 2000 };
        
        this.directions = {
            'L':  { pan: -1.0, path: Array.from({length: 25}, (_, i) => [this.playerPos.y, i]) },
            'UL': { pan: -0.4, path: Array.from({length: 25}, (_, i) => [i - 2, i]) },
            'UR': { pan: 0.4,  path: Array.from({length: 25}, (_, i) => [i - 2, this.worldWidth - 9 - i]) },
            'R':  { pan: 1.0,  path: Array.from({length: 25}, (_, i) => [this.playerPos.y, this.worldWidth - 9 - i]) }
        };

        if(this.asciiScreen) this.asciiScreen.setColor('#ffffff');
        //this.sound.stopAll();
        this.drawScreen();
    }

    handleAttack(dirKey) {
        if (this.gameOver || this.playerState !== 'ready') return;

        this.playerState = `attack_${dirKey}`;
        this.playerAttackTimer = this.ATTACK_DURATION;

        // Play strike sound with panning
        const pan = this.directions[dirKey].pan;
        this.sound.play('strike', { pan: pan });

        let hit = false;
        this.ghosts.forEach(ghost => {
            const path = this.directions[ghost.dir].path;
            const dist = path.length - 1 - Math.floor(ghost.pathPos);
            if (ghost.dir === dirKey && dist < this.STRIKE_DISTANCE) {
                ghost.isHit = true;
                hit = true;
            }
        });

        if(hit) {
            // Play damage sound with panning
            this.sound.play('damage', { pan: pan });

            this.score++;
            this.checkStageProgress();
            this.ghosts = this.ghosts.filter(g => {
                if(g.isHit) {
                    if (g.sound) { g.sound.stop(); g.sound.destroy(); }
                    return false;
                }
                return true;
            });
        }
    }

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

        if (this.playerAttackTimer > 0) {
            this.playerAttackTimer -= delta;
            if (this.playerAttackTimer <= 0) {
                this.playerState = 'ready';
            }
        }

        this.ghostSpawner.timer -= delta;
        if (this.ghostSpawner.timer <= 0) {
            const dirs = Object.keys(this.directions);
            const dirKey = dirs[Math.floor(Math.random() * dirs.length)];
            this.ghosts.push({ dir: dirKey, pathPos: 0, sound: null });
            this.ghostSpawner.interval = Math.max(500, this.ghostSpawner.interval * 0.98);
            this.ghostSpawner.timer = this.ghostSpawner.interval;
        }

        const moveD = (this.GHOST_SPEED * delta) / 1000;
        this.ghosts.forEach(ghost => {
            ghost.pathPos += moveD;
            const path = this.directions[ghost.dir].path;
            const dist = path.length - 1 - Math.floor(ghost.pathPos);

            if (dist < this.STRIKE_DISTANCE + 2) {
                if (!ghost.sound) {
                    ghost.sound = this.sound.add('zombie_roar', { loop: true, volume: 1 });
                    ghost.sound.play();
                }
                //ghost.sound.setVolume(1 - (dist / this.STRIKE_DISTANCE));
                ghost.sound.setPan(this.directions[ghost.dir].pan);
            }

            if (Math.floor(ghost.pathPos) >= path.length -1) {
                this.asciiScreen.setColor('#ff0000');
                this.drawScreen();
                this.sound.play('scream');
                this.gameOver = true;
            }
        });

        this.drawScreen();
        if(this.gameOver) this.drawGameOver();
    }
    
    checkStageProgress() {
        if (this.score >= 15) {
            this.sound.stopAll();
            this.scene.start('Final');
            return;
        }
        if (this.score >= 10) {
            this.asciiScreen.setColor('#000000'); // Invisible
        } else if (this.score >= 5) {
            this.asciiScreen.setColor('#808080'); // Dim
        }
    }
    
    drawScreen() {
        if (this.gameOver) return;
        let screen = Array(this.worldHeight).fill(0).map(() => Array(this.worldWidth).fill(' '));
        
        let playerFrame;
        switch(this.playerState) {
            case 'attack_L': playerFrame = this.playerAttackL; break;
            case 'attack_UL': playerFrame = this.playerAttackUL; break;
            case 'attack_UR': playerFrame = this.playerAttackUR; break;
            case 'attack_R': playerFrame = this.playerAttackR; break;
            default: playerFrame = this.playerReadyFrame;
        }
        this.drawSprite(screen, playerFrame, this.playerPos.y, this.playerPos.x);

        this.ghosts.forEach(ghost => {
            const path = this.directions[ghost.dir].path;
            const pos = path[Math.floor(ghost.pathPos)];
            if(pos) this.drawSprite(screen, this.ghostFrame, pos[0], pos[1]);
        });
        
        let screenText = screen.map(row => row.join('')).join('\n');
        //screenText += `\nScore: ${this.score} / 15`;
        this.asciiScreen.setText(screenText);
    }
    
    drawSprite(screen, sprite, y, x) {
        sprite.forEach((line, i) => {
            if (y + i >= 0 && y + i < this.worldHeight) {
                for (let j = 0; j < line.length; j++) {
                    if (x + j >= 0 && x + j < this.worldWidth) {
                        screen[y + i][x + j] = line[j];
                    }
                }
            }
        });
    }

    drawGameOver(){
        this.time.delayedCall(1000, () => {
            this.sound.stopAll();
            this.scene.start('Start');
        });
        this.asciiScreen.setText(`\n\n\n\n\n\n\n                Демоны разорвали вашу плоть\n\n                Ещё раз? [Any]\n\n                                   `);
    }
}