#include <QCoreApplication>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/qnetworkaccessmanager.h>

struct WaitlistEntry
{
  QString firstName;
  QString lastName;
  QString email;
};

QVector<WaitlistEntry> parseGraphQLResponse(const QByteArray &responseData)
{
  QVector<WaitlistEntry> waitlist;
  QJsonDocument doc = QJsonDocument::fromJson(responseData);
  if (!doc.isObject())
    return waitlist;

  QJsonObject obj = doc.object();
  QJsonArray entries = obj["data"].toObject()["getWaitlist"].toArray();

  for (const QJsonValue &value : entries)
  {
    QJsonObject entryObj = value.toObject();
    WaitlistEntry entry{entryObj["firstName"].toString(), entryObj["lastName"].toString(),
                        entryObj["email"].toString()};
    waitlist.append(entry);
  }
  return waitlist;
}

void sendGraphQLQuery(QNetworkAccessManager &manager)
{
  QUrl url("https://helios.dev.flowy.live/query");
  QNetworkRequest request(url);
  request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
  request.setRawHeader("Authorization", "talksik");

  // Define GraphQL query
  QJsonObject json;
  json["query"] = R"(
        query {
            getWaitlist {
                firstName
                lastName
                email
            }
        }
    )";

  // Convert to JSON and send request
  QNetworkReply *reply = manager.post(request, QJsonDocument(json).toJson());

  // Handle response asynchronously
  QObject::connect(reply, &QNetworkReply::finished, [reply]() {
    if (reply->error() == QNetworkReply::NoError)
    {
      auto response = reply->readAll();

      auto parsedEntries = parseGraphQLResponse(response);

      for (const auto &entry : parsedEntries)
      {
        qDebug() << "Entry: " << entry.email << Qt::endl;
      }
    }
    else
    {
      qDebug() << "Error:" << reply->errorString();
    }
    reply->deleteLater();

    QCoreApplication::quit();
  });
}

int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);

  // Set up code that uses the Qt event loop here.
  // Call a.quit() or a.exit() to quit the application.
  // A not very useful example would be including
  // #include <QTimer>
  // near the top of the file and calling
  // QTimer::singleShot(5000, &a, &QCoreApplication::quit);
  // which quits the application after 5 seconds.

  // If you do not need a running Qt event loop, remove the call
  // to a.exec() or use the Non-Qt Plain C++ Application template.
  qDebug() << "Sending GraphQL query...";
  QNetworkAccessManager manager;
  sendGraphQLQuery(manager);
  qDebug() << "Waiting for response...";

  return a.exec();
}
