package com.tiedup.remake.v2.blocks;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.phys.BlockHitResult;
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;

/**
 * Pet Cage Part Block (Slave) - Invisible structural part of a 3x3x2 multi-block cage.
 *
 * <p>No visible model, no selection outline. Provides collision shapes computed
 * from the actual OBJ model dimensions (delegated to {@link PetCageBlock#computeCageCollision}).
 * Interactions and breaking are delegated to the master.
 */
public class PetCagePartBlock extends Block {

    public static final DirectionProperty FACING =
        HorizontalDirectionalBlock.FACING;

    public PetCagePartBlock(Properties properties) {
        super(properties);
        this.registerDefaultState(
            this.stateDefinition.any().setValue(FACING, Direction.NORTH)
        );
    }

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

    @Override
    public VoxelShape getShape(
        BlockState state,
        BlockGetter level,
        BlockPos pos,
        CollisionContext context
    ) {
        // Invisible: no outline, no selection box
        return Shapes.empty();
    }

    @Override
    public VoxelShape getCollisionShape(
        BlockState state,
        BlockGetter level,
        BlockPos pos,
        CollisionContext context
    ) {
        Direction facing = state.getValue(FACING);
        BlockPos masterPos = findMasterPos(state, level, pos);
        if (masterPos == null) return Shapes.empty();
        return PetCageBlock.computeCageCollision(masterPos, facing, pos);
    }

    @Override
    public RenderShape getRenderShape(BlockState state) {
        return RenderShape.INVISIBLE;
    }

    @Override
    public InteractionResult use(
        BlockState state,
        Level level,
        BlockPos pos,
        Player player,
        InteractionHand hand,
        BlockHitResult hit
    ) {
        BlockPos masterPos = findMasterPos(state, level, pos);
        if (masterPos != null) {
            BlockState masterState = level.getBlockState(masterPos);
            if (masterState.getBlock() instanceof PetCageBlock cage) {
                return cage.use(
                    masterState,
                    level,
                    masterPos,
                    player,
                    hand,
                    hit
                );
            }
        }
        return InteractionResult.PASS;
    }

    @Override
    public void onRemove(
        BlockState state,
        Level level,
        BlockPos pos,
        BlockState newState,
        boolean isMoving
    ) {
        if (!state.is(newState.getBlock())) {
            BlockPos masterPos = findMasterPos(state, level, pos);
            if (masterPos != null) {
                BlockState masterState = level.getBlockState(masterPos);
                if (masterState.getBlock() instanceof PetCageBlock) {
                    level.destroyBlock(masterPos, true);
                }
            }
        }
        super.onRemove(state, level, pos, newState, isMoving);
    }

    @Override
    public void playerWillDestroy(
        Level level,
        BlockPos pos,
        BlockState state,
        Player player
    ) {
        // Don't call super to prevent double drops
    }

    @Nullable
    private BlockPos findMasterPos(
        BlockState partState,
        BlockGetter level,
        BlockPos partPos
    ) {
        Direction facing = partState.getValue(FACING);
        Direction left = facing.getCounterClockWise();

        int lx = left.getStepX(),
            lz = left.getStepZ();
        int fx = facing.getStepX(),
            fz = facing.getStepZ();

        for (int dy = 0; dy <= 1; dy++) {
            for (int dl = -1; dl <= 1; dl++) {
                for (int df = -1; df <= 1; df++) {
                    if (dl == 0 && dy == 0 && df == 0) continue;

                    int wx = -(dl * lx + df * fx);
                    int wz = -(dl * lz + df * fz);
                    BlockPos candidate = partPos.offset(wx, -dy, wz);

                    BlockState candidateState = level.getBlockState(candidate);
                    if (
                        candidateState.getBlock() instanceof PetCageBlock &&
                        candidateState.getValue(PetCageBlock.FACING) == facing
                    ) {
                        return candidate;
                    }
                }
            }
        }

        return null;
    }
}
