package com.r3944realms.modernlifepatch.content.blocks.type.mirror.shape;

import com.r3944realms.modernlifepatch.content.blocks.type.mirror.MirrorPart;
import com.r3944realms.modernlifepatch.utils.ShapeUtil;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import java.util.stream.Stream;

public class MassiveMirrorShape implements IMirrorShape {
    public static final VoxelShape F11_SHAPE_NORTH = Block.box(0, 0, 0, 16, 16, 1.1),
            F11_SHAPE_SOUTH, F11_SHAPE_EAST, F11_SHAPE_WEST,
    F10_SHAPE_NORTH =Block.box(0, 0, 0, 16, 16, 1.1),
            F10_SHAPE_SOUTH, F10_SHAPE_WEST, F10_SHAPE_EAST,
    F12_SHAPE_NORTH = Block.box(0, 0, 0, 16, 16, 1.1),
            F12_SHAPE_SOUTH, F12_SHAPE_WEST, F12_SHAPE_EAST,
    H01_SHAPE_NORTH  = Block.box(0, 0, 0, 16, 16, 1.1),
            H01_SHAPE_SOUTH, H01_SHAPE_WEST, H01_SHAPE_EAST,
    H00_SHAPE_NORTH = Block.box(0, 0, 0, 16, 16, 1.1),
            H00_SHAPE_SOUTH, H00_SHAPE_WEST, H00_SHAPE_EAST,
    H02_SHAPE_NORTH = Block.box(0, 0, 0, 16, 16, 1.1),
            H02_SHAPE_SOUTH, H02_SHAPE_WEST, H02_SHAPE_EAST;
    static {
        F11_SHAPE_EAST = ShapeUtil.RotateVoxelShapeClockwise(F11_SHAPE_NORTH);
        F11_SHAPE_SOUTH = ShapeUtil.RotateVoxelShapeClockwise(F11_SHAPE_EAST);
        F11_SHAPE_WEST = ShapeUtil.RotateVoxelShapeClockwise(F11_SHAPE_SOUTH);

        F10_SHAPE_EAST = ShapeUtil.RotateVoxelShapeClockwise(F10_SHAPE_NORTH);
        F10_SHAPE_SOUTH = ShapeUtil.RotateVoxelShapeClockwise(F10_SHAPE_EAST);
        F10_SHAPE_WEST = ShapeUtil.RotateVoxelShapeClockwise(F10_SHAPE_SOUTH);

        F12_SHAPE_EAST = ShapeUtil.RotateVoxelShapeClockwise(F12_SHAPE_NORTH);
        F12_SHAPE_SOUTH = ShapeUtil.RotateVoxelShapeClockwise(F12_SHAPE_EAST);
        F12_SHAPE_WEST = ShapeUtil.RotateVoxelShapeClockwise(F12_SHAPE_SOUTH);

        H01_SHAPE_EAST = ShapeUtil.RotateVoxelShapeClockwise(H01_SHAPE_NORTH);
        H01_SHAPE_SOUTH = ShapeUtil.RotateVoxelShapeClockwise(H01_SHAPE_EAST);
        H01_SHAPE_WEST = ShapeUtil.RotateVoxelShapeClockwise(H01_SHAPE_SOUTH);

        H00_SHAPE_EAST = ShapeUtil.RotateVoxelShapeClockwise(H00_SHAPE_NORTH);
        H00_SHAPE_SOUTH = ShapeUtil.RotateVoxelShapeClockwise(H00_SHAPE_EAST);
        H00_SHAPE_WEST = ShapeUtil.RotateVoxelShapeClockwise(H00_SHAPE_SOUTH);

        H02_SHAPE_EAST = ShapeUtil.RotateVoxelShapeClockwise(H02_SHAPE_NORTH);
        H02_SHAPE_SOUTH = ShapeUtil.RotateVoxelShapeClockwise(H02_SHAPE_EAST);
        H02_SHAPE_WEST = ShapeUtil.RotateVoxelShapeClockwise(H02_SHAPE_SOUTH);
    }
    @Override
    public VoxelShape getDefaultShape(@NotNull Direction direction) {
        return (VoxelShape) switch (direction) {
            case DOWN, UP -> Stream.empty();
            case NORTH -> F11_SHAPE_NORTH;
            case SOUTH -> F11_SHAPE_SOUTH;
            case WEST -> F11_SHAPE_WEST;
            case EAST -> F11_SHAPE_EAST;
        };
    }

    @Override
    public VoxelShape getShapeByPart(Direction direction, MirrorPart part) {
        if (!testIsRightPart(part)) throw new IllegalArgumentException("Not a right part in mirror shape");
        return switch (part) {
            case H00 -> N_S_W_E(direction, H00_SHAPE_NORTH, H00_SHAPE_SOUTH, H00_SHAPE_WEST, H00_SHAPE_EAST);
            case H01 -> N_S_W_E(direction, H01_SHAPE_NORTH, H01_SHAPE_SOUTH, H01_SHAPE_WEST, H01_SHAPE_EAST);
            case H02 -> N_S_W_E(direction, H02_SHAPE_NORTH, H02_SHAPE_SOUTH, H02_SHAPE_WEST, H02_SHAPE_EAST);
            case F10 -> N_S_W_E(direction, F10_SHAPE_NORTH, F10_SHAPE_SOUTH, F10_SHAPE_WEST, F10_SHAPE_EAST);
            case F11 -> N_S_W_E(direction, F11_SHAPE_NORTH, F11_SHAPE_SOUTH, F11_SHAPE_WEST, F11_SHAPE_EAST);
            case F12 -> N_S_W_E(direction, F12_SHAPE_NORTH, F12_SHAPE_SOUTH, F12_SHAPE_WEST, F12_SHAPE_EAST);
            default -> throw new IllegalStateException("Unexpected value: " + part);
        };
    }
    @Contract(pure = true)
    private VoxelShape N_S_W_E(@NotNull Direction direction, VoxelShape N, VoxelShape S, VoxelShape E, VoxelShape W) {
        return (VoxelShape) switch (direction) {
            case DOWN, UP -> Stream.empty();
            case NORTH -> N;
            case SOUTH -> S;
            case WEST -> E;
            case EAST -> W;
        };
    }

    @Override
    public MirrorPart.MirrorType getMirrorType() {
        return MirrorPart.MirrorType.MASSIVE_MIRROR;
    }

}
