#include "pappsojsqml.h"

namespace pappso
{

void
registerQmlTypes(const char *uri, int versionMajor, int versionMinor)
{
  Q_UNUSED(uri)
  Q_UNUSED(versionMajor)
  Q_UNUSED(versionMinor)

  // Register the namespace meta object
#if 0
  // At the moment no need to register namespace pappso as metaobject.
  qmlRegisterUncreatableMetaObject(staticMetaObject,
                                   uri,
                                   versionMajor,
                                   versionMinor,
                                   "Enums",
                                   "Cannot create PappsoMS namespace");
#endif
  // Register other types here too
}

// This function needs to be called this way:
// pappso::registerEnumsToQJSEngine(engine_p)
// in the program or library linking to this library.
void
registerEnumsToQJSEngine(QJSEngine *engine)
{
  // qDebug() << "Now registering the Enums:: enums for pappso";

  // Get the meta-object for the namespace (generated by Q_NAMESPACE
  // as stated right below the Enums namespace at types.h).

  if(engine == nullptr)
    {
      qFatal() << "Cannot register class: engine is null";
    }

  const QMetaObject *metaObject = &Enums::staticMetaObject;
  // qDebug() << "Namespace Enums with full name:" << metaObject->className();

  QJSValue pappso_root_property;

  if(engine->globalObject().hasProperty("pappso"))
    {
      // qDebug() << "Global object property 'pappso' already exists.";
      pappso_root_property = engine->globalObject().property("pappso");
    }
  else
    {
      // qDebug() << "Global object property 'pappso' not found.";
      // Create a JS object for pappso
      pappso_root_property = engine->newObject();
    }

  // Create a nested JS object for Enums
  QJSValue all_js_enums = engine->newObject();

  // Loop through all enums and populate jsEnums
  for(int i = 0; i < metaObject->enumeratorCount(); ++i)
    {
      QMetaEnum iter_meta_enum = metaObject->enumerator(i);

      // qDebug() << "Now iterating in enum:" << iter_meta_enum.enumName();

      QJSValue single_js_enum = engine->newObject();

      for(int j = 0; j < iter_meta_enum.keyCount(); ++j)
        {
          // qDebug() << "Now iterating in new key:" << iter_meta_enum.key(j)
          //          << "with value:" << iter_meta_enum.value(j);

          // key() would be "LEFT", with value() = 1
          single_js_enum.setProperty(iter_meta_enum.key(j),
                                     iter_meta_enum.value(j));
        }

      // name would be CapType
      all_js_enums.setProperty(iter_meta_enum.enumName(), single_js_enum);
    }

  // Attach Enums to pappsomspp
  pappso_root_property.setProperty("Enums", all_js_enums);

  engine->globalObject().setProperty("pappso", pappso_root_property);

#if 0

  qDebug()
    << "Now checking for correct exposition of Enums::enum::<key/value> pairs.";

  QJSValue jsEnums =
    engine->globalObject().property("pappso").property("Enums");

  if(jsEnums.isUndefined())
    {
      qDebug() << "Error: pappso.Enums not found!";
      return;
    }
  else
    {
      qDebug() << "pappso.Enums JS object exists";

      // Get all enum names (properties of the Enums object)
      QJSValue propNames =
        engine->evaluate("Object.getOwnPropertyNames(pappso.Enums)");

      if(propNames.isError())
        {
          qDebug() << "JS Error:" << propNames.toString();
          return;
        }

      // Iterate through each enum
      const QStringList enumNames = propNames.toVariant().toStringList();
      for(const QString &enumName : enumNames)
        {
          QJSValue jsEnum = jsEnums.property(enumName);

          if(!jsEnum.isObject())
            {
              qDebug() << "Skipping non-object property:" << enumName;
              continue;
            }

          qDebug() << "\nChecking enum:" << enumName;

          // Get all keys of the iterated enum
          QJSValue enumKeys = engine->evaluate(
            QString("Object.getOwnPropertyNames(pappso.Enums.%1)")
              .arg(enumName));

          if(enumKeys.isError())
            {
              qDebug() << "  JS Error:" << enumKeys.toString();
              continue;
            }

          // Print key-value pairs for the iterated enum
          const QStringList keys = enumKeys.toVariant().toStringList();
          for(const QString &key : keys)
            {
              QJSValue value = jsEnum.property(key);
              qDebug() << "  " << key << "=" << value.toInt();
              qDebug().noquote() << "\nChecked enum: " << enumName << "member ("
                                 << key << " / " << value.toInt() << ")";
            }
        }
    }
#endif
}


} // namespace pappso
