#ifndef ALARMEVENTUTILS_H
#define ALARMEVENTUTILS_H

#include <QUrl>
#include "alarmEventGlobal.h"

///////------structs-----
//RabbitMQ链接配置
struct RabbitMQConfig
{
    QString host;
    int port;
    QString username;
    QString password;
    QString virtualHost;
    QString exchangeName;
    QString queueName;
    QString routingKey;
    int reconnectInterval; //重连间隔(毫秒)
    int heartbeat;
    bool autoAck;

    RabbitMQConfig()
        : port(5672)
        , reconnectInterval(3000)
        , heartbeat(60)
        , autoAck(true)
    {}

    bool isValid() const
    {
        if(host.isEmpty())
        {
            qWarning() << "RabbitMQ host is empty";
            return false;
        }
        if(port <= 0 || port > 65535)
        {
            qWarning() << "RabbitMQ port is invalid: " << port;
            return false;
        }
        if(username.isEmpty())
        {
            qWarning() << "RabbitMQ username is empty";
            return false;
        }
        if(exchangeName.isEmpty())
        {
            qWarning() << "RabbitMQ exchange name is empty";
            return false;
        }
        if(queueName.isEmpty())
        {
            qWarning() << "RabbitMQ queue name is empty";
            return false;
        }
        if(routingKey.isEmpty())
        {
            qWarning() << "RabbitMQ routingKey is empty";
            return false;
        }
        if (reconnectInterval <= 0)
        {
            qWarning() << "RabbitMQ reconnect interval is invalid:" << reconnectInterval;
            return false;
        }

        return true;
    }
};

//历史数据服务配置
struct HistoricalConfig
{
    QUrl baseUrl;
    int timeout; //请求超时(毫秒)
    QVariantMap requestHeaders;
    int maxRetries; //最大重试次数
    int retryInterval; //重试间隔

    HistoricalConfig()
        : timeout(3000)
        , maxRetries(3)
        , retryInterval(1000)
    {}

    bool isValid() const
    {
        if(!baseUrl.isValid())
        {
            qWarning() << "Historical service base URL is invalid:" << baseUrl.errorString();
            return false;
        }
        if(timeout <= 0)
        {
            qWarning() << "Historical service timeout is invalid:" << timeout;
            return false;
        }
        if(maxRetries < 0)
        {
            qWarning() << "Historical service max retries is invalid:" << maxRetries;
            return false;
        }
        if(retryInterval <= 0)
        {
            qWarning() << "Historical service retry interval is invalid:" << retryInterval;
            return false;
        }

        return true;
    }
};

//缓存配置
struct CacheConfig
{
    int maxSize; //缓存事件最大数量
    int cleanupInterval; //清理间隔(毫秒)
    bool enableStatistics; //是否统计

    CacheConfig()
        : maxSize(10000)
        , cleanupInterval(60000) //1分钟
        , enableStatistics(false)
    {}

    bool isValid() const
    {
        if(maxSize <= 0)
        {
            qWarning() << "Cache max size is invalid:" << maxSize;
            return false;
        }
        if(cleanupInterval < 0 )
        {
            qWarning() << "Cache cleanup interval is invalid:" << cleanupInterval;
            return false;
        }

        return true;
    }
};

//统一服务配置
struct ServiceConfig
{
    RabbitMQConfig rabbitMQConfig;
    HistoricalConfig historicalConfig;
    CacheConfig cacheConfig;

    ServiceConfig() {}

    bool isValid() const
    {
        return rabbitMQConfig.isValid() && historicalConfig.isValid() && cacheConfig.isValid();
    }

    //从JSON对象加载配置
    static ServiceConfig fromJson(const QJsonObject& json);
    //转化为JSON对象
    QJsonObject toJson() const;
};

///////------classes-----
class AlarmEventDataFilter
{
public:
    AlarmEventDataFilter();

    void setTimeRange(const QDateTime& start, const QDateTime& end) {m_beginTime = start; m_endTime = end;}
    QDateTime beginTime() {return m_beginTime;}
    QDateTime endTime() {return m_endTime;}
    void setStationFilter(const QString& station) {m_station = station;}
    void setBayFilter(const QString& bay) {m_bay = bay;}
    void setTypeFilter(int type) {m_type = type;}
    void setSeverityFilter(const QString& severity) {m_severity = severity;}
    void setDescriptionFilter(const QString& description) {m_description = description;}
    void setConfirmStatusFilter(int status) {m_status = status;}
    int confirmStatus() {return m_status;}

    bool matches(const EventData& event);
    void clear();
    QVector<EventData> apply(const QVector<EventData>& events);

private:
    void reset();
    bool isEmpty();

    QDateTime m_beginTime;
    QDateTime m_endTime;
    QString m_station;
    QString m_bay;
    int m_type;
    QString m_severity;
    QString m_description;
    int m_status;
};

/**
 * @brief 数据缓存
 *
 * 数据缓存的主要作用：
 * 批量存储：当数据需要做本地存储时，可以先存入缓存，达到一定数量后批量进行存储，从而减少数据库的频繁操作
 * 快速访问：按条件查询数据时，先从缓存中查找，减少数据库或网络操作
 * 数据去重：避免存储重复数据
 * 清理策略：例如采用LRU，自动清理最久未使用的数据，从而控制内存内使用
 *
 * 若有以上场景，可以按需扩展该类，目前暂无场景
 */
class AlarmEventCache
{
public:
    AlarmEventCache();

    void setMaxSize(int maxSize);
    int getMaxSize() const {return m_maxSize;}

    void addEvent(const EventData& event);
    void clear();

private:
    void trimToSize();

    int m_maxSize;
    QVector<EventData> m_events;
};

#endif
