/*
 * SPDX-FileCopyrightText: 2026 KOKA99CAB
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

package net.koka99cab.portals.world.feature;

import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;

public final class SkeletonBasaltSpikeFeature extends Feature<NoneFeatureConfiguration> {
	private static final BlockState BASALT = Blocks.BASALT.defaultBlockState();
	private static final BlockState SMOOTH_BASALT = Blocks.SMOOTH_BASALT.defaultBlockState();
	private static final BlockState SOUL_SOIL = Blocks.SOUL_SOIL.defaultBlockState();

	public SkeletonBasaltSpikeFeature(Codec<NoneFeatureConfiguration> codec) {
		super(codec);
	}

	@Override
	public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
		WorldGenLevel level = context.level();
		RandomSource random = context.random();
		BlockPos origin = context.origin();
		int y = level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, origin.getX(), origin.getZ());

		if (y <= level.getMinY() + 4 || y >= level.getMaxY() - 8) {
			return false;
		}

		BlockPos base = new BlockPos(origin.getX(), y - 1, origin.getZ());

		if (level.getBlockState(base).isAir()) {
			return false;
		}

		int height = Math.min(10 + random.nextInt(27), level.getMaxY() - y - 2);
		int baseRadius = 2 + random.nextInt(4);

		if (height < 10) {
			return false;
		}

		boolean placed = false;

		for (int dy = 0; dy < height; dy++) {
			double taper = 1.0D - (double) dy / (double) height;
			int radius = Math.max(0, (int) Math.ceil(baseRadius * taper + random.nextDouble() * 0.85D - 0.35D));

			for (int dx = -radius; dx <= radius; dx++) {
				for (int dz = -radius; dz <= radius; dz++) {
					double distance = Math.sqrt(dx * dx + dz * dz);

					if (distance > radius + random.nextDouble() * 0.8D || dy > 2 && random.nextInt(18) == 0) {
						continue;
					}

					BlockState state = random.nextInt(5) == 0 ? SMOOTH_BASALT : BASALT;
					placed |= placeBlock(level, base.offset(dx, dy, dz), state);
				}
			}
		}

		for (int shard = 0; shard < 2 + random.nextInt(4); shard++) {
			int dx = random.nextInt(baseRadius * 4 + 1) - baseRadius * 2;
			int dz = random.nextInt(baseRadius * 4 + 1) - baseRadius * 2;
			int shardHeight = 3 + random.nextInt(Math.max(4, height / 3));

			for (int dy = 0; dy < shardHeight; dy++) {
				placed |= placeBlock(level, base.offset(dx, dy, dz), random.nextInt(4) == 0 ? SMOOTH_BASALT : BASALT);
			}
		}

		for (int dx = -baseRadius - 1; dx <= baseRadius + 1; dx++) {
			for (int dz = -baseRadius - 1; dz <= baseRadius + 1; dz++) {
				if (Math.abs(dx) + Math.abs(dz) > baseRadius + 2 || random.nextInt(4) == 0) {
					continue;
				}

				BlockPos scatter = base.offset(dx, -1, dz);

				if (!level.getBlockState(scatter).isAir()) {
					placed |= placeBlock(level, scatter, SOUL_SOIL);
				}
			}
		}

		return placed;
	}

	private static boolean placeBlock(WorldGenLevel level, BlockPos pos, BlockState state) {
		if (pos.getY() <= level.getMinY() || pos.getY() >= level.getMaxY() || !level.ensureCanWrite(pos)) {
			return false;
		}

		level.setBlock(pos, state, 3);
		return true;
	}
}
