/*
 *  Copyright 2025-2026 R3944Realms
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package top.r3944realms.eroticdungeongame.content.block.type;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.WoodType;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import top.r3944realms.eroticdungeongame.content.block.IWoodTypeBlock;
import top.r3944realms.eroticdungeongame.content.block.multiply.AbstractCrossSeatBlock;
import top.r3944realms.eroticdungeongame.content.block.part.CrossSeatPart;
import top.r3944realms.lib39.util.shape.ShapeUtil;

import java.util.EnumMap;
import java.util.Map;

public class PetrineCrossBlock extends AbstractCrossSeatBlock implements IWoodTypeBlock {

    private final WoodType woodType;

    public PetrineCrossBlock(WoodType woodType) {
        super(PROPERTIES);
        this.woodType = woodType;
    }

    public WoodType getWoodType() {
        return woodType;
    }

    @Override
    protected BlockPos getMiddlePartPos(BlockPos primaryPos, Direction facing) {
        return primaryPos;
    }

    @Override
    public BlockPos[] getOtherPartPositions(BlockPos currentPos, @NotNull CrossSeatPart currentPart, Direction facing) {
        BlockPos[] positions = new BlockPos[3];

        switch (currentPart) {
            case MAIN_MIDDLE -> {
                positions[0] = currentPos.relative(facing.getClockWise());         // 左边
                positions[1] = currentPos.relative(facing.getCounterClockWise());  // 右边
                positions[2] = currentPos.above();                                 // 上边
            }
            case MAIN_LEFT -> {
                // 右边 + 上面
                positions[0] = currentPos.relative(facing.getCounterClockWise());
                positions[1] = positions[0].above();
                positions[2] = currentPos.relative(facing.getCounterClockWise(),2);
            }
            case MAIN_RIGHT -> {
                // 左边 + 上面
                positions[0] = currentPos.relative(facing.getClockWise());
                positions[1] = positions[0].above();
                positions[2] = currentPos.relative(facing.getClockWise(),2);
            }
            case SECONDARY_MIDDLE -> {
                positions[0] = currentPos.below();                                   // 下边
                positions[1] = positions[0].relative(facing.getClockWise());         // 左边
                positions[2] = positions[0].relative(facing.getCounterClockWise());  // 右边
            }
        }

        return positions;
    }

    @Override
    protected void placeOtherParts(@NotNull Level level, BlockPos primaryPos, @NotNull BlockState primaryState, LivingEntity placer, ItemStack stack) {
        Direction facing = primaryState.getValue(FACING);
        // 只有这个需要考虑
        BlockPos middlePos = getMiddlePartPos(primaryPos, facing);
        BlockPos topPos = middlePos.above();
        if (level.getBlockState(topPos).canBeReplaced()) {
            BlockState middleState = primaryState.setValue(PART, CrossSeatPart.SECONDARY_MIDDLE).setValue(WATERLOGGED, level.getFluidState(topPos).getType() == Fluids.WATER);
            level.setBlock(topPos, middleState, Block.UPDATE_ALL);
        }

        // 放置顶右部件
        BlockPos leftPos = middlePos.relative(facing.getCounterClockWise());
        if (level.getBlockState(leftPos).canBeReplaced()) {
            BlockState topState = primaryState.setValue(PART, CrossSeatPart.MAIN_RIGHT).setValue(WATERLOGGED, level.getFluidState(leftPos).getType() == Fluids.WATER);
            level.setBlock(leftPos, topState, Block.UPDATE_ALL);
        }
        // 放置顶左部件
        BlockPos rightPos = middlePos.relative(facing.getClockWise());
        if (level.getBlockState(rightPos).canBeReplaced()) {
            BlockState topState = primaryState.setValue(PART, CrossSeatPart.MAIN_LEFT).setValue(WATERLOGGED, level.getFluidState(rightPos).getType() == Fluids.WATER);
            level.setBlock(rightPos, topState, Block.UPDATE_ALL);
        }

        // 更新方块
        level.blockUpdated(primaryPos, Blocks.AIR);
        primaryState.updateNeighbourShapes(level, primaryPos, Block.UPDATE_ALL);
    }

    @Override
    public BlockPos getPrimaryPartPos(@NotNull BlockState blockState, BlockPos blockPos) {
        CrossSeatPart part = blockState.getValue(PART);
        Direction facing = blockState.getValue(FACING);
        return switch (part) {
            case MAIN_MIDDLE -> blockPos;
            case MAIN_LEFT -> blockPos.relative(facing.getCounterClockWise());
            case MAIN_RIGHT -> blockPos.relative(facing.getClockWise());
            case SECONDARY_MIDDLE -> blockPos.below();
        };
    }

    @Override
    public void setupShape() {
        VoxelShape head = ShapeUtil.builder()
                .addPixelBox(4, 0, 14, 12, 16, 16)
                .build();
        VoxelShape foot = ShapeUtil.builder()
                .addPixelBox(4, 0, 14, 12, 16, 16)
                .addPixelBox(12, 8, 14, 16, 14, 16)
                .addPixelBox(0, 8, 14, 4, 14, 16)
                .build();
        VoxelShape left = ShapeUtil.builder()
                .addPixelBox(0, 8, 14, 7, 14, 16)
                .build();
        VoxelShape right = ShapeUtil.builder()
                .addPixelBox(9, 8, 14, 16, 14, 16)
                .build();
        EnumMap<CrossSeatPart, Map<Direction, VoxelShape>> shapes = new EnumMap<>(CrossSeatPart.class);
        shapes.put(CrossSeatPart.MAIN_MIDDLE, ShapeUtil.createUniformDirectionMap(foot));
        shapes.put(CrossSeatPart.SECONDARY_MIDDLE, ShapeUtil.createUniformDirectionMap(head));
        shapes.put(CrossSeatPart.MAIN_LEFT, ShapeUtil.createUniformDirectionMap(left));
        shapes.put(CrossSeatPart.MAIN_RIGHT, ShapeUtil.createUniformDirectionMap(right));
        setPartMap(shapes);
    }

    @Override
    public CrossSeatPart getPrimaryPart() {
        return CrossSeatPart.MAIN_MIDDLE;
    }
}
