package net.Chipperfluff.chipi.block;

import net.minecraft.block.BlockState;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;

import net.Chipperfluff.chipi.advancement.ModCriteria;

public class ChipperPortalShape {

    private final World world;
    private final BlockPos origin;
    private final Direction.Axis axis;

    public ChipperPortalShape(World world, BlockPos origin, Direction.Axis axis) {
        this.world = world;
        this.origin = origin;
        this.axis = axis;
    }

    public static boolean tryCreate(World world, BlockPos placedPos) {
        if (!(world instanceof ServerWorld serverWorld)) return false;

        for (Direction.Axis axis : new Direction.Axis[] {Direction.Axis.X, Direction.Axis.Z}) {
            ChipperPortalShape shape = new ChipperPortalShape(world, placedPos, axis);
            if (shape.isValid()) {
                shape.placePortal();

                if (serverWorld.getClosestPlayer(placedPos.getX(), placedPos.getY(), placedPos.getZ(), 10, false)
                    instanceof ServerPlayerEntity serverPlayer) {
                    ModCriteria.PORTAL_ACTIVATED.trigger(serverPlayer);
                }

                System.out.println("[CHIPI] portal created at " + placedPos + " axis=" + axis);
                return true;
            }
        }
        return false;
    }

    private boolean isValid() {
        BlockPos base = findBottomLeft();
        if (base == null) return false;

        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 5; y++) {
                boolean edge = x == 0 || x == 3 || y == 0 || y == 4;
                BlockPos pos = offset(base, x, y);
                BlockState state = world.getBlockState(pos);

                if (edge) {
                    if (!state.isOf(ModBlocks.CHIPPER_FRAME)) return false;
                } else {
                    if (!state.isAir()) return false;
                }
            }
        }
        return true;
    }

    private BlockPos findBottomLeft() {
        for (int dx = -3; dx <= 0; dx++) {
            for (int dy = -4; dy <= 0; dy++) {
                BlockPos pos = offset(origin.add(dx, dy, 0), 0, 0);
                if (world.getBlockState(pos).isOf(ModBlocks.CHIPPER_FRAME)) {
                    return pos;
                }
            }
        }
        return null;
    }

    private BlockPos offset(BlockPos pos, int x, int y) {
        return axis == Direction.Axis.X ? pos.add(0, y, x) : pos.add(x, y, 0);
    }

    private void placePortal() {
        BlockPos base = findBottomLeft();
        if (base == null) return;

        for (int x = 1; x <= 2; x++) {
            for (int y = 1; y <= 3; y++) {
                world.setBlockState(offset(base, x, y), ModBlocks.CHIPPER_PORTAL.getDefaultState(), 3);
            }
        }
    }

    public static void destroyNearby(World world, BlockPos pos) {
        for (int x = -3; x <= 3; x++) {
            for (int y = -4; y <= 4; y++) {
                for (int z = -3; z <= 3; z++) {
                    BlockPos p = pos.add(x, y, z);
                    if (world.getBlockState(p).isOf(ModBlocks.CHIPPER_PORTAL)) {
                        world.setBlockState(p, world.getFluidState(p).getBlockState(), 3);
                    }
                }
            }
        }
    }
}
