#include "BubbleMessageManager.h"

#include <algorithm>

#include <QAbstractTextDocumentLayout>
#include <QFileInfo>
#include <QGuiApplication>
#include <QImageReader>
#include <QScreen>
#include <QScrollBar>
#include <QTextBlock>
#include <QTextCursor>
#include <QTextDocumentFragment>

// 基础气泡消息实现
BubbleMessage::BubbleMessage(const QString &content,
                             MessageType type,
                             MessageDirection direction,
                             QGraphicsItem *parent)
    : QGraphicsItem(parent)
    , m_type(type)
    , m_direction(direction)
    , m_content(content)
    , m_timestamp(QDateTime::currentDateTime())
    , m_isHovered(false)
    , m_padding(10)
    , m_borderRadius(8)
    , m_avatarSize(40)
    , m_isSelecting(false)
{
    setAcceptHoverEvents(true);

    // 根据消息方向设置不同的颜色
    if (direction == Sent) {
        m_bubbleColor = QColor(0, 145, 255);
        m_textColor = Qt::white;
    } else {
        m_bubbleColor = QColor(240, 240, 240);
        m_textColor = Qt::black;
    }

    m_font = QFont("Microsoft YaHei", 10);
    updateSize();
}

BubbleMessage::~BubbleMessage() {}

QRectF BubbleMessage::boundingRect() const
{
    // 时间消息和撤回消息不需要考虑头像
    if (m_type == TimeMessage || m_type == RecallMessage) {
        return m_boundingRect;
    } else {
        // 为头像预留空间，但不改变气泡本身的位置
        QRectF rect = m_boundingRect;
        if (m_direction == Sent) {
            // 发送消息：头像在右侧，扩展boundingRect但不移动气泡
            rect.setWidth(rect.width() + m_avatarSize + 10);
        } else {
            // 接收消息：头像在左侧，扩展boundingRect并向左移动
            rect.setX(-m_avatarSize - 10);
            rect.setWidth(rect.width() + m_avatarSize + 10);
        }
        return rect;
    }
}

void BubbleMessage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    Q_UNUSED(option);
    Q_UNUSED(widget);

    painter->setRenderHint(QPainter::Antialiasing);

    // 绘制气泡背景
    QPainterPath path;
    path.addRoundedRect(m_boundingRect, m_borderRadius, m_borderRadius);

    // 添加小三角形指向头像
    if (m_type != TimeMessage && m_type != RecallMessage && !m_avatar.isNull()) {
        if (m_direction == Sent) {
            // 发送消息：右侧小三角
            QPointF triangleTop(m_boundingRect.right(), m_boundingRect.top() + 20);
            QPointF triangleBottom(m_boundingRect.right(), m_boundingRect.top() + 40);
            QPointF trianglePoint(m_boundingRect.right() + 10, m_boundingRect.top() + 30);

            QPainterPath trianglePath;
            trianglePath.moveTo(triangleTop);
            trianglePath.lineTo(trianglePoint);
            trianglePath.lineTo(triangleBottom);
            trianglePath.lineTo(triangleTop);

            path.addPath(trianglePath);
        } else {
            // 接收消息：左侧小三角
            QPointF triangleTop(m_boundingRect.left(), m_boundingRect.top() + 20);
            QPointF triangleBottom(m_boundingRect.left(), m_boundingRect.top() + 40);
            QPointF trianglePoint(m_boundingRect.left() - 10, m_boundingRect.top() + 30);

            QPainterPath trianglePath;
            trianglePath.moveTo(triangleTop);
            trianglePath.lineTo(trianglePoint);
            trianglePath.lineTo(triangleBottom);
            trianglePath.lineTo(triangleTop);

            path.addPath(trianglePath);
        }
    }

    painter->fillPath(path, m_bubbleColor);

    // 如果鼠标悬停，绘制边框
    if (m_isHovered && isSelectable()) {
        QPen pen(Qt::gray, 1, Qt::DashLine);
        painter->setPen(pen);
        painter->drawPath(path);
    }

    // 绘制头像（除了时间消息和撤回消息）
    if (m_type != TimeMessage && m_type != RecallMessage && !m_avatar.isNull()) {
        QRectF avatarRect;
        if (m_direction == Sent) {
            // 发送消息：头像在气泡右侧
            avatarRect = QRectF(m_boundingRect.right() + 10, 0, m_avatarSize, m_avatarSize);
        } else {
            // 接收消息：头像在气泡左侧
            avatarRect = QRectF(-m_avatarSize - 10, 0, m_avatarSize, m_avatarSize);
        }

        // 绘制圆形头像
        QPainterPath avatarPath;
        avatarPath.addEllipse(avatarRect);
        painter->setClipPath(avatarPath);
        painter->drawPixmap(avatarRect, m_avatar, m_avatar.rect());
        painter->setClipping(false);
    }
}

void BubbleMessage::updateSize()
{
    // 默认大小，子类会重写此方法
    m_boundingRect = QRectF(0, 0, 200, 50);
}

void BubbleMessage::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    if (!isSelectable()) {
        QGraphicsItem::contextMenuEvent(event);
        return;
    }

    QMenu menu;
    QAction *copyAction = menu.addAction("复制全部");

    class TextMessage *textMsg = dynamic_cast<class TextMessage *>(this);
    QAction *copySelectedAction = nullptr;

    if (textMsg && textMsg->m_hasSelection && textMsg->m_selectionStart != textMsg->m_selectionEnd) {
        copySelectedAction = menu.addAction("复制选中文本");
    }

    QAction *selectedAction = menu.exec(event->screenPos());
    if (selectedAction == copyAction) {
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(m_content);
    } else if (selectedAction == copySelectedAction) {
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(textMsg->selectedText());
    }

    event->accept();
}

void BubbleMessage::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    QGraphicsItem::mousePressEvent(event);
}

void BubbleMessage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    QGraphicsItem::mouseReleaseEvent(event);
}

void BubbleMessage::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    m_isHovered = true;
    update();
    QGraphicsItem::hoverEnterEvent(event);
}

void BubbleMessage::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    m_isHovered = false;
    update();
    QGraphicsItem::hoverLeaveEvent(event);
}

// 时间消息实现
TimeMessage::TimeMessage(const QDateTime &time, QGraphicsItem *parent)
    : BubbleMessage(time.toString("yyyy-MM-dd hh:mm:ss"), MessageType::TimeMessage, Received, parent)
{
    m_bubbleColor = QColor(230, 230, 230, 150);
    m_textColor = QColor(100, 100, 100);
    updateSize();
}

void TimeMessage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    BubbleMessage::paint(painter, option, widget);

    painter->setFont(m_font);
    painter->setPen(m_textColor);
    painter->drawText(m_boundingRect, Qt::AlignCenter, m_content);
}

// 文本消息实现
TextMessage::TextMessage(const QString &text, MessageDirection direction, QGraphicsItem *parent)
    : BubbleMessage(text, MessageType::TextMessage, direction, parent)
{
    m_textDocument.setDefaultFont(m_font);
    m_textDocument.setDocumentMargin(m_padding);
    m_textDocument.setHtml(text);

    // 确保接收鼠标事件
    setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
    setFlag(QGraphicsItem::ItemIsSelectable, true);

    updateSize();
}
void TextMessage::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        QPointF pos = event->pos();
        if (m_boundingRect.contains(pos)) {
            m_isSelecting = true;
            m_selectionStart = positionAt(pos - QPointF(m_padding, m_padding));
            m_selectionEnd = m_selectionStart;
            m_hasSelection = false;
            update();
        }
    }
    BubbleMessage::mousePressEvent(event);
}

void TextMessage::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_isSelecting) {
        QPointF pos = event->pos();
        m_selectionEnd = positionAt(pos - QPointF(m_padding, m_padding));
        m_hasSelection = true;
        update();
    }
    BubbleMessage::mouseMoveEvent(event);
}

void TextMessage::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (m_isSelecting) {
        m_isSelecting = false;
        if (m_hasSelection && m_selectionStart != m_selectionEnd) {
            // 如果有选中文本，可以在这里显示复制菜单
            QMenu menu;
            QAction *copyAction = menu.addAction("复制选中文本");

            QAction *selectedAction = menu.exec(event->screenPos());
            if (selectedAction == copyAction) {
                QClipboard *clipboard = QApplication::clipboard();
                clipboard->setText(selectedText());
            }
        }
    }
    BubbleMessage::mouseReleaseEvent(event);
}

// 获取指定位置的文本位置
int TextMessage::positionAt(const QPointF &pos) const
{
    return m_textDocument.documentLayout()->hitTest(pos, Qt::FuzzyHit);
}

// 获取选中的文本
QString TextMessage::selectedText()
{
    if (!m_hasSelection || m_selectionStart == m_selectionEnd)
        return QString();

    QTextCursor cursor(&m_textDocument);
    int start = qMin(m_selectionStart, m_selectionEnd);
    int end = qMax(m_selectionStart, m_selectionEnd);

    cursor.setPosition(start);
    cursor.setPosition(end, QTextCursor::KeepAnchor);

    return cursor.selectedText();
}
void TextMessage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    BubbleMessage::paint(painter, option, widget);

    painter->setFont(m_font);
    painter->setPen(m_textColor);

    // 保存画家状态
    painter->save();
    painter->translate(m_padding, m_padding);

    // 设置文本颜色
    QAbstractTextDocumentLayout::PaintContext context;
    context.palette.setColor(QPalette::Text, m_textColor);

    // 如果有选中区域，设置选中区域的格式
    if (m_hasSelection && m_selectionStart != m_selectionEnd) {
        QTextCursor cursor(&m_textDocument);
        int start = qMin(m_selectionStart, m_selectionEnd);
        int end = qMax(m_selectionStart, m_selectionEnd);

        cursor.setPosition(start);
        cursor.setPosition(end, QTextCursor::KeepAnchor);

        QAbstractTextDocumentLayout::Selection selection;
        selection.cursor = cursor;
        selection.format.setBackground(Qt::lightGray);
        selection.format.setForeground(Qt::black);

        context.selections.append(selection);
    }

    // 绘制文本
    m_textDocument.documentLayout()->draw(painter, context);

    // 恢复画家状态
    painter->restore();
}

void TextMessage::updateSize()
{
    // 使用视图宽度而不是屏幕宽度
    int viewWidth = 500; // 默认值

    // 尝试获取实际视图宽度
    if (scene() && !scene()->views().isEmpty()) {
        viewWidth = scene()->views().first()->width();
    }

    // 使用视图宽度的60%，并减去边距和头像空间
    int maxWidth = viewWidth * 0.6 - m_avatarSize - 30; // 30为额外边距
    m_textDocument.setTextWidth(maxWidth - 2 * m_padding);

    QSizeF docSize = m_textDocument.size();
    m_boundingRect = QRectF(0, 0, docSize.width() + 2 * m_padding, docSize.height() + 2 * m_padding);
}

// 成功消息实现
SuccessMessage::SuccessMessage(const QString &text,
                               MessageDirection direction,
                               QGraphicsItem *parent)
    : TextMessage(text, direction, parent)
{
    m_type = MessageType::SuccessMessage;
    m_bubbleColor = QColor(76, 175, 80);
    m_textColor = Qt::white;
}

void SuccessMessage::paint(QPainter *painter,
                           const QStyleOptionGraphicsItem *option,
                           QWidget *widget)
{
    TextMessage::paint(painter, option, widget);

    // 绘制成功图标
    painter->setPen(Qt::white);
    painter->setBrush(Qt::white);

    QRectF iconRect(m_boundingRect.right() - 25, m_boundingRect.top() + 5, 20, 20);
    painter->drawEllipse(iconRect.center(), 8, 8);

    QPainterPath checkPath;
    checkPath.moveTo(iconRect.center().x() - 4, iconRect.center().y());
    checkPath.lineTo(iconRect.center().x(), iconRect.center().y() + 4);
    checkPath.lineTo(iconRect.center().x() + 4, iconRect.center().y() - 4);

    QPen checkPen(Qt::green, 2);
    painter->setPen(checkPen);
    painter->drawPath(checkPath);
}

// 失败消息实现
FailureMessage::FailureMessage(const QString &text,
                               MessageDirection direction,
                               QGraphicsItem *parent)
    : TextMessage(text, direction, parent)
{
    m_type = MessageType::FailureMessage;
    m_bubbleColor = QColor(244, 67, 54);
    m_textColor = Qt::white;
}

void FailureMessage::paint(QPainter *painter,
                           const QStyleOptionGraphicsItem *option,
                           QWidget *widget)
{
    TextMessage::paint(painter, option, widget);

    // 绘制失败图标
    painter->setPen(Qt::white);
    painter->setBrush(Qt::white);

    QRectF iconRect(m_boundingRect.right() - 25, m_boundingRect.top() + 5, 20, 20);
    painter->drawEllipse(iconRect.center(), 8, 8);

    QPen crossPen(Qt::red, 2);
    painter->setPen(crossPen);
    painter->drawLine(iconRect.center().x() - 4,
                      iconRect.center().y() - 4,
                      iconRect.center().x() + 4,
                      iconRect.center().y() + 4);
    painter->drawLine(iconRect.center().x() - 4,
                      iconRect.center().y() + 4,
                      iconRect.center().x() + 4,
                      iconRect.center().y() - 4);
}

// 文件消息实现
FileMessage::FileMessage(const QString &fileName,
                         const QString &filePath,
                         qint64 fileSize,
                         MessageDirection direction,
                         QGraphicsItem *parent)
    : BubbleMessage(fileName, MessageType::FileMessage, direction, parent)
    , m_fileName(fileName)
    , m_filePath(filePath)
    , m_fileSize(fileSize)
{
    // 根据文件类型获取图标
    QFileInfo fileInfo(filePath);
    QString suffix = fileInfo.suffix().toLower();

    // 这里可以根据不同的文件类型设置不同的图标
    if (suffix == "pdf") {
        m_fileIcon = QPixmap(":/icons/pdf.png");
    } else if (suffix == "doc" || suffix == "docx") {
        m_fileIcon = QPixmap(":/icons/word.png");
    } else if (suffix == "xls" || suffix == "xlsx") {
        m_fileIcon = QPixmap(":/icons/excel.png");
    } else if (suffix == "ppt" || suffix == "pptx") {
        m_fileIcon = QPixmap(":/icons/powerpoint.png");
    } else if (suffix == "zip" || suffix == "rar" || suffix == "7z") {
        m_fileIcon = QPixmap(":/icons/archive.png");
    } else {
        m_fileIcon = QPixmap(":/icons/file.png");
    }

    // 如果没有找到图标资源，使用默认图标
    if (m_fileIcon.isNull()) {
        m_fileIcon = QPixmap(32, 32);
        m_fileIcon.fill(Qt::transparent);
        QPainter p(&m_fileIcon);
        p.setPen(QPen(Qt::gray, 1));
        p.setBrush(Qt::white);
        p.drawRect(0, 0, 31, 31);
        p.drawText(QRect(0, 0, 32, 32), Qt::AlignCenter, "FILE");
    }

    updateSize();
}

void FileMessage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    BubbleMessage::paint(painter, option, widget);

    // 绘制文件图标
    QRectF iconRect(m_padding, m_padding, 32, 32);
    painter->drawPixmap(iconRect, m_fileIcon, m_fileIcon.rect());

    // 绘制文件名
    painter->setPen(m_textColor);
    painter->setFont(QFont(m_font.family(), m_font.pointSize(), QFont::Bold));
    QRectF nameRect(iconRect.right() + 5,
                    m_padding,
                    m_boundingRect.width() - iconRect.right() - 10,
                    20);
    painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter, m_fileName);

    // 绘制文件大小
    painter->setFont(QFont(m_font.family(), m_font.pointSize() - 1));
    QRectF sizeRect(iconRect.right() + 5, nameRect.bottom(), nameRect.width(), 20);

    // 格式化文件大小
    QString sizeStr;
    if (m_fileSize < 1024) {
        sizeStr = QString("%1 B").arg(m_fileSize);
    } else if (m_fileSize < 1024 * 1024) {
        sizeStr = QString("%1 KB").arg(m_fileSize / 1024.0, 0, 'f', 2);
    } else if (m_fileSize < 1024 * 1024 * 1024) {
        sizeStr = QString("%1 MB").arg(m_fileSize / (1024.0 * 1024.0), 0, 'f', 2);
    } else {
        sizeStr = QString("%1 GB").arg(m_fileSize / (1024.0 * 1024.0 * 1024.0), 0, 'f', 2);
    }

    painter->drawText(sizeRect, Qt::AlignLeft | Qt::AlignVCenter, sizeStr);
}

void FileMessage::updateSize()
{
    // 文件消息的固定大小
    m_boundingRect = QRectF(0, 0, 250, 60);
}

// 撤回消息实现
RecallMessage::RecallMessage(const QString &recalledBy,
                             MessageDirection direction,
                             QGraphicsItem *parent)
    : BubbleMessage(QString("%1 撤回了一条消息").arg(recalledBy),
                    MessageType::RecallMessage,
                    direction,
                    parent)
{
    m_bubbleColor = QColor(200, 200, 200, 150);
    m_textColor = QColor(100, 100, 100);
    updateSize();
}

void RecallMessage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    BubbleMessage::paint(painter, option, widget);

    painter->setFont(m_font);
    painter->setPen(m_textColor);
    painter->drawText(m_boundingRect.adjusted(m_padding, m_padding, -m_padding, -m_padding),
                      Qt::AlignCenter,
                      m_content);
}

// 图片消息实现
ImageMessage::ImageMessage(const QPixmap &image, MessageDirection direction, QGraphicsItem *parent)
    : BubbleMessage("", MessageType::ImageMessage, direction, parent)
    , m_image(image)
{
    updateSize();
}

void ImageMessage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    BubbleMessage::paint(painter, option, widget);

    // 绘制图片
    QRectF imageRect = m_boundingRect.adjusted(m_padding, m_padding, -m_padding, -m_padding);
    painter->drawPixmap(imageRect, m_scaledImage, m_scaledImage.rect());
}

void ImageMessage::updateSize()
{
    // 限制最大尺寸
    int maxWidth = QGuiApplication::primaryScreen()->size().width() * 0.4;
    int maxHeight = 300;

    if (m_image.width() > maxWidth || m_image.height() > maxHeight) {
        m_scaledImage = m_image.scaled(maxWidth,
                                       maxHeight,
                                       Qt::KeepAspectRatio,
                                       Qt::SmoothTransformation);
    } else {
        m_scaledImage = m_image;
    }

    m_boundingRect = QRectF(0,
                            0,
                            m_scaledImage.width() + 2 * m_padding,
                            m_scaledImage.height() + 2 * m_padding);
}

// 文本图片混合消息实现
TextImageMessage::TextImageMessage(const QString &text,
                                   const QPixmap &image,
                                   MessageDirection direction,
                                   QGraphicsItem *parent)
    : BubbleMessage(text, MessageType::TextImageMessage, direction, parent)
    , m_image(image)
{
    m_textDocument.setDefaultFont(m_font);
    m_textDocument.setDocumentMargin(m_padding);
    m_textDocument.setHtml(text);
    updateSize();
}

void TextImageMessage::paint(QPainter *painter,
                             const QStyleOptionGraphicsItem *option,
                             QWidget *widget)
{
    BubbleMessage::paint(painter, option, widget);

    // 保存画家状态
    painter->save();

    // 绘制文本
    painter->setPen(m_textColor);
    painter->translate(m_padding, m_padding);
    QAbstractTextDocumentLayout::PaintContext context;
    context.palette.setColor(QPalette::Text, m_textColor);
    m_textDocument.documentLayout()->draw(painter, context);

    // 恢复画家状态
    painter->restore();

    // 绘制图片
    QSizeF docSize = m_textDocument.size();
    QRectF imageRect(m_padding,
                     m_padding + docSize.height() + 5,
                     m_scaledImage.width(),
                     m_scaledImage.height());
    painter->drawPixmap(imageRect, m_scaledImage, m_scaledImage.rect());
}

void TextImageMessage::updateSize()
{
    // 限制最大宽度
    int maxWidth = QGuiApplication::primaryScreen()->size().width() * 0.4;
    m_textDocument.setTextWidth(maxWidth - 2 * m_padding);

    // 限制图片最大尺寸
    int maxImageWidth = maxWidth - 2 * m_padding;
    int maxImageHeight = 200;

    if (m_image.width() > maxImageWidth || m_image.height() > maxImageHeight) {
        m_scaledImage = m_image.scaled(maxImageWidth,
                                       maxImageHeight,
                                       Qt::KeepAspectRatio,
                                       Qt::SmoothTransformation);
    } else {
        m_scaledImage = m_image;
    }

    QSizeF docSize = m_textDocument.size();
    m_boundingRect = QRectF(0,
                            0,
                            std::max((int) docSize.width() + 2 * m_padding,
                                     m_scaledImage.width() + 2 * m_padding),
                            docSize.height() + m_scaledImage.height() + 2 * m_padding + 5);
}

// 消息场景实现
MessageScene::MessageScene(QObject *parent)
    : QGraphicsScene(parent)
    , m_verticalSpacing(10)
    , m_horizontalMargin(20)
{
    setBackgroundBrush(QColor(245, 245, 245));

    // 创建默认头像
    m_defaultSentAvatar = QPixmap(40, 40);
    m_defaultSentAvatar.fill(Qt::blue);

    m_defaultReceivedAvatar = QPixmap(40, 40);
    m_defaultReceivedAvatar.fill(Qt::green);
}

void MessageScene::addMessage(BubbleMessage *message)
{
    if (message->messageType() != BubbleMessage::TimeMessage
        && message->messageType() != BubbleMessage::RecallMessage) {
        if (message->messageDirection() == BubbleMessage::Sent) {
            message->setAvatar(m_defaultSentAvatar);
        } else {
            message->setAvatar(m_defaultReceivedAvatar);
        }
    }

    // 存储消息时间戳用于排序
    message->setData(0, message->timestamp());

    addItem(message);

    // 直接放置新消息，而不是重新排列所有消息
    placeNewMessage(message);

    // 确保视图滚动到最新消息
    if (!views().isEmpty() && views().first()->verticalScrollBar()) {
        views().first()->verticalScrollBar()->setValue(
            views().first()->verticalScrollBar()->maximum());
    }
}
void MessageScene::placeNewMessage(BubbleMessage *message)
{
    qreal sceneWidth = views().isEmpty() ? 500 : views().first()->width();

    // 获取当前场景中最后一条消息的位置
    qreal currentY = 10; // 默认起始位置

    if (!items().isEmpty()) {
        // 找到当前最底部的消息
        qreal maxY = 0;
        for (QGraphicsItem *item : items()) {
            BubbleMessage *msg = dynamic_cast<BubbleMessage *>(item);
            if (msg) {
                qreal itemBottom = msg->y() + msg->boundingRect().height();
                if (itemBottom > maxY) {
                    maxY = itemBottom;
                }
            }
        }
        currentY = maxY + m_verticalSpacing;
    }

    // 计算消息的X坐标
    qreal x;
    if (message->messageType() == BubbleMessage::TimeMessage
        || message->messageType() == BubbleMessage::RecallMessage) {
        // 时间消息和撤回消息居中显示
        x = (sceneWidth - message->boundingRect().width()) / 2;
    } else if (message->messageDirection() == BubbleMessage::Sent) {
        // 发送的消息靠右显示，但要留出头像的空间
        x = sceneWidth - message->boundingRect().width() - m_horizontalMargin;
    } else {
        // 接收的消息靠左显示，考虑头像空间
        x = m_horizontalMargin + message->avatar().width() + 10;
    }

    // 设置消息位置
    message->setPos(x, currentY);

    // 更新场景高度，确保能看到所有消息
    QRectF currentRect = sceneRect();
    qreal newHeight = currentY + message->boundingRect().height() + m_verticalSpacing;
    if (newHeight > currentRect.height()) {
        setSceneRect(0, 0, sceneWidth, newHeight);
    }
}
void MessageScene::clear()
{
    QGraphicsScene::clear();
}
void MessageScene::setDefaultAvatars(const QPixmap &sentAvatar, const QPixmap &receivedAvatar)
{
    m_defaultSentAvatar = sentAvatar;
    m_defaultReceivedAvatar = receivedAvatar;
}
void MessageScene::arrangeMessages()
{
    // 获取所有消息项
    QList<QGraphicsItem *> items = this->items();

    // 按照时间戳排序（从早到晚）
    std::sort(items.begin(), items.end(), [](QGraphicsItem *a, QGraphicsItem *b) {
        return a->data(0).toDateTime() < b->data(0).toDateTime();
    });

    qreal currentY = 10;
    qreal sceneWidth = views().isEmpty() ? 500 : views().first()->width();

    for (QGraphicsItem *item : items) {
        BubbleMessage *message = dynamic_cast<BubbleMessage *>(item);
        if (!message)
            continue;

        qreal x;
        if (message->messageType() == BubbleMessage::TimeMessage
            || message->messageType() == BubbleMessage::RecallMessage) {
            // 时间消息和撤回消息居中显示
            x = (sceneWidth - message->boundingRect().width()) / 2;
        } else if (message->messageDirection() == BubbleMessage::Sent) {
            // 发送的消息靠右显示，但要留出头像的空间
            x = sceneWidth - message->boundingRect().width() - m_horizontalMargin;
        } else {
            // 接收的消息靠左显示，考虑头像空间
            x = m_horizontalMargin + message->avatar().width() + 10;
        }

        message->setPos(x, currentY);
        currentY += message->boundingRect().height() + m_verticalSpacing;
    }

    // 更新场景矩形
    setSceneRect(0, 0, sceneWidth, currentY);
}

// 消息视图实现
BubbleMessageView::BubbleMessageView(QWidget *parent)
    : QGraphicsView(parent)
    , m_autoScroll(true)
{
    m_scene = new MessageScene(this);
    setScene(m_scene);

    // 设置视图属性
    setRenderHint(QPainter::Antialiasing);
    setRenderHint(QPainter::SmoothPixmapTransform);
    setRenderHint(QPainter::TextAntialiasing);

    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    // 设置视图背景
    setBackgroundBrush(QColor(245, 245, 245));

    // 设置拖拽模式
    setDragMode(QGraphicsView::NoDrag);

    // 优化性能
    setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    setCacheMode(QGraphicsView::CacheBackground);
    setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing
                         | QGraphicsView::DontSavePainterState);
}

void BubbleMessageView::addTimeMessage(const QDateTime &time)
{
    class TimeMessage *message = new class TimeMessage(time);
    m_scene->addMessage(message);

    if (m_autoScroll) {
        verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    }
}

void BubbleMessageView::addTextMessage(const QString &text,
                                       BubbleMessage::MessageDirection direction)
{
    class TextMessage *message = new class TextMessage(text, direction);
    m_scene->addMessage(message);

    // if (m_autoScroll) {
    //     verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    // }
}

void BubbleMessageView::addSuccessMessage(const QString &text,
                                          BubbleMessage::MessageDirection direction)
{
    class SuccessMessage *message = new class SuccessMessage(text, direction);
    m_scene->addMessage(message);

    if (m_autoScroll) {
        verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    }
}

void BubbleMessageView::addFailureMessage(const QString &text,
                                          BubbleMessage::MessageDirection direction)
{
    class FailureMessage *message = new class FailureMessage(text, direction);
    m_scene->addMessage(message);

    if (m_autoScroll) {
        verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    }
}

void BubbleMessageView::addFileMessage(const QString &fileName,
                                       const QString &filePath,
                                       qint64 fileSize,
                                       BubbleMessage::MessageDirection direction)
{
    class FileMessage *message = new class FileMessage(fileName, filePath, fileSize, direction);
    m_scene->addMessage(message);

    if (m_autoScroll) {
        verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    }
}

void BubbleMessageView::addRecallMessage(const QString &recalledBy,
                                         BubbleMessage::MessageDirection direction)
{
    class RecallMessage *message = new class RecallMessage(recalledBy, direction);
    m_scene->addMessage(message);

    if (m_autoScroll) {
        verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    }
}

void BubbleMessageView::addImageMessage(const QPixmap &image,
                                        BubbleMessage::MessageDirection direction)
{
    class ImageMessage *message = new class ImageMessage(image, direction);
    m_scene->addMessage(message);

    if (m_autoScroll) {
        verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    }
}

void BubbleMessageView::addTextImageMessage(const QString &text,
                                            const QPixmap &image,
                                            BubbleMessage::MessageDirection direction)
{
    class TextImageMessage *message = new class TextImageMessage(text, image, direction);
    m_scene->addMessage(message);

    if (m_autoScroll) {
        verticalScrollBar()->setValue(verticalScrollBar()->maximum());
    }
}

void BubbleMessageView::clearMessages()
{
    m_scene->clear();
}

void BubbleMessageView::resizeEvent(QResizeEvent *event)
{
    QGraphicsView::resizeEvent(event);

    // 调整场景大小以适应视图
    QRectF sceneRect = m_scene->sceneRect();
    sceneRect.setWidth(viewport()->width());
    m_scene->setSceneRect(sceneRect);

    // 重新排列消息
    m_scene->arrangeMessages();
}

void BubbleMessageView::wheelEvent(QWheelEvent *event)
{
    // 检测用户是否手动滚动
    int maxValue = verticalScrollBar()->maximum();
    int currentValue = verticalScrollBar()->value();

    QGraphicsView::wheelEvent(event);

    // 如果用户向上滚动，禁用自动滚动
    if (event->angleDelta().y() > 0 && currentValue < maxValue) {
        m_autoScroll = false;
    }

    // 如果用户滚动到底部，启用自动滚动
    if (verticalScrollBar()->value() >= verticalScrollBar()->maximum()) {
        m_autoScroll = true;
    }
}
