#include "PropertyTypeCustomization_ObjectDefault.h"
#include "QQuickDetailsViewLayoutBuilder.h"
#include "QQuickDetailsViewRow.h"
#include "QPropertyHandle.h"
#include "IPropertyGroupProvider.h"

void PropertyTypeCustomization_ObjectDefault::customizeChildren(QPropertyHandle* inPropertyHandle, QQuickDetailsViewLayoutBuilder* inBuilder)
{
	auto objectHandle = inPropertyHandle->asObject();
	const QMetaObject* metaObject = objectHandle->getMetaObject();

	int startIndex = objectHandle->isGadget() ? 0 : 1;

	// Check if the object supports property grouping
	IPropertyGroupProvider* groupProvider = nullptr;
	if (!objectHandle->isGadget() && objectHandle->getObject()) {
		groupProvider = dynamic_cast<IPropertyGroupProvider*>(objectHandle->getObject());
	}

	if (groupProvider) {
		// Collect properties by group
		QMap<QString, QList<QMetaProperty>> groupedProps;
		QList<QMetaProperty> ungroupedProps;
		for (int i = startIndex; i < metaObject->propertyCount(); i++) {
			QMetaProperty prop = metaObject->property(i);
			QString group = groupProvider->getPropertyGroup(prop.name());
			if (group.isEmpty()) {
				ungroupedProps.append(prop);
			} else {
				groupedProps[group].append(prop);
			}
		}

		auto addProp = [&](QQuickDetailsViewLayoutBuilder* builder, QMetaProperty prop) {
			builder->addProperty(
				inPropertyHandle->findOrCreateChild(
					prop.metaType(),
					prop.name(),
					[this, prop, objectHandle]() {
						return prop.read(objectHandle->getObject());
					},
					[this, prop, objectHandle, inPropertyHandle](QVariant var) {
						prop.write(objectHandle->getObject(), var);
					}
				),
				prop.name()
			);
		};

		// Add grouped properties
		for (auto it = groupedProps.begin(); it != groupedProps.end(); ++it) {
			IDetailsViewRow* groupRow = inBuilder->addGroup(it.key());
			QQuickDetailsViewLayoutBuilder groupBuilder(groupRow);
			for (const auto& prop : it.value()) {
				addProp(&groupBuilder, prop);
			}
		}

		// Add ungrouped properties directly
		for (const auto& prop : ungroupedProps) {
			addProp(inBuilder, prop);
		}
	} else if (objectHandle->isGadget()) {
		for (int i = startIndex; i < metaObject->propertyCount(); i++) {
			QMetaProperty prop = metaObject->property(i);
			QString propName = prop.name();
			inBuilder->addProperty(
				inPropertyHandle->findOrCreateChild(
					prop.metaType(),
					propName,
					[this, prop, objectHandle]() {
						return prop.readOnGadget(objectHandle->getGadget());
					},
					[this, prop, objectHandle, inPropertyHandle](QVariant var) {
						prop.writeOnGadget(objectHandle->getGadget(), var);
						inPropertyHandle->setVar(objectHandle->getObjectHolder());
						objectHandle->refreshObjectPtr();
					}
				),
				propName
			);
		}
	}
	else {
		if (objectHandle->getObject() != nullptr) {
			for (int i = startIndex; i < metaObject->propertyCount(); i++) {
				QMetaProperty prop = metaObject->property(i);
				QString propName = prop.name();
				inBuilder->addProperty(
					inPropertyHandle->findOrCreateChild(
						prop.metaType(),
						propName,
						[this, prop, objectHandle]() {
							return prop.read(objectHandle->getObject());
						},
						[this, prop, objectHandle, inPropertyHandle](QVariant var) {
							prop.write(objectHandle->getObject(), var);
						}
					),
					propName
				);
			}
		}
	}
}

