import { Player } from "../entities/Player";
import { GameScene } from "./GameScene";
import { EventBus } from "../EventBus";
import { Mountain } from "../entities/Mountain";
import { TreeFactory } from "../entities/Tree";
import { FlagsFactory } from "../entities/Flags";
import { RightWall } from "../entities/RightWall";
import { PlayButton } from "../entities/PlayButton";
import { GameOverContainer } from "../entities/GameOverContainer";
class PlayScene extends GameScene {
    player = null;
    mountain = null;
    rightWall = null;
    trees = null;
    flags = null;
    flagsBadAreas = null;
    treeFactory = new TreeFactory(this);
    flagsFactory = new FlagsFactory(this);
    gameOverText;
    restartText;
    playButton_;
    gameOverContainer;
    playButtonContainer;
    playButton;
    score = 0;
    collectedFlags = 0;
    scoreInterval = 100;
    scoreDeltaTime = 0;
    treeSpawnInterval = 3000;
    treeSpawnTime = 0;
    flagsSpawnInterval = 10000;
    flagsSpawnTime = 0;
    gameSpeed = 2;
    gameSpeedModifier = 1;
    cursors;
    isGameOverVisible = false;
    isPlayButtonVisible = true;
    progressSound;
    progressSoundShiny;
    lastTimeFlagCollected = 0;
    flagCollectedInterval = 500;
    constructor() {
        super("PlayScene");
    }
    create() {
        this.cursors = this.input.keyboard?.createCursorKeys();
        this.createMountain();
        this.createPlayer();
        this.createRightWall();
        // this.createTrees();
        this.handleTreeCollisions();
        this.handleRightWallCollision();
        this.createFlags();
        this.handleFlagsCollisions();
        // this.createShinyStars();
        // this.handleShinyStarCollisions();
        // this.createPlayButton();
        this.createGameOverContainer();
        this.handleGameRestartSetup();
        this.progressSound = this.sound.add("progress", { volume: 0.2 });
        this.progressSoundShiny = this.sound.add("progress", { volume: 0.5 });
        EventBus.emit('current-scene-ready', this);
        this.handleGameStart();
        // this.spawnFlags();
    }
    update(time, delta) {
        if (!this.isGameRunning)
            return;
        EventBus.emit('play-scene-updated', this);
        if (this.player && this.rightWall) {
            const isPlayerTouchingGround = this.physics.overlap(this.player, this.rightWall);
            this.player.canGoRight = !isPlayerTouchingGround;
        }
        this.treeSpawnTime += delta;
        this.flagsSpawnTime += delta;
        this.scoreDeltaTime += delta;
        if (this.scoreDeltaTime >= this.scoreInterval) {
            this.score++;
            this.scoreDeltaTime = 0;
            // if (this.score % 100 === 0) {
            //   this.gameSpeedModifier += 0.2;
            //   this.tweens.add({
            //     targets: this.scoreText,
            //     duration: 100,
            //     repeat: 3,
            //     alpha: 0,
            //     yoyo: true
            //   });
            // }
        }
        // if (this.treeSpawnTime >= this.treeSpawnInterval) {
        //   this.spawnTree();
        //   this.treeSpawnTime = 0;
        // }
        if (this.flagsSpawnTime >= this.flagsSpawnInterval) {
            this.spawnFlags();
            this.flagsSpawnTime = 0;
        }
        Phaser.Actions.IncY(this.trees?.getChildren() || [], -this.gameSpeed * this.gameSpeedModifier * .5);
        Phaser.Actions.IncY(this.flags?.getChildren() || [], -this.gameSpeed * this.gameSpeedModifier * .5);
        Phaser.Actions.IncY(this.flagsBadAreas?.getChildren() || [], -this.gameSpeed * this.gameSpeedModifier * .5);
        const score = Array.from(String(this.score), Number);
        for (let i = 0; i < 5 - String(this.score).length; i++) {
            score.unshift(0);
        }
        this.trees?.getChildren().forEach((tree) => {
            if (tree.getBounds().right < 0) {
                this.trees?.remove(tree);
            }
        });
        this.flags?.getChildren().forEach((flags) => {
            if (flags.getBounds().right < 0) {
                this.flags?.remove(flags);
            }
        });
        this.flagsBadAreas?.getChildren().forEach((badArea) => {
            if (badArea.getBounds().right < 0) {
                this.flagsBadAreas?.remove(badArea);
            }
        });
    }
    createPlayer() {
        this.player = new Player(this);
    }
    createMountain() {
        this.mountain = new Mountain(this);
    }
    createRightWall() {
        this.rightWall = new RightWall(this);
    }
    createTrees() {
        this.trees = this.physics.add.group();
    }
    createFlags() {
        this.flags = this.physics.add.group();
        this.flagsBadAreas = this.physics.add.group();
    }
    createPlayButton() {
        this.playButton = new PlayButton(this);
        this.playButton_ = this.playButton.playButton;
        this.playButtonContainer = this.playButton;
    }
    createGameOverContainer() {
        this.gameOverContainer = new GameOverContainer(this);
        this.gameOverText = this.gameOverContainer.gameOverText;
        this.restartText = this.gameOverContainer.restartText;
    }
    spawnTree() {
        if (!this.trees)
            return;
        this.treeFactory.create(this.trees);
    }
    spawnFlags() {
        if (!this.flags)
            return;
        const createdFlags = this.flagsFactory.create(this.flags);
        createdFlags.badAreaLeft && this.flagsBadAreas?.add(createdFlags.badAreaLeft);
        createdFlags.badAreaRight && this.flagsBadAreas?.add(createdFlags.badAreaRight);
    }
    handleGameStart() {
        const rollOutEvent = this.time.addEvent({
            delay: 1000 / 60,
            loop: true,
            callback: () => {
                this.player?.setVelocityX(80);
                rollOutEvent.remove();
                this.player?.setVelocityX(0);
                // this.scoreText.setAlpha(1);
                this.isGameRunning = true;
            }
        });
        this.playButtonContainer?.setAlpha(0);
    }
    handleGameRestartSetup() {
        this.restartText?.on("pointerdown", () => {
            this.handleGameRestart();
        });
        this.playButton?.playButton?.on("pointerdown", () => {
            this.handleGameRestart();
        });
    }
    handleGameRestart() {
        this.physics.resume();
        this.player?.setVelocityY(0);
        this.trees?.clear(true, true);
        this.flags?.clear(true, true);
        this.collectedFlags = 0;
        this.score = 0;
        this.gameOverContainer?.setAlpha(0);
        this.playButtonContainer?.setAlpha(0);
        this.isGameOverVisible = false;
        this.isPlayButtonVisible = false;
        this.anims.resumeAll();
        this.isGameRunning = true;
        this.player?.setTexture("marty-in-plane");
        this.player?.positionOnMountain();
    }
    handleRightWallCollision() {
        // the player should not be able to move past the right wall
        if (!this.player)
            return;
        if (!this.rightWall)
            return;
        this.physics.add.collider(this.player, this.rightWall, () => {
            if (this.player) {
                this.player.canGoRight = false;
            }
        });
    }
    handleTreeCollisions() {
        if (!this.trees)
            return;
        if (!this.player)
            return;
        this.physics.add.collider(this.trees, this.player, () => {
            this.isGameRunning = false;
            this.physics.pause();
            this.anims.pauseAll();
            this.player?.die();
            this.gameOverContainer?.setAlpha(1);
            this.isGameOverVisible = true;
            this.treeSpawnTime = 0;
            this.score = 0;
            this.collectedFlags = 0;
            this.scoreDeltaTime = 0;
            this.gameSpeedModifier = 1;
            EventBus.emit('die', this);
        });
    }
    handleFlagsCollisions() {
        if (!this.flags)
            return;
        if (!this.flagsBadAreas)
            return;
        if (!this.player)
            return;
        this.physics.add.collider(this.flags, this.player, (player, flags) => {
            if (flags.getData('collected'))
                return;
            if (this.time.now - this.lastTimeFlagCollected < this.flagCollectedInterval)
                return;
            this.lastTimeFlagCollected = this.time.now;
            // flags.destroy();
            flags.setData('collected', true);
            // this.score += 40;
            this.collectedFlags++;
            EventBus.emit('flags-collected', this);
            if (this.collectedFlags === 10) {
                EventBus.emit('target-achieved', this);
                this.isGameRunning = false;
                this.playButtonContainer?.setAlpha(1);
                this.isPlayButtonVisible = true;
                this.physics.pause();
                this.anims.pauseAll();
            }
            this.progressSound?.play();
        });
        this.physics.add.collider(this.flagsBadAreas, this.player, (player, badArea) => {
            if (badArea.getData('collected'))
                return;
            badArea.setData('collected', true);
            if (this.time.now - this.lastTimeFlagCollected < this.flagCollectedInterval)
                return;
            this.lastTimeFlagCollected = this.time.now;
            if (this.collectedFlags === 0)
                return;
            this.collectedFlags--;
            EventBus.emit('flags-lost', this);
            this.player?.hitSound?.play();
        });
    }
}
export default PlayScene;
