#pragma once

#include "../db/dao/ruledao.h"
#include "../db/dao/categorydao.h"
#include "../db/dao/mailitemdao.h"
#include "../db/dao/folderdao.h"
#include <QVector>
#include <QMap>
#include <QJsonObject>
#include <QJsonArray>
#include <functional>

class RulesEngine
{
public:
    struct EvaluationContext
    {
        const MailItem* mailItem = nullptr;
        qint64 folderId = -1;
        qint64 accountId = -1;
        QMap<QString, QVariant> variables;
    };

    struct ActionResult
    {
        bool success = false;
        QString message;
        QVariant data;
    };

    // Main evaluation entry point
    static QVector<ActionResult> evaluateAndExecute(const EvaluationContext& ctx);

    // Rule matching
    static bool matchesConditions(const Rule& rule, const EvaluationContext& ctx);
    static bool matchCondition(const RuleCondition& cond, const EvaluationContext& ctx);
    static QString getFieldValue(const RuleCondition& cond, const EvaluationContext& ctx);

    // Action execution
    static ActionResult executeAction(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeMoveToFolder(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeMarkAsRead(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeMarkAsFlagged(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeDelete(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeAssignCategory(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeRemoveCategory(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeForwardTo(const RuleAction& action, const EvaluationContext& ctx);
    static ActionResult executeSetPriority(const RuleAction& action, const EvaluationContext& ctx);

    // Batch operations
    static int runRulesOnFolder(qint64 folderId, qint64 accountId = -1);
    static int runRulesOnMails(const QVector<qint64>& mailIds, qint64 accountId = -1);

    // Callbacks for UI integration
    using ProgressCallback = std::function<void(int processed, int total, const QString& currentRule)>;
    static void setProgressCallback(ProgressCallback cb);

private:
    static ProgressCallback s_progressCallback;
    static bool shouldStopProcessing(const RuleAction& action);
};