package ovh.glitchlabs.ornamentum.blocks.custom;

import com.google.common.collect.ImmutableMap;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;

public class ShelfBlock extends HorizontalDirectionalBlock {
    public static final MapCodec<ShelfBlock> CODEC = simpleCodec(ShelfBlock::new);
    private final ImmutableMap<BlockState, VoxelShape> shapes = this.makeShapes();

    public ShelfBlock(Properties properties) {
        super(properties);
    }

    private ImmutableMap<BlockState, VoxelShape> makeShapes() {
        return this.getShapeForEachState(state -> {
            return switch (state.getValue(FACING)) {
                case NORTH -> Shapes.or(box(0, 0, 0, 1, 16, 1), box(0, 0, 15, 1, 16, 16), box(15, 0, 15, 16, 16, 16), box(15, 0, 0, 16, 16, 1), box(14, 0, 0, 16, 16, 2), box(0, 0, 0, 2, 16, 2), box(0, 0, 14, 2, 16, 16), box(14, 0, 14, 16, 16, 16),
                        box(0.5, 10, 0.5, 15.5, 12, 15.5), box(0.5, 2, 0.5, 15.5, 4, 15.5));
                case EAST -> Shapes.or(box(15, 0, 0, 16, 16, 1), box(0, 0, 0, 1, 16, 1), box(0, 0, 15, 1, 16, 16), box(15, 0, 15, 16, 16, 16), box(14, 0, 14, 16, 16, 16), box(14, 0, 0, 16, 16, 2), box(0, 0, 0, 2, 16, 2), box(0, 0, 14, 2, 16, 16),
                        box(0.5, 10, 0.5, 15.5, 12, 15.5), box(0.5, 2, 0.5, 15.5, 4, 15.5));
                case WEST -> Shapes.or(box(0, 0, 15, 1, 16, 16), box(15, 0, 15, 16, 16, 16), box(15, 0, 0, 16, 16, 1), box(0, 0, 0, 1, 16, 1), box(0, 0, 0, 2, 16, 2), box(0, 0, 14, 2, 16, 16), box(14, 0, 14, 16, 16, 16), box(14, 0, 0, 16, 16, 2),
                        box(0.5, 10, 0.5, 15.5, 12, 15.5), box(0.5, 2, 0.5, 15.5, 4, 15.5));
                default -> Shapes.or(box(15, 0, 15, 16, 16, 16), box(15, 0, 0, 16, 16, 1), box(0, 0, 0, 1, 16, 1), box(0, 0, 15, 1, 16, 16), box(0, 0, 14, 2, 16, 16), box(14, 0, 14, 16, 16, 16), box(14, 0, 0, 16, 16, 2), box(0, 0, 0, 2, 16, 2),
                        box(0.5, 10, 0.5, 15.5, 12, 15.5), box(0.5, 2, 0.5, 15.5, 4, 15.5));
            };
        });
    }

    @Override
    public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
        return shapes.get(state);
    }

    @Override
    protected MapCodec<? extends HorizontalDirectionalBlock> codec() {
        return CODEC;
    }

    @Nullable
    @Override
    public BlockState getStateForPlacement(BlockPlaceContext context) {
        return this.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite());
    }

    @Override
    protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
        builder.add(FACING);
    }
}
