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

import eu.mhsl.minenet.minigames.world.generator.featureEnriched.ValeGenerator;
import eu.mhsl.minenet.minigames.world.generator.terrain.BaseGenerator;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.generator.GenerationUnit;

import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

public class BlockBreakRaceGenerator extends BaseGenerator {
    public static final int BOTTOM_Y = 50;
    public static final int[] ROW_OFFSETS_X = {4, 8, 12};
    public static final int[] ROW_OFFSETS_Z = {4, 8, 12};
    private static final Block[] FILL_BLOCKS = {
        Block.STONE,
        Block.DIRT,
        Block.OAK_PLANKS
    };
    public final int TOP_Y;
    private final Random random = ThreadLocalRandom.current();

    public BlockBreakRaceGenerator(int height) {
        this.TOP_Y = BOTTOM_Y + height;
        ValeGenerator vale = new ValeGenerator();
        vale.setXShiftMultiplier(i -> 0.5d);
        vale.setHeightNoiseMultiplier(i -> 2);
        vale.setXShiftOffset(i -> 40d);
        this.addMixIn(vale);

        this.addMixIn(unit -> {
            if(unit.absoluteStart().chunkX() != 0) return;

            for(int localX : ROW_OFFSETS_X) {
                for(int localZ : ROW_OFFSETS_Z) {
                    final int absZ = unit.absoluteStart().blockZ() + localZ;
                    this.placeTube(unit, localX, absZ);
                }
            }
        });
    }

    private void placeTube(GenerationUnit unit, int x, int z) {
        for(int y = BOTTOM_Y; y < this.TOP_Y; y++) {
            Block fill = FILL_BLOCKS[this.random.nextInt(FILL_BLOCKS.length)];
            unit.modifier().fill(
                new Pos(x, y, z),
                new Pos(x, y, z).add(1),
                fill
            );
        }

        for(int dx = -1; dx <= 1; dx++) {
            for(int dz = -1; dz <= 1; dz++) {
                if(dx == 0 && dz == 0) continue; // Zentrum überspringen
                unit.modifier().fill(
                    new Pos(x + dx, BOTTOM_Y, z + dz),
                    new Pos(x + dx, this.TOP_Y + 3, z + dz).add(1),
                    Block.BARRIER
                );
            }
        }
    }
}
