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

AccountService::AccountService(QObject *parent)
    : QObject(parent)
{
}

QVector<Account> AccountService::getAllAccounts()
{
    return AccountDao::findAll();
}

Account* AccountService::findAccountById(int id)
{
    return AccountDao::findById(id);
}

Account* AccountService::findAccountByEmail(const QString &email)
{
    return AccountDao::findByEmail(email);
}

void AccountService::addAccount(const QString &email, const QString &providerType,
                                 const QString &accessToken, const QString &refreshToken)
{
    Account account;
    account.setEmail(email);
    account.setDisplayName(email);
    
    if (providerType == "gmail") account.setType(AccountType::Gmail);
    else if (providerType == "outlook") account.setType(AccountType::Outlook);
    else account.setType(AccountType::IMAP);
    
    account.setAccessToken(accessToken);
    account.setRefreshToken(refreshToken);

    if (AccountDao::insert(account)) {
        qDebug() << "[AccountService] Account added:" << email;
        publishAccountEvent(account, true);
        emit accountAdded(account);
        emit accountListChanged();
    } else {
        qWarning() << "[AccountService] Failed to add account:" << email;
    }
}

void AccountService::removeAccount(int accountId)
{
    Account *account = AccountDao::findById(accountId);
    if (account) {
        SynchronizerProvider::instance().unregisterSynchronizer(QString::number(accountId));
        AccountDao::remove(accountId);
        publishAccountEvent(*account, false);
        emit accountRemoved(accountId);
        emit accountListChanged();
        delete account;
    }
}

void AccountService::updateAccount(const Account &account)
{
    if (AccountDao::update(account)) {
        qDebug() << "[AccountService] Account updated:" << account.email();
        emit accountListChanged();
    }
}

void AccountService::startAuthentication(const QString &email, const QString &providerType)
{
    Authenticator *auth = createAuthenticator(providerType);
    if (auth) {
        connect(auth, &Authenticator::authenticationCompleted, this, [this](const Account &account) {
            addAccount(account.email(), 
                       account.type() == AccountType::Gmail ? "gmail" 
                       : account.type() == AccountType::Outlook ? "outlook" : "imap",
                       account.accessToken(), account.refreshToken());
        });
        connect(auth, &Authenticator::authenticationFailed, this, [](const QString &error) {
            qWarning() << "[AccountService] Authentication failed:" << error;
        });
        connect(auth, &QObject::destroyed, auth, [auth]() { /* cleanup handled by Qt */ });
        auth->authenticate(email);
    }
}

Authenticator* AccountService::createAuthenticator(const QString &providerType)
{
    if (providerType == "gmail") return new GmailAuthenticator(this);
    if (providerType == "outlook") return new OutlookAuthenticator(this);
    if (providerType == "imap") return new ImapAuthenticator(this);
    qWarning() << "[AccountService] Unknown provider:" << providerType;
    return nullptr;
}

void AccountService::publishAccountEvent(const Account &account, bool added)
{
    if (added) {
        WinoMail::Events::AccountAddedEvent event;
        event.account = account;
        EVENT_BUS.publish(event);
    } else {
        WinoMail::Events::AccountRemovedEvent event;
        event.accountId = account.id();
        EVENT_BUS.publish(event);
    }
}

#include "accountservice.moc"