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 { safeAddSound } from "../../utils/safe-add-sound";
class PlayScene extends GameScene {
    player = null;
    mountain = null;
    rightWall = null;
    trees = null;
    flags = null;
    flagsBadAreas = null;
    treeFactory = new TreeFactory(this);
    flagsFactory = new FlagsFactory(this);
    restartText;
    playButton_;
    playButton;
    score = 0;
    collectedFlags = 0;
    scoreInterval = 100;
    scoreDeltaTime = 0;
    treeSpawnInterval = 3000;
    treeSpawnTime = 0;
    flagsSpawnInterval = 5000;
    flagsSpawnTime = 0;
    gameSpeed = 2;
    gameSpeedModifier = 1;
    cursors;
    isGameOverVisible = false;
    isPlayButtonVisible = true;
    progressSound;
    progressSoundShiny;
    lastTimeFlagCollected = 0;
    flagCollectedInterval = 500;
    isTutorialComplete = false;
    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.handleGameRestartSetup();
        this.progressSound = safeAddSound(this, "progress", { volume: 0.2 });
        this.progressSoundShiny = safeAddSound(this, "progress", { volume: 0.5 });
        EventBus.emit('current-scene-ready', this);
        this.syncScaleBounds();
        this.scale.on('resize', this.syncScaleBounds, this);
        EventBus.on('tutorial-finished', this.handleTutorialFinished, this);
        this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
            this.scale.off('resize', this.syncScaleBounds, this);
            EventBus.removeListener('tutorial-finished', this.handleTutorialFinished, this);
        });
        // this.spawnTree();
        // this.spawnFlags();
        if (this.scale.width < 600) {
            this.gameSpeed = 3;
        }
        else if (this.scale.width < 800) {
            this.gameSpeed = 3;
        }
        else if (this.scale.width < 1200) {
            this.gameSpeed = 4;
        }
        else if (this.scale.width < 1600) {
            this.gameSpeed = 4;
        }
        else if (this.scale.width < 2000) {
            this.gameSpeed = 4;
        }
        else if (this.scale.width < 2500) {
            this.gameSpeed = 5;
        }
        else {
            this.gameSpeed = 6;
        }
    }
    syncScaleBounds() {
        if (!this.physics.world)
            return;
        this.physics.world.setBounds(0, 0, this.scale.width, this.scale.height);
        this.mountain?.scaleToFit();
        this.player?.scaleToFit();
        this.player?.positionOnMountain();
    }
    update(time, delta) {
        if (!this.isGameRunning)
            return;
        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;
        }
        const frameScale = delta / (1000 / 60);
        const deltaY = -this.gameSpeed * this.gameSpeedModifier * frameScale;
        this.moveAndDestroyOffscreenChildren(this.trees, deltaY);
        this.moveAndDestroyOffscreenChildren(this.flags, deltaY);
        this.moveAndDestroyOffscreenChildren(this.flagsBadAreas, deltaY);
    }
    setGameRunning(isRunning) {
        if (this.isGameRunning === isRunning)
            return;
        this.isGameRunning = isRunning;
        EventBus.emit('game-running-changed', this);
    }
    moveAndDestroyOffscreenChildren(group, deltaY) {
        const children = group?.getChildren();
        if (!children?.length)
            return;
        for (let index = children.length - 1; index >= 0; index--) {
            const child = children[index];
            child.y += deltaY;
            if (child.y + child.displayHeight < -8) {
                group?.remove(child, true, true);
            }
        }
    }
    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.playButton.hide();
    }
    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() {
        if (!this.isTutorialComplete)
            return;
        if (this.isGameRunning)
            return;
        this.isGameOverVisible = false;
        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.setGameRunning(true);
            }
        });
        // this.playButtonContainer?.setAlpha(0);
        this.playButton?.onGameStart();
    }
    handleGameRestartSetup() {
        this.restartText?.on("pointerdown", () => {
            this.handleGameRestart();
        });
        this.playButton?.playButton?.on("pointerdown", () => {
            if (!this.isTutorialComplete)
                return;
            if (this.isGameRunning) {
                this.treeCollision();
            }
            else {
                this.handleGameRestart();
            }
        });
    }
    handleGameRestart() {
        if (!this.isTutorialComplete)
            return;
        this.physics.resume();
        this.player?.setVelocityY(0);
        this.trees?.clear(true, true);
        this.flags?.clear(true, true);
        this.flagsBadAreas?.clear(true, true);
        this.collectedFlags = 0;
        this.score = 0;
        // this.playButtonContainer?.setAlpha(0);
        // this.isPlayButtonVisible = false;
        this.anims.resumeAll();
        this.setGameRunning(true);
        this.isGameOverVisible = false;
        this.playButton?.onGameStart();
        // this.player?.setTexture("marty-in-plane");
        this.player?.positionOnMountain();
    }
    handleTutorialFinished() {
        this.isTutorialComplete = true;
        this.playButton?.show();
    }
    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;
            }
        });
    }
    treeCollision() {
        this.setGameRunning(false);
        this.physics.pause();
        this.anims.pauseAll();
        this.player?.die();
        this.playButton?.onGameOver();
        this.isGameOverVisible = true;
        // this.playButtonContainer?.setAlpha(1);
        // this.isPlayButtonVisible = true;
        this.treeSpawnTime = 0;
        this.score = 0;
        this.collectedFlags = 0;
        this.flagsBadAreas?.clear(true, true);
        this.scoreDeltaTime = 0;
        this.gameSpeedModifier = 1;
        EventBus.emit('die', this);
    }
    handleTreeCollisions() {
        if (!this.trees)
            return;
        if (!this.player)
            return;
        this.physics.add.collider(this.trees, this.player, () => {
            this.treeCollision();
        });
    }
    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);
                EventBus.emit('mission-complete', this);
                this.setGameRunning(false);
                this.playButton?.onFlagsCollected();
                // 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;
