#include "gmailauthenticator.h"
#include <QDebug>
#include <QUrlQuery>
#include <QDesktopServices>
#include <QNetworkReply>

// Gmail OAuth2 configuration
static const char* GMAIL_CLIENT_ID = "your-gmail-client-id.apps.googleusercontent.com";
static const char* GMAIL_CLIENT_SECRET = "your-gmail-client-secret";
static const char* GMAIL_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
static const char* GMAIL_TOKEN_URL = "https://oauth2.googleapis.com/token";
static const char* GMAIL_SCOPES = "https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.readonly email profile";

GmailAuthenticator::GmailAuthenticator(QObject *parent)
    : Authenticator(parent)
    , m_callbackServer(new OAuthCallbackServer(8080, this))
{
    m_clientId = GMAIL_CLIENT_ID;
    m_clientSecret = GMAIL_CLIENT_SECRET;
    m_authEndpoint = GMAIL_AUTH_URL;
    m_tokenEndpoint = GMAIL_TOKEN_URL;
    m_scopes = GMAIL_SCOPES;

    connect(m_callbackServer, &OAuthCallbackServer::codeReceived,
            this, &GmailAuthenticator::onAuthCodeReceived);
    connect(m_callbackServer, &OAuthCallbackServer::errorOccurred,
            [this](const QString &error) {
        emit authenticationFailed("OAuth callback error: " + error);
    });
}

void GmailAuthenticator::authenticate(const QString &email)
{
    m_email = email;
    m_redirectUri = m_callbackServer->redirectUri();
    qDebug() << "[GmailAuthenticator] Starting authentication for:" << email;
    qDebug() << "[GmailAuthenticator] Redirect URI:" << m_redirectUri;

    // Start local callback server before opening browser
    if (!m_callbackServer->start()) {
        emit authenticationFailed("Could not start OAuth callback server on port 8080");
        return;
    }

    QUrl authUrl(m_authEndpoint);
    QUrlQuery query;
    query.addQueryItem("client_id", m_clientId);
    query.addQueryItem("redirect_uri", m_redirectUri);
    query.addQueryItem("response_type", "code");
    query.addQueryItem("scope", m_scopes);
    query.addQueryItem("access_type", "offline");
    query.addQueryItem("prompt", "consent");
    authUrl.setQuery(query);

    qDebug() << "[GmailAuthenticator] Opening browser:" << authUrl.toString();
    QDesktopServices::openUrl(authUrl);
}

void GmailAuthenticator::onAuthCodeReceived(const QString &code, const QString &state)
{
    Q_UNUSED(state);
    qDebug() << "[GmailAuthenticator] Authorization code received, exchanging for tokens...";

    // Stop the callback server — we got what we need
    m_callbackServer->stop();

    m_authCode = code;

    // Exchange the authorization code for tokens using base class implementation
    exchangeAuthorizationCode(code, m_redirectUri, m_email);
}

void GmailAuthenticator::refreshToken(const Account &account)
{
    qDebug() << "[GmailAuthenticator] Refreshing token for account:" << account.email();

    QUrlQuery params;
    params.addQueryItem("client_id", m_clientId);
    params.addQueryItem("client_secret", m_clientSecret);
    params.addQueryItem("refresh_token", account.refreshToken());
    params.addQueryItem("grant_type", "refresh_token");

    QNetworkRequest request = createTokenRequest(QUrl(m_tokenEndpoint));
    QNetworkReply *reply = m_networkManager->post(request, params.toString(QUrl::FullyEncoded).toUtf8());
    connect(reply, &QNetworkReply::finished, this, [this, reply]() {
        handleTokenResponse(reply->readAll(), m_email, "gmail");
        reply->deleteLater();
    });
}

void GmailAuthenticator::onTokenReply(QNetworkReply *reply) {
    qDebug() << "[GmailAuthenticator] onTokenReply called";
    reply->deleteLater();
}

#include "gmailauthenticator.moc"