#include <QtTest/QtTest>
#include "../../src/db/dao/accountdao.h"
#include "../../src/db/databasemanager.h"
#include "../../src/core/models/account.h"
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>

class TestAccountDao : public QObject
{
    Q_OBJECT
private slots:
    void initTestCase();
    void cleanupTestCase();
    void testInsertAndFind();
    void testUpdate();
    void testRemove();
};

void TestAccountDao::initTestCase()
{
    // Use in-memory SQLite database
    // Ensure fresh connection by removing previous connection
    QSqlDatabase::removeDatabase(QStringLiteral("wino_mail_connection"));
    QVERIFY(DatabaseManager::instance().initialize(QStringLiteral(":memory:")));
    // Create tables (initialize will do it)
}

void TestAccountDao::cleanupTestCase()
{
    // Database will be closed automatically in destructor
}

void TestAccountDao::testInsertAndFind()
{
    Account account;
    account.setEmail(QStringLiteral("test@example.com"));
    account.setDisplayName(QStringLiteral("Test User"));
    account.setSignature(QStringLiteral("Test sig"));
    account.setType(AccountType::IMAP);
    
    Account::ConnectionSettings settings;
    settings.type = QStringLiteral("imap");
    settings.incomingHost = QStringLiteral("imap.example.com");
    settings.incomingPort = 993;
    settings.incomingSsl = true;
    settings.outgoingHost = QStringLiteral("smtp.example.com");
    settings.outgoingPort = 465;
    settings.outgoingSsl = true;
    settings.username = QStringLiteral("testuser");
    settings.password = QStringLiteral("testpass");
    settings.authMethod = QStringLiteral("plain");
    account.setConnectionSettings(settings);

    qint64 insertedId = AccountDao::insert(account);
    QVERIFY(insertedId != -1);
    // Optionally set id on account for later use (if needed)
    // account.setId(insertedId);

    Account* foundPtr = AccountDao::findById(insertedId);
    QVERIFY(foundPtr != nullptr);
    Account found = *foundPtr;
    QCOMPARE(found.id(), insertedId);
    QCOMPARE(found.email(), QStringLiteral("test@example.com"));
    QCOMPARE(found.displayName(), QStringLiteral("Test User"));
    QCOMPARE(found.signature(), QStringLiteral("Test sig"));
    QCOMPARE(found.type(), AccountType::IMAP);
    QCOMPARE(found.connectionSettings().incomingHost, QStringLiteral("imap.example.com"));
    QCOMPARE(found.connectionSettings().incomingPort, 993);
    QVERIFY(found.connectionSettings().incomingSsl);
    QCOMPARE(found.connectionSettings().username, QStringLiteral("testuser"));
    QCOMPARE(found.connectionSettings().password, QStringLiteral("testpass"));
    QCOMPARE(found.connectionSettings().authMethod, QStringLiteral("plain"));
}

void TestAccountDao::testUpdate()
{
    Account account;
    account.setEmail(QStringLiteral("original@example.com"));
    account.setDisplayName(QStringLiteral("Original User"));
    account.setType(AccountType::IMAP);
    Account::ConnectionSettings settings;
    settings.type = QStringLiteral("imap");
    settings.incomingHost = QStringLiteral("imap.example.com");
    settings.incomingPort = 993;
    settings.incomingSsl = true;
    settings.outgoingHost = QStringLiteral("smtp.example.com");
    settings.outgoingPort = 465;
    settings.outgoingSsl = true;
    settings.username = QStringLiteral("user");
    settings.password = QStringLiteral("pass");
    settings.authMethod = QStringLiteral("plain");
    account.setConnectionSettings(settings);

    qint64 insertedId = AccountDao::insert(account);
    QVERIFY(insertedId != -1);
    qint64 id = insertedId;

    // Modify
    account.setEmail(QStringLiteral("updated@example.com"));
    account.setDisplayName(QStringLiteral("Updated User"));
    account.setType(AccountType::Gmail);
    Account::ConnectionSettings newSettings;
    newSettings.type = QStringLiteral("imap");
    newSettings.incomingHost = QStringLiteral("imap.gmail.com");
    newSettings.incomingPort = 993;
    newSettings.incomingSsl = true;
    newSettings.outgoingHost = QStringLiteral("smtp.gmail.com");
    newSettings.outgoingPort = 465;
    newSettings.outgoingSsl = true;
    newSettings.username = QStringLiteral("user2");
    newSettings.password = QStringLiteral("newpass");
    newSettings.authMethod = QStringLiteral("plain");
    account.setConnectionSettings(newSettings);

    bool updated = AccountDao::update(account);
    QVERIFY(updated);

    Account* foundPtr = AccountDao::findById(id);
    QVERIFY(foundPtr != nullptr);
    Account found = *foundPtr;
    QCOMPARE(found.id(), id);
    QCOMPARE(found.email(), QStringLiteral("updated@example.com"));
    QCOMPARE(found.displayName(), QStringLiteral("Updated User"));
    QCOMPARE(found.type(), AccountType::Gmail);
    QCOMPARE(found.connectionSettings().incomingHost, QStringLiteral("imap.gmail.com"));
    QCOMPARE(found.connectionSettings().incomingPort, 993);
    QVERIFY(found.connectionSettings().incomingSsl);
    QCOMPARE(found.connectionSettings().username, QStringLiteral("user2"));
    QCOMPARE(found.connectionSettings().password, QStringLiteral("newpass"));
    QCOMPARE(found.connectionSettings().authMethod, QStringLiteral("plain"));
}

void TestAccountDao::testRemove()
{
    Account account;
    account.setEmail(QStringLiteral("todelete@example.com"));
    account.setType(AccountType::IMAP);
    Account::ConnectionSettings settings;
    settings.type = QStringLiteral("imap");
    settings.incomingHost = QStringLiteral("imap.example.com");
    settings.incomingPort = 993;
    settings.incomingSsl = true;
    settings.outgoingHost = QStringLiteral("smtp.example.com");
    settings.outgoingPort = 465;
    settings.outgoingSsl = true;
    settings.username = QStringLiteral("user");
    settings.password = QStringLiteral("pass");
    settings.authMethod = QStringLiteral("plain");
    account.setConnectionSettings(settings);

    qint64 insertedId = AccountDao::insert(account);
    QVERIFY(insertedId != -1);
    qint64 id = insertedId;

    bool removed = AccountDao::remove(id);
    QVERIFY(removed);

    Account* foundPtr = AccountDao::findById(id);
    QVERIFY(foundPtr == nullptr);
}

QTEST_MAIN(TestAccountDao)
#include "test_accountdao.moc"
