package eu.mhsl.minenet.minigames.instance.game.stateless.types.tntrun;

import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.LastWinsScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.TaskSchedule;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.CompletableFuture;

public class TntRun extends StatelessGame {
    final int totalElevation = 50;
    final int heightPerLevel = 20;

    final int radius;
    final int stackCount;
    public TntRun(int radius, int stackCount) {
        super(Dimension.OVERWORLD.key, "tntRun", new LastWinsScore());
        this.radius = radius;
        this.stackCount = stackCount;
        setGenerator(new CircularPlateTerrainGenerator(radius));
    }

    @Override
    protected void onLoad(@NotNull CompletableFuture<Void> callback) {
        AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
        for (int level = 0; level < stackCount; level++) {
            for(int x = -radius; x <= radius; x++) {
                for(int z = -radius; z <= radius; z++) {
                    if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;

                    batch.setBlock(x, totalElevation + (level * heightPerLevel), z, Block.TNT);
                }
            }
        }

        BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
    }

    @Override
    protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {


        if(playerMoveEvent.getNewPosition().y() < totalElevation) {
            if(isBeforeBeginning) {
                playerMoveEvent.getPlayer().teleport(getSpawn());
                return;
            }
            playerMoveEvent.getPlayer().setGameMode(GameMode.SPECTATOR);
            getScore().insertResult(playerMoveEvent.getPlayer());
        }

        if(isRunning && !getScore().hasResult(playerMoveEvent.getPlayer())) {
            MinecraftServer.getSchedulerManager().scheduleTask(() -> {
                float radius = 0.5F;
                for (float x = -radius; x <= radius; x++) {
                    for (float z = -radius; z <= radius; z++) {
                        Pos firstLocation = playerMoveEvent.getNewPosition().add(x, -1, z);
                        Pos secondLocation = firstLocation.withY(y -> y-1);
                        if(!getBlock(firstLocation).isAir() || !getBlock(secondLocation).isAir()) {
                            setBlock(firstLocation, Block.AIR);
                            setBlock(secondLocation, Block.AIR);

//                            Entity fallingTnt = new Entity(EntityType.TNT);
//                            PrimedTntMeta fallingTntMeta = (PrimedTntMeta) fallingTnt.getEntityMeta();
//                            fallingTntMeta.setFuseTime(20);
//                            fallingTnt.setInstance(this, secondLocation);
                        }
                    }
                }
            }, TaskSchedule.millis(500), TaskSchedule.stop(), ExecutionType.TICK_END);
        }
    }

    @Override
    public Pos getSpawn() {
        return new Pos(0, totalElevation + heightPerLevel * (stackCount-1) + 1, 0);
    }
}
