#include "authenticator.h"
#include <QDebug>

Authenticator::Authenticator(QObject *parent)
    : QObject(parent)
    , m_networkManager(new QNetworkAccessManager(this))
{
}

void Authenticator::exchangeAuthorizationCode(const QString &code, const QString &redirectUri, const QString &email)
{
    QUrl url(m_tokenEndpoint);
    QNetworkRequest request = createTokenRequest(url);

    QByteArray postData;
    postData.append("grant_type=authorization_code");
    postData.append("&code=" + code.toUtf8());
    postData.append("&redirect_uri=" + redirectUri.toUtf8());
    postData.append("&client_id=" + QString(m_clientId).toUtf8());
    postData.append("&client_secret=" + QString(m_clientSecret).toUtf8());

    // Capturamos email por copia para usar en el lambda
    QString capturedEmail = email;

    QNetworkReply *reply = m_networkManager->post(request, postData);
    connect(reply, &QNetworkReply::finished, this, [this, reply, capturedEmail]() {
        handleTokenResponse(reply->readAll(), capturedEmail, providerName());
        reply->deleteLater();
    });
}

void Authenticator::handleTokenResponse(const QByteArray &data, const QString &email, const QString &providerType)
{
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (!doc.isObject()) {
        emit authenticationFailed("Invalid response from server");
        return;
    }

    QJsonObject obj = doc.object();
    if (obj.contains("error")) {
        emit authenticationFailed(obj["error"].toString() + ": " + obj["error_description"].toString());
        return;
    }

    // Account::setProvider no existe; usamos setEmail + setType con mapeo desde providerType string
    Account account;
    account.setEmail(email);
    // Mapear providerType string a AccountType enum
    AccountType type = AccountType::IMAP; // default
    if (providerType == "outlook") type = AccountType::Outlook;
    else if (providerType == "gmail") type = AccountType::Gmail;
    account.setType(type);
    account.setAccessToken(obj["access_token"].toString());
    account.setRefreshToken(obj["refresh_token"].toString());
    account.setTokenExpires(QDateTime::currentDateTimeUtc().addSecs(obj["expires_in"].toInt()));

    emit authenticationCompleted(account);
}

QNetworkRequest Authenticator::createTokenRequest(const QUrl &url) const
{
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    return request;
}

#include "authenticator.moc"