import PlayScene from "../scenes/PlayScene";


const pickRandom = <T>(arr: T[]): T => arr[Math.floor(Math.random() * arr.length)];

const positionsMap: { [position: string]: number } = {
    left: 70 ,
    middle: 1000 ,
    right: 1900 ,
    'left-middle': 500 ,
    'right-middle': 1500 ,
}

export class FlagsFactory {
    scene: PlayScene;
    possiblePositions: string[] = ["left", "middle", "right", "left-middle", "right-middle"];

    constructor(scene: PlayScene) {
        this.scene = scene;
    }

    create(group: Phaser.Physics.Arcade.Group) {
        const position = pickRandom(this.possiblePositions);
        const flags = new Flags(this.scene, position);
        group.add(flags);
        // Testing
        // {
        //     const position = "right";
        //     const flags = new Flags(this.scene, position);
        //     group.add(flags);
        //     return flags;
        // }

        return flags;
    }
}

export class Flags extends Phaser.Physics.Arcade.Sprite {
    scene: PlayScene;
    position: string;

    badAreaLeft: Area | undefined;
    badAreaRight: Area | undefined;


    constructor(scene: PlayScene, position: string) {
        const x = 0;
        const y = 0;
        super(scene, x, y, "flags");
        this.scene = scene;
        this.position = position;
        scene.add.existing(this);
        scene.physics.add.existing(this);

        this.init();
        this.scene.events.on(Phaser.Scenes.Events.UPDATE, this.update, this);
    }

    init() {
        this
            .setOrigin(0, 1)
            .setCollideWorldBounds(true)
            .setDepth(2);

        // this.scene.scale.once('resize', this.positionOnMountain, this);

        this.positionOnMountain();
    }

    positionOnMountain() {
        // Keep the display size as you originally set it.
        const scaleFactorY = this.scene.mountain?.scaleFactors.height || 1;
        const scaleFactorX = this.scene.mountain?.scaleFactors.width || 1;
        const flagWidth = 480;
        const flagHeight = 240;
        this.setDisplaySize(flagWidth * scaleFactorX, flagHeight * scaleFactorY);
        (this.body as Phaser.Physics.Arcade.Body).setSize(flagWidth / 2, 10);
        (this.body as Phaser.Physics.Arcade.Body).setOffset(0, flagHeight / 2);

        const distance = Phaser.Math.Between((this.scene.mountain?.height || 0), (this.scene.mountain?.height || 0) * 1.4);
        this.setY(distance * scaleFactorY);

        const flagsX = positionsMap[this.position] * scaleFactorX;

        const x = flagsX;
        this.setX(x);

        const mountainWidth = this.scene.mountain?.width || 0;

        // Create bad areas
        this.badAreaLeft = new Area(this.scene, 0, this.y - 10, this.x, 10);
        this.badAreaRight = new Area(this.scene, this.x + (this.width + 80) * scaleFactorX, this.y - 10, mountainWidth, 10);
    }

    update() {
        // Optionally update safe zone if needed on resize.
    }
}


class Area extends Phaser.Physics.Arcade.Sprite {
    scene: PlayScene;
    heightScaled: number = 0;
    scaleFactor: number = 0;

    constructor(scene: PlayScene, x: number, y: number, width: number, height: number) {
        super(scene, x, y, "");
        this.width = width;
        this.height = height;
        this.scene = scene;
        scene.add.existing(this);
        scene.physics.add.existing(this, false);

        this.init();
    }

    init() {
        this
            .setOrigin(0, 0)
            .setVisible(false)
            .setDepth(2)
            .setDisplaySize(this.width, this.height);
        // Handle resizing
        // this.scene.scale.once('resize', this.positionOnMountain, this);
    }

    // positionOnMountain() {
    //     this.setDisplaySize(this.width, 10);

    //     this.setY(0);
    //     this.setX(this.scene.scale.width - 10);
    // }


}
