#include "syncscheduler.h"
#include <QDebug>
#include <QSettings>
#include "db/dao/accountdao.h"
#include "core/synchronizerprovider.h"
#include "services/synchronizer.h"
#include "core/eventbus.h"
#include "core/events.h"

SyncScheduler::SyncScheduler(QObject *parent)
    : QObject(parent)
{
    m_syncTimer = new QTimer(this);
    m_syncTimer->setInterval(m_syncIntervalMinutes * 60 * 1000); // convert minutes to milliseconds
    connect(m_syncTimer, &QTimer::timeout, this, &SyncScheduler::onTimerTick);
}

void SyncScheduler::start()
{
    // Load last sync timestamp from settings
    QSettings settings;
    qint64 lastSync = settings.value("lastSyncTimestamp", 0).toLongLong();
    // If never synced, we can set to a long time ago to allow immediate sync if conditions met
    if (lastSync == 0) {
        lastSync = QDateTime::currentDateTimeUtc().toSecsSinceEpoch() - (m_minDaysBetweenSync * 24 * 60 * 60);
        settings.setValue("lastSyncTimestamp", lastSync);
    }
    m_syncTimer->start();
    qDebug() << "SyncScheduler started. Next check in" << m_syncIntervalMinutes << "minutes.";
}

void SyncScheduler::stop()
{
    m_syncTimer->stop();
    qDebug() << "SyncScheduler stopped.";
}

void SyncScheduler::triggerSync()
{
    performSync();
}

void SyncScheduler::onTimerTick()
{
    qDebug() << "SyncScheduler: Timer tick at" << QDateTime::currentDateTime().toString();
    if (shouldRunSync()) {
        performSync();
    } else {
        qDebug() << "SyncScheduler: Conditions not met for sync at this time.";
    }
}

void SyncScheduler::performSync()
{
    qDebug() << "SyncScheduler: Performing synchronization...";
    bool syncPerformed = false;

    // Get all accounts
    QVector<Account> accounts = AccountDao::findAll();
    for (const Account& account : accounts) {
        // Get the synchronizer for this account
        Synchronizer* synchronizer = SynchronizerProvider::instance().getSynchronizer(QString::number(account.id()));
        if (!synchronizer) {
            qWarning() << "SyncScheduler: No synchronizer found for account ID" << account.id();
            continue;
        }

        // Optionally, we could initialize the synchronizer if not already initialized.
        // However, we assume it's already initialized and registered (e.g., when account was added).
        // If we want to be safe, we can try to initialize it here.
        // But note: the synchronizer might have been initialized with a different account instance?
        // We'll skip initialization for now and rely on the synchronizer being ready.

        // Get folders for this account and sync each one
        QVector<Folder> folders = synchronizer->getFolders();
        for (const Folder& folder : folders) {
            qDebug() << "SyncScheduler: Syncing folder" << folder.name() << "for account ID" << account.id();
            bool success = synchronizer->syncFolder(folder);
            if (!success) {
                qWarning() << "SyncScheduler: Failed to sync folder" << folder.name() << "for account ID" << account.id();
            }
            syncPerformed = true;
        }
    }

    if (syncPerformed) {
        // Update last sync timestamp only if we actually performed a sync
        QSettings settings;
        qint64 now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch();
        settings.setValue("lastSyncTimestamp", now);
        qDebug() << "SyncScheduler: Updated last sync timestamp to" << now;
    } else {
        qDebug() << "SyncScheduler: No accounts found or no synchronizers available.";
    }
}

bool SyncScheduler::shouldRunSync() const
{
    // Check if enough time has passed since last sync
    qint64 lastSync = getLastSyncTimestamp();
    qint64 now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch();
    qint64 minIntervalSecs = m_minDaysBetweenSync * 24 * 60 * 60;
    if (now - lastSync < minIntervalSecs) {
        qDebug() << "SyncScheduler: Not enough time since last sync. Last:" << lastSync << "Now:" << now;
        return false;
    }
    // Check if current hour >= m_runHour (UTC? we'll use local time for simplicity)
    QDateTime nowUtc = QDateTime::currentDateTimeUtc();
    if (nowUtc.time().hour() < m_runHour) {
        qDebug() << "SyncScheduler: Current UTC hour" << nowUtc.time().hour() << "is less than run hour" << m_runHour;
        return false;
    }
    return true;
}

qint64 SyncScheduler::getLastSyncTimestamp() const
{
    QSettings settings;
    return settings.value("lastSyncTimestamp", 0).toLongLong();
}

void SyncScheduler::setLastSyncTimestamp(qint64 timestamp)
{
    QSettings settings;
    settings.setValue("lastSyncTimestamp", timestamp);
}
#include "syncscheduler.moc"
