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

import eu.mhsl.minenet.minigames.instance.game.stateless.StatelessGame;
import eu.mhsl.minenet.minigames.score.FirstWinsScore;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.world.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularPlateTerrainGenerator;
import io.github.togar2.pvp.feature.CombatFeatures;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.CompletableFuture;

class Deathcube extends StatelessGame {

    final int radius;
    final int height;
    final int percentage;

    public Deathcube(int radius, int height, int percentage, int pvpEnabled) {
        super(Dimension.THE_END.key, "Deathcube", new FirstWinsScore());
        this.radius = radius;
        this.height = height + 49;
        this.percentage = percentage;
        this.setGenerator(new CircularPlateTerrainGenerator(radius+10).setPlateHeight(50));

        if(pvpEnabled == 1) eventNode().addChild(
            CombatFeatures.empty()
                .add(CombatFeatures.VANILLA_ATTACK)
                .add(CombatFeatures.VANILLA_DAMAGE)
                .add(CombatFeatures.VANILLA_KNOCKBACK)
                .build().createNode()
        );
        System.out.println(radius);
    }

    @Override
    protected void onLoad(@NotNull CompletableFuture<Void> callback) {
        AbsoluteBlockBatch batch = new AbsoluteBlockBatch();

        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;

                for (int y = 49; y < height; y++) {
                    if(super.rnd.nextInt(1, 100) <= percentage) {
                        batch.setBlock(x, y, z, BlockPallet.WOOD.rnd());
                    }
                }
            }
        }

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

    @Override
    protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
        super.onPlayerMove(playerMoveEvent);
        if(playerMoveEvent.getNewPosition().y() < 48) {
            playerMoveEvent.setCancelled(true);
            playerMoveEvent.getPlayer().teleport(getSpawn());
            return;
        }
        if(isBeforeBeginning && playerMoveEvent.getNewPosition().y() > 51.5) {
            playerMoveEvent.setCancelled(true);
            return;
        }
        if(playerMoveEvent.getNewPosition().y() > height) getScore().insertResult(playerMoveEvent.getPlayer());
    }

    @Override
    public Pos getSpawn() {
        return new Pos(0, 50, -(radius+5));
    }
}
