import { world, system, ItemStack } from "@minecraft/server";
import * as utils from "./utils";
import * as inventory_utils from "./inventory_utils";
import * as game_events from "./game_events";
import * as survival_stats from "./apps/survival_stats";

let onLoadStarted = false;
let onLoadFinished = false;
let onFirstLoadStarted = false;
let onFirstLoadFinished = false;
let onLoadFirstFinishTick = -100;
let nextIntervalTick = -100;

//Color bindings
const Orange = "§6";
const Red = "§4";
const Reset = "§r";
const Bold = "§l";

async function mainLoop() 
{
    if (system.currentTick == onLoadFirstFinishTick+20)
    {
        await utils.player0.addTag("onLoadFirstTimeFinished");
    }
        
    if (!onLoadStarted)
        await onLoad();
    else if (onLoadFinished)
        await onTick();
    
    system.run(mainLoop);
	
}

async function onLoad() {
	onLoadStarted = true;
	
	// First thing always - load player0
	await utils.onLoad();
	
	if (!utils.player0.hasTag("goe_spa_first_load_started"))
	{
		await utils.player0.addTag("goe_spa_first_load_started");
		if (await utils.player0.hasTag("goe_spa_first_load_finished"))
			return;
		
		await game_events.onLoadFirstTime();
		
		await utils.player0.addTag("goe_spa_first_load_finished");
		onLoadFirstFinishTick = system.currentTick;
	}

    // initialize modules
	await game_events.onLoad();

	// Set host join time
	survival_stats.setJoinTime(utils.player0);
	
	// Subscribe to world events
	world.afterEvents.playerSpawn.subscribe(game_events.onPlayerSpawn);
	world.afterEvents.playerJoin.subscribe(game_events.onPlayerJoin);
	world.afterEvents.entitySpawn.subscribe(game_events.onEntitySpawn);
	world.afterEvents.entityDie.subscribe(game_events.onEntityDie);
	world.afterEvents.entityHurt.subscribe(game_events.onEntityHurt);
	world.afterEvents.entityHealthChanged.subscribe(game_events.onEntityHealthChanged);
	world.afterEvents.projectileHitEntity.subscribe(game_events.onProjectileHitEntity);
	world.afterEvents.itemUse.subscribe(game_events.onItemUse);
	world.afterEvents.itemStartUse.subscribe(game_events.onItemStartUse);
	world.afterEvents.itemStopUse.subscribe(game_events.onItemStopUse);
	world.afterEvents.itemReleaseUse.subscribe(game_events.onItemReleaseUse);
	world.afterEvents.itemUseOn.subscribe(game_events.onItemUseOn);
	world.afterEvents.playerBreakBlock.subscribe(game_events.onPlayerBreakBlock);
	world.afterEvents.weatherChange.subscribe(game_events.onWeatherChange);
	
	world.beforeEvents.itemUse.subscribe(game_events.onItemUseBefore);
	
	// Subscribe to system events
	system.afterEvents.scriptEventReceive.subscribe(game_events.onScriptEventReceive);

	onLoadFinished = true;
}

async function onTick() {
	await game_events.onTick();
	
	for(let player of world.getAllPlayers()) 
	{
		if (player === undefined)
			continue;
		if(player.getDynamicProperty("goe_spa_coins") == undefined)
			player.setDynamicProperty("goe_spa_coins", 0);
		if(player.getDynamicProperty("goe_spa_music") == undefined)
			player.setDynamicProperty("goe_spa_music", "");

		if(!player.hasTag("goe_spa_starterkit")) {
			player.addTag("goe_spa_starterkit")
			player.dimension.spawnItem(new ItemStack("goe_spa:black_smartphone", 1), player.location);
		}
	}
}

system.run(mainLoop);