#pragma once

#include <QDateTime>
#include <QVector>
#include <optional>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QColor>

struct TemplateVariable
{
    QString name;
    QString label;
    QString defaultValue;
    QString type;  // "text", "email", "date", "select", "textarea"
    QStringList options;  // for select type
};

struct Template
{
    qint64 id{-1};
    qint64 accountId{-1};  // -1 = global
    QString name;
    QString subject;
    QString bodyHtml;
    QString bodyText;
    QVector<TemplateVariable> variables;
    bool isDefault{false};
    QDateTime createdAt;
    QDateTime updatedAt;

    bool isGlobal() const { return accountId < 0; }
    bool isValid() const { return id >= 0 && !name.isEmpty(); }
    
    QJsonObject toJson() const;
    static Template fromJson(const QJsonObject& obj);
};

struct Signature
{
    qint64 id{-1};
    qint64 accountId{-1};  // -1 = global
    QString name;
    QString html;
    bool isDefault{false};
    QDateTime createdAt;
    QDateTime updatedAt;
    
    bool isGlobal() const { return accountId < 0; }
    bool isValid() const { return id >= 0 && !name.isEmpty(); }
};

struct Category
{
    qint64 id{-1};
    qint64 accountId{-1};  // -1 = global
    QString name;
    QColor color;  // color
    qint64 parentCategoryId{-1};
    int sortOrder{0};
    QDateTime createdAt;
    
    bool isGlobal() const { return accountId < 0; }
    bool isValid() const { return id >= 0 && !name.isEmpty(); }
};

struct RuleCondition
{
    enum Field { From, To, Cc, Subject, Body, HasAttachment, Size, Date, Flagged, Read };
    enum Operator { Contains, NotContains, Equals, NotEquals, StartsWith, EndsWith, Regex, GreaterThan, LessThan, Before, After };
    
    Field field{From};
    Operator op{Contains};
    QString value;
    bool caseSensitive{false};
    
    bool match(const QString& text) const;
    QJsonObject toJson() const;
    static RuleCondition fromJson(const QJsonObject& obj);
};

struct RuleAction
{
    enum Type { 
        MoveToFolder,           // value = folderId
        MarkAsRead,             // value = "true"/"false"
        MarkAsFlagged,          // value = "true"/"false"
        Delete,                 // no value
        AssignCategory,         // value = categoryId
        RemoveCategory,         // value = categoryId
        ForwardTo,              // value = email address
        ReplyWithTemplate,      // value = templateId
        SetPriority,            // value = "high"/"normal"/"low"
        StopProcessing          // no value (stop evaluating more rules)
    };
    
    Type type{MoveToFolder};
    QString value;
    
    QJsonObject toJson() const;
    static RuleAction fromJson(const QJsonObject& obj);
};

struct Rule
{
    qint64 id{-1};
    qint64 accountId{-1};  // -1 = global
    QString name;
    QString description;
    bool enabled{true};
    int priority{100};  // lower = higher priority
    bool matchAll{true};  // true = AND, false = OR
    QVector<RuleCondition> conditions;
    QVector<RuleAction> actions;
    QDateTime createdAt;
    QDateTime updatedAt;
    QDateTime lastRun;
    qint64 runCount{0};
    
    bool isGlobal() const { return accountId < 0; }
    bool isValid() const { return id >= 0 && !name.isEmpty(); }
    
    QJsonObject toJson() const;
    static Rule fromJson(const QJsonObject& obj);
};