@WorkInProgress
public abstract class DynamicPacket<R extends GenericInterface<?>> extends BidirectionalEventPacket {
    private Class<R> packetClass;


    public DynamicPacket(FriendlyByteBuf buffer) {
        super(buffer);
    }

    public DynamicPacket(R generic, @Nullable PacketData<?>... sourceData) {
        super(null, -1, sourceData);
        this.packetClass = (Class<R>) generic.getClass();
        InsightAPI.INTERFACE_REF.registerHandler(generic.getClass(), generic);
    }

    @Override
    public void decode(FriendlyByteBuf buffer) {
        try {
            this.packetClass = (Class<R>) Class.forName(buffer.readUtf());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        int size = buffer.readInt();
        this.readData = new Object[size];

        if (size > 0) {
            SerializerFactory.BuiltInFactory factory = SerializerRegistry.getFactory();

            for (int i = 0; i < size; i++) {
                boolean flag = buffer.readBoolean();
                int serializerId = buffer.readInt();
                if (serializerId != -1) {
                    DataSerializer<?> serializer = null;
                    if (flag) {
                        for (Integer enumId : factory.getEnumSerializers().inverse().values()) {
                            if (enumId == serializerId) {
                                serializer = factory.getEnumSerializer(enumId);
                                break;
                            }
                        }
                    } else {
                        serializer = factory.getSerializer(serializerId);
                    }

                    if (serializer != null) {
                        Object fromBuffer = serializer.readFromBuffer(buffer);
                        readData[i] = fromBuffer;
                    }
                }
            }
        }
    }

    @Override
    public void encode(FriendlyByteBuf buffer) {
        buffer.writeUtf(packetClass.getName());

        PacketData<?>[] sourceData = this.getSourceData();

        if (sourceData == null) {
            buffer.writeInt(0); // Prevent for null objects
        } else {
            boolean enumFlag = false;
            SerializerFactory.BuiltInFactory builtInFactory = SerializerRegistry.getFactory();

            buffer.writeInt(sourceData.length);

            for (PacketData<?> object : sourceData) {
                if (object != null) {
                    DataSerializer<?> serializer = object.getSerializer();
                    int serializerId;
                    if (EnumSerializer.class.isAssignableFrom(serializer.getClass())) {
                        enumFlag = true;
                        serializerId = builtInFactory.getEnumSerializerId(((EnumSerializer<?>) serializer));
                    } else {
                        serializerId = builtInFactory.getSerializerId(serializer);
                    }
                    buffer.writeBoolean(enumFlag);
                    buffer.writeInt(serializerId);
                    object.encode(buffer);
                } else {
                    buffer.writeInt(-1);
                }
            }
        }
    }

   public abstract void compile(Method method, Object... data);

    @Override
    protected void onHandle(Identifiable holderKey, Level level, Player player) {
        super.onHandle(holderKey, level, player);

        Method handler = InsightAPI.INTERFACE_REF.getHandler(packetClass);

        if (handler != null) {
            //  Object invoke = handler.invoke(handler.getDeclaringClass().newInstance(), getReadData());
            this.compile(handler, getReadData());
        } else {
            throw new IllegalArgumentException("No handler found for packet: " + packetClass.getName());
        }
    }
}