import { ModalFormData } from "@minecraft/server-ui";
import { system, world } from "@minecraft/server";
import * as utils from "../utils";
import * as inventory_utils from "../inventory_utils";
import * as Vector3 from "../vector3";
import * as gld from "../gld";
import { showApp as main_menu, checkDepletedBattery } from "./main_menu"; 

const flashlightName = gld.getAppData("flashlight");

export async function showApp(player){
    if (await checkDepletedBattery(player))
        return;
    let flashlightEnabled = await player.getDynamicProperty("goe_spa_flashlight_enabled");
    let flashlightLevel = await player.getDynamicProperty("goe_spa_flashlight_level");
    
    if(!flashlightEnabled)
        flashlightEnabled = false;
    if(!flashlightLevel)
        flashlightLevel = 0;

    const FlashlightApp = new ModalFormData().title(flashlightName.name)
        .slider(gld.getScreenTitle(player) + 
            "Use this app to get a useful light source in dark places.\n\n" +
            "§dFlashlight strength", 0, 15, 1, flashlightLevel);
        //.toggle("␪§bFlashlight", flashlightEnabled);

    FlashlightApp.show(player).then(formData => {
        inventory_utils.replacePhoneIfUIClosed(player, formData);
        if (formData.formValues)
        {
            player.playSound("goe_spa:flashlight");
            let newFlashlightLevel = formData.formValues[0];
            let newFlashlightEnabled = formData.formValues[0] === 0 ? false : true; // formData.formValues[1];
            player.setDynamicProperty("goe_spa_flashlight_level", newFlashlightLevel);
            player.setDynamicProperty("goe_spa_flashlight_enabled", newFlashlightEnabled);
            player.addTag("goe_spa_flashlight_updated");
            if (flashlightEnabled && newFlashlightEnabled && (flashlightLevel !== newFlashlightLevel))
               updateLightLevel(player, newFlashlightLevel);
            main_menu(player);
        }   
    });
}

export async function onTick() {
    for(let player of world.getAllPlayers()) {
        if(player === undefined)
            continue;

        let flashlightEnabled = player.getDynamicProperty("goe_spa_flashlight_enabled");
        let lightIsAactive = player.hasTag("goe_spa_flashlight_mode");
        let isHoldingPhone = inventory_utils.isHoldingPhone(player);

        if (flashlightEnabled)
        {
            if (isHoldingPhone)
                await applyLightEffect(player);
            else if (lightIsAactive)
                await removeLightEffect(player);
        }
        else
        {
            if (lightIsAactive)
                await removeLightEffect(player);
        }
    }
}

async function applyLightEffect(player) {
	if (player.getEffect("darkness") !== undefined )
		await player.removeEffect("darkness");
	
    let lightLevel = player.getDynamicProperty("goe_spa_flashlight_level");
    let oldLightLocation = await player.getDynamicProperty("goe_spa_light_location");
	let newLightLocation = Vector3.copyFloor(player.location);
	if (newLightLocation.equals(oldLightLocation) && !player.hasTag("goe_spa_flashlight_updated"))
		return;
    player.removeTag("goe_spa_flashlight_updated");

	player.setDynamicProperty("goe_spa_light_location", newLightLocation.toLocation());
    
    if (oldLightLocation === undefined)
        player.addTag("goe_spa_flashlight_mode");
    else
	{	
        if (newLightLocation.x === oldLightLocation.x + 1)
        {
            oldLightLocation = Vector3.copy(oldLightLocation);
            let corner1 = oldLightLocation.add({x:-1, y:-1, z:-1});
            let corner2 = oldLightLocation.add({x:-1, y:1, z:1});
            await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} air replace light_block`);
        }
        else if (newLightLocation.x === oldLightLocation.x - 1)
        {
            oldLightLocation = Vector3.copy(oldLightLocation);
            let corner1 = oldLightLocation.add({x:1, y:-1, z:-1});
            let corner2 = oldLightLocation.add({x:1, y:1, z:1});
            await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} air replace light_block`);
        }
        if (newLightLocation.y === oldLightLocation.y + 1)
        {
            oldLightLocation = Vector3.copy(oldLightLocation);
            let corner1 = oldLightLocation.add({x:-1, y:-1, z:-1});
            let corner2 = oldLightLocation.add({x:1, y:-1, z:1});
            await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} air replace light_block`);
        }
        else if (newLightLocation.y === oldLightLocation.y - 1)
        {
            oldLightLocation = Vector3.copy(oldLightLocation);
            let corner1 = oldLightLocation.add({x:-1, y:1, z:-1});
            let corner2 = oldLightLocation.add({x:1, y:1, z:1});
            await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} air replace light_block`);
        }
        if (newLightLocation.z === oldLightLocation.z + 1)
        {
            oldLightLocation = Vector3.copy(oldLightLocation);
            let corner1 = oldLightLocation.add({x:-1, y:-1, z:-1});
            let corner2 = oldLightLocation.add({x:1, y:1, z:-1});
            await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} air replace light_block`);
        }
        else if (newLightLocation.z === oldLightLocation.z - 1)
        {
            oldLightLocation = Vector3.copy(oldLightLocation);
            let corner1 = oldLightLocation.add({x:-1, y:-1, z:1});
            let corner2 = oldLightLocation.add({x:1, y:1, z:1});
            await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} air replace light_block`);
        }
	}
    
	let corner1 = newLightLocation.add(-1);
	let corner2 = newLightLocation.add(1);
	await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} light_block["block_light_level"=${lightLevel}] replace air`);
}

async function updateLightLevel(player, newLevel) {
    let lightLocation = player.getDynamicProperty("goe_spa_light_location");
	let corner1 = Vector3.copy(lightLocation).add(-1);
	let corner2 = Vector3.copy(lightLocation).add(1);
	await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} light_block["block_light_level"=${newLevel}] replace light_block`);
}

export async function removeLightEffect(player) {
    player.removeTag("goe_spa_flashlight_mode");
    let lightLocation = await player.getDynamicProperty("goe_spa_light_location");
    let lightLevel= player.getDynamicProperty("goe_spa_flashlight_level");
	if (lightLocation === undefined)
		return;
	
	lightLocation = Vector3.copy(lightLocation);
	let corner1 = lightLocation.add(-1);
	let corner2 = lightLocation.add(1);
    await utils.runPlayerCommand(player, `fill ${corner1.toCommand()} ${corner2.toCommand()} air replace light_block`);
	player.setDynamicProperty("goe_spa_light_location", undefined);
}
