#ifndef MESSAGE_H
#define MESSAGE_H

#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <QPropertyAnimation>
#include <mutex>

#define POP_MSG(...) Message::instance()->Push(__VA_ARGS__)

enum MessageType {
    MESSAGE_TYPE_SUCCESS = 0x20,
    MESSAGE_TYPE_ERROR,
    MESSAGE_TYPE_WARNING,
    MESSAGE_TYPE_INFORMATION
};

class MessageItem;

class Message : public QObject
{
    Q_OBJECT
public:
    static Message *instance();
    explicit Message(QObject *parent = nullptr);
    explicit Message(int duration, QObject *parent = nullptr);
    ~Message() override;

    /**
     * @brief Push 推入消息
     * @param type 消息类型
     * @param content 消息内容
     */
    void Push(MessageType type, QString content);

    /**
     * @brief SetDuration 设置消息显示的时间
     * @param nDuration 显示时间,必须大于等于0,若等于0则不消失
     */
    void setDuration(int nDuration);

private:
    std::vector<MessageItem*> messages_;
    std::mutex mtx_;
    int width_;
    int duration_;

private slots:
    void adjustItemPos(MessageItem* pItem);
    void removeItem(MessageItem* pItem);
};

class MessageItem : public QWidget
{
    Q_OBJECT
public:
    explicit MessageItem(QWidget* parent = nullptr,
                         MessageType type = MessageType::MESSAGE_TYPE_INFORMATION,
                         const QString content = "",
                         const int duration = 3000,
                         const int iconMargin = 12,
                         const int leftMargin = 64,
                         const int topMargin = 10,
                         const int minWidth = 400,
                         const int minHeight = 70);
    ~MessageItem() override;
    void Show();
    void Close();
    void SetDuration(int nDuration);

protected:
    void paintEvent(QPaintEvent *event) override;

private:
    void AppearAnimation();
    void DisappearAnimation();

private:
    QTimer lifeTimer_;
    int width_;
    int height_;
    int duration_;
    QLabel* pLabelIcon_;
    QLabel* pLabelContent_;

signals:
    void itemReadyRemoved(MessageItem* pItem);
    void itemRemoved(MessageItem* pItem);
};

#endif // MESSAGE_H