import * as PIXI from "../pixi/pixi.mjs";
import { loadGameAssets } from "./AssetsLoader/AssetsLoader";
import { UICameraInfo, UIGameProfilerPipe, UIMainPipe, UIObtainedResourcesPipe, UISelectionInfo } from "./UIPipes/UIPipes";
import { getSpriteFromAtlas } from "./Utils/Sprites.utils";
import { profileFPS } from "./Profiler/Profiler";
import { createKeyboardBinding, inputControllerTick } from "./InputController/InputController";
import { BC_APP, BC_BUILDING_PLACEHOLDERS, BC_CAMERA, BC_CURRENT_SCENE, BC_SPRITES_SETTINGS, BC_TERRAIN_MANAGER, BC_VIEWPORT, BC_WORLD, PRNG, setBC_APP, setBC_CURRENT_SCENE, setBC_NPC_LAYER, setBC_SELECTION, setBC_TERRAIN_MANAGER, setBC_VIEWPORT, setBC_WORLD } from "./GlobalVariables/GlobalVariables";
import { Point2D, PointInt2D, clampNumber, interpolate,  } from "./Utils/Math.utils";
import { calculateViewportFromCamera, moveHorizontally, moveVertically, screenToWorldCoordinates } from "./Camera/Camera";

import { handleBuildingsIncome, incBuildingCount } from "./Buildings/Buildings";
import { handleDayNightCycle } from "./World/DayNightCycle";
import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/Sound";
import { addGameObjectToGameState, gameStateObjectsCleaner } from "./GameState/GameState";
import { tickHandler } from "./TickHandler/TickHandler";
import { GameScene } from "./GameScene/GameScene";
// import { createFirstWorldChunks, getTileAt, getWorldChunkAt, worldCoordinatesToChunkIndex } from "./WorldGeneration/WorldGen_";
// import { ChunkStorageTypes } from "./WorldGeneration/WorldChunk/WorldGenChunk";
// import { WorldChunksVisibilityUpdater } from "./WorldGeneration/WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater";
import { NPCProto } from "./NPC/NPCProto/NPCProto";
import { NPCController } from "./NPC/NPCController/NPCController";
import { PathFinder } from "./Utils/PathFinding.utils";
import { getNavigationGridTile } from "./World/NavigationGrid/NavigationGrid";
import { TerrainManger } from "./WorldGenV2/TerrainManager/TerrainManager";
import { generateFirstChunks } from "./WorldGenV2/WorldGenV2";
import { CHUNK_LAYER_TERRAIN } from "./WorldGenV2/Chunk/Chunk";

export function generateWorld() {

    // createFirstWorldChunks();
    startGame();
}

function setupGlobalInput() {
    window.addEventListener("wheel", (event) => {
        const delta = Math.sign(event.deltaY);
        if (delta > 0) {
            BC_CAMERA.targetZoom = Number(clampNumber(BC_CAMERA.targetZoom - BC_CAMERA.zoomStep, BC_CAMERA.minZoom, BC_CAMERA.maxZoom).toFixed(2));
        } else {
            BC_CAMERA.targetZoom = Number(clampNumber(BC_CAMERA.targetZoom + BC_CAMERA.zoomStep, BC_CAMERA.minZoom, BC_CAMERA.maxZoom).toFixed(2));
        }
        UICameraInfo.update((s) => {
            s.zoom = BC_CAMERA.targetZoom;
        });
    });
}

function setupInGameSelector() {

    let sprite0 = PIXI.Sprite.from("assets/images/selection.png");
    sprite0.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
    BC_VIEWPORT.addChild(sprite0);
    sprite0.zIndex = 100;
    setBC_SELECTION(sprite0);

    BC_VIEWPORT.eventMode = "static";
    BC_VIEWPORT.onmousemove = (e) => {
        let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
        let tile = BC_TERRAIN_MANAGER.getTileAt(new PointInt2D(t.x, t.y), CHUNK_LAYER_TERRAIN);
        if(tile)
        {
            UISelectionInfo.update((s)=>{
                s.types = [tile.tileId];
            });
        }
        t.x = BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale * Math.floor(t.x / (BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale));
        t.y = BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale * Math.floor(t.y / (BC_SPRITES_SETTINGS.defaultSize * BC_SPRITES_SETTINGS.scale));
        sprite0.position.set(t.x, t.y); 
    };

    BC_VIEWPORT.onclick = (e) => 
    {
        let t = screenToWorldCoordinates(e.data.global.x, e.data.global.y);
        // console.log(getNavigationGridTile(t.x, t.y));
        // npccc.moveTo(new Point2D(getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getX(), getTileAt(t.x, t.y, ChunkStorageTypes.TYPE_TERRAIN).worldPosition.getY()));
        let tile = getNavigationGridTile(t.x, t.y);
        if(tile.isObstacle) return;
        npccc.startTask(new PointInt2D(tile.position.getX(), tile.position.getY()));
        // npccc.moveTo(new PointInt2D(tile.position.getX(), tile.position.getY()),
        // (cb)=>{
        //     console.log(cb);
        // });
    }

}

export async function initGame() {
    const app = new PIXI.Application();
    await app.init({ resizeTo: window, antialias: false });
    document.body.appendChild(app.canvas);
    setBC_APP(app);
    app.ticker.targetFPMS = 0.14;
    app.ticker.maxFPS = 140;

    await loadGameAssets();
    UIMainPipe.update((s) => {
        s.loadingAssets = false;
    });

    // let world = new PIXI.Container();
    let viewport = new PIXI.Container();
    // let NPCLayer = new PIXI.Container();
    // world.addChild(viewport);
    // viewport.addChild(NPCLayer);
    setBC_VIEWPORT(viewport);
    // setBC_WORLD(world);
    // setBC_NPC_LAYER(NPCLayer);
    // NPCLayer.zIndex = 100;
    viewport.isRenderGroup = true;
    // NPCLayer.isRenderGroup = true;
    app.stage.addChild(viewport);
    // world.tint = 0x00ffff;

    setBC_CURRENT_SCENE(new GameScene());

    // BC_CAMERA.position.x = Math.floor(PRNG() * 3242 - 372);
    // BC_CAMERA.position.y = Math.floor(PRNG() * 1285 - 255);

    UICameraInfo.update((s)=>{
        s.position.x = BC_CAMERA.position.x;
        s.position.y = BC_CAMERA.position.y;
    })

    app.ticker.add(inputControllerTick);
    app.ticker.add(calculateViewportFromCamera);
    //static functions shitty binding
    // app.ticker.add(WorldChunksVisibilityUpdater.handleWorldChunksVisibility.bind(WorldChunksVisibilityUpdater));
    // app.ticker.add(WorldChunksVisibilityUpdater.handleWorldChunkFilling.bind(WorldChunksVisibilityUpdater));
    //end of shit
    app.ticker.add(profileFPS);
    // app.ticker.add(handleBuildingsIncome);

    createKeyboardBinding("KeyW", "Hold", [moveVertically]);
    createKeyboardBinding("KeyS", "Hold", [moveVertically]);
    createKeyboardBinding("KeyA", "Hold", [moveHorizontally]);
    createKeyboardBinding("KeyD", "Hold", [moveHorizontally]);
    // createKeyboardBinding("ArrowRight", "Down", [()=>{
    //     BC_TERRAIN_MANAGER.changeTerrain(BC_TERRAIN_MANAGER.createNewTerrain());
    // }]);

}

let npccc;

function startGame() {
    setupGlobalInput();
    setupInGameSelector();
    BC_APP.ticker.add(handleDayNightCycle);
    BC_APP.ticker.add(handleSounds);
    ambientDay.play();
    ambientNight.play();
    ambientMusic.play();
    BC_APP.ticker.add(gameStateObjectsCleaner);
    BC_APP.ticker.add(tickHandler);
    
    let terrainManager = new TerrainManger();
    terrainManager.currentTerrain = terrainManager.createNewTerrain();
    setBC_TERRAIN_MANAGER(terrainManager);
    BC_VIEWPORT.addChild(terrainManager.currentTerrain.drawObject);
    BC_APP.ticker.add(terrainManager.tickHandler.bind(terrainManager));
    generateFirstChunks();
    // createFirstWorldChunks();

    let testNPCController = new NPCController(true);
    let testNPC = new NPCProto(true, testNPCController);
    testNPC.spriteSheetPath = "assets/images/characters/char0.png";
    testNPC.frame = new PIXI.Rectangle(0, 0, 16, 16);
    testNPC.controller = testNPCController;
    testNPC.worldPosition = new PointInt2D(0,0);
    testNPCController.controlledNPC = testNPC;
    addGameObjectToGameState(testNPCController);
    BC_CURRENT_SCENE.addObjectToSceneWithInitialization(testNPC);
    testNPC.drawObject.zIndex = 4;
    testNPC.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
    npccc = testNPCController;
}
