package net.Chipperfluff.chipi.block;

import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.s2c.play.PositionFlag;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import java.util.EnumSet;

public class ChipperPortalBlock extends Block {

    private static final BlockPos DEFAULT_SPAWN = new BlockPos(5, 90, 6);
    private static final Identifier CHIPI_DIM_ID = new Identifier("chipi", "chipi_dimension");

    public ChipperPortalBlock(Settings settings) {
        super(settings);
    }

    // Walk-through portal
    @Override
    public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
        return VoxelShapes.empty();
    }

    @Override
    public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
        if (world.isClient) return;
        if (!(entity instanceof PlayerEntity player)) return;

        ServerWorld targetWorld = getChipiWorld(world);
        if (targetWorld == null) return;

        teleportToChipiSpawn(targetWorld, player);
    }

    @Override
    public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) {
        return player.isCreative() ? super.calcBlockBreakingDelta(state, player, world, pos) : 0.0F;
    }

    public static void teleportToChipiSpawn(ServerWorld targetWorld, PlayerEntity player) {
        BlockPos spawn = resolveSafeSpawn(targetWorld);

        player.setVelocity(0.0, 0.0, 0.0);
        player.fallDistance = 0.0f;
        player.setOnGround(true);

        player.teleport(
            targetWorld,
            spawn.getX() + 0.5,
            spawn.getY(),
            spawn.getZ() + 0.5,
            EnumSet.noneOf(PositionFlag.class),
            player.getYaw(),
            player.getPitch()
        );

        player.setVelocity(0.0, 0.0, 0.0);
        player.fallDistance = 0.0f;
        player.setOnGround(true);
    }

    public static BlockPos resolveSafeSpawn(ServerWorld targetWorld) {
        BlockPos spawn = DEFAULT_SPAWN;
        BlockPos under = spawn.down();

        if (!targetWorld.getBlockState(under).isSolidBlock(targetWorld, under)) {
            spawn = spawn.up();
        }

        return spawn;
    }

    public static ServerWorld getChipiWorld(World world) {
        if (world == null || world.getServer() == null) return null;

        RegistryKey<World> key = RegistryKey.of(RegistryKeys.WORLD, CHIPI_DIM_ID);
        return world.getServer().getWorld(key);
    }
}
