#include "chatmessagedelegate.h"
#include "chatmessage.h"
#include "thememanager.h"

#include <QAbstractTextDocumentLayout>
#include <QFontMetrics>
#include <QPainter>
#include <QPainterPath>
#include <QTextDocument>
#include <QTextLayout>

ChatMessageDelegate::ChatMessageDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
    , m_viewportWidth(600)
{
    test.setWindowTitle("test ChatMessageDelegate");
    //test.show();
}

int ChatMessageDelegate::hitTestText(const QPoint &pos, const QString &text) const
{
    QFont fn;
    QFontMetrics fm(fn);
    if (text.isEmpty() || pos.x() < 0 || pos.y() < 0)
        return -1;

    int maxWidth = viewportWidth() - 2 * ChatConstants::BUBBLE_PADDING - ChatConstants::AVATAR_SIZE
                   - 2 * ChatConstants::BUBBLE_SPACING;

    // 使用QTextLayout计算文本布局
    QTextLayout textLayout(text);
    textLayout.setFont(QFont());

    QTextOption option;
    option.setWrapMode(QTextOption::WordWrap);
    option.setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    textLayout.setTextOption(option);

    // 计算文本布局
    textLayout.beginLayout();

    int y = 0;
    int lineIndex = 0;
    QVector<QTextLine> lines;

    while (true) {
        QTextLine line = textLayout.createLine();
        if (!line.isValid())
            break;

        line.setLineWidth(maxWidth);
        int lineHeight = line.height();
        line.setPosition(QPointF(0, y));

        lines.append(line);
        y += lineHeight;
        lineIndex++;
    }

    textLayout.endLayout();

    // 查找点击位置对应的行和字符
    for (int i = 0; i < lines.size(); ++i) {
        QTextLine line = lines[i];
        QRectF lineRect(0, line.y(), line.width(), line.height());

        if (pos.y() >= lineRect.top() && pos.y() <= lineRect.bottom()) {
            // 找到了行，现在找字符位置
            int xPos = qBound(0, pos.x(), int(line.width()));
            return line.xToCursor(xPos);
        }
    }

    // 如果点击在最后一行之后，返回文本末尾
    if (pos.y() > y && !lines.isEmpty())
        return text.length();

    return -1;
}

void ChatMessageDelegate::paint(QPainter *painter,
                                const QStyleOptionViewItem &option,
                                const QModelIndex &index) const
{
    painter->setRenderHint(QPainter::Antialiasing);
    painter->setRenderHint(QPainter::TextAntialiasing);

    const ChatMessage message = index.data().value<ChatMessage>();

    // 系统消息特殊处理
    if (message.type == MessageType::System) {
        drawSystemMessage(painter, option, message);
        return;
    }

    // 计算名字高度
    QFont nameFont = option.font;
    nameFont.setPointSize(std::max(option.font.pointSize() - 2, 8));
    QFontMetrics nameFm(nameFont);
    int nameHeight = message.senderName.isEmpty() ? 0 : nameFm.height();
    int nameSpacing = message.senderName.isEmpty() ? 0 : 2;

    // 计算内容大小（文本或图片）
    QSize contentSize = calculateContentSize(message, option.fontMetrics);

    // 计算头像位置
    QRectF avatarRect;
    if (message.type == MessageType::Left) {
        avatarRect = QRectF(option.rect.left() + ChatConstants::BUBBLE_SPACING,
                            option.rect.top() + nameHeight + nameSpacing,
                            ChatConstants::AVATAR_SIZE,
                            ChatConstants::AVATAR_SIZE);
    } else {
        avatarRect = QRectF(option.rect.right() - ChatConstants::AVATAR_SIZE
                                - ChatConstants::BUBBLE_SPACING,
                            option.rect.top() + nameHeight + nameSpacing,
                            ChatConstants::AVATAR_SIZE,
                            ChatConstants::AVATAR_SIZE);
    }

    // 计算气泡位置
    QRectF bubbleRect;
    if (message.type == MessageType::Left) {
        bubbleRect = QRectF(avatarRect.right() + ChatConstants::BUBBLE_SPACING,
                            option.rect.top() + nameHeight + nameSpacing,
                            contentSize.width() + 2 * ChatConstants::BUBBLE_PADDING,
                            contentSize.height() + 2 * ChatConstants::BUBBLE_PADDING);
    } else {
        bubbleRect = QRectF(option.rect.right() - contentSize.width()
                                - 2 * ChatConstants::BUBBLE_PADDING - ChatConstants::AVATAR_SIZE
                                - 2 * ChatConstants::BUBBLE_SPACING,
                            option.rect.top() + nameHeight + nameSpacing,
                            contentSize.width() + 2 * ChatConstants::BUBBLE_PADDING,
                            contentSize.height() + 2 * ChatConstants::BUBBLE_PADDING);
    }

    // 绘制名字
    if (!message.senderName.isEmpty()) {
        painter->save();
        painter->setFont(nameFont);
        painter->setPen(QColor(120, 120, 120));
        int nameX, nameWidth;
        QRect nameRect;
        if (message.type == MessageType::Left) {
            // 左侧消息，名字左对齐，紧贴头像右侧
            nameX = avatarRect.right() + ChatConstants::BUBBLE_SPACING;
            nameWidth = bubbleRect.width();
            nameRect = QRect(nameX, option.rect.top(), nameWidth, nameHeight);
            painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignVCenter, message.senderName);
        } else {
            // 右侧消息，名字右对齐，紧贴头像左侧
            nameWidth = nameFm.horizontalAdvance(message.senderName);
            // 名字宽度不超过气泡宽度
            nameWidth = std::min(nameWidth, static_cast<int>(bubbleRect.width()));
            nameX = bubbleRect.right() - nameWidth;
            nameRect = QRect(nameX, option.rect.top(), nameWidth, nameHeight);
            painter->drawText(nameRect, Qt::AlignRight | Qt::AlignVCenter, message.senderName);
        }
        painter->restore();
    }

    // 绘制气泡
    drawBubble(painter, bubbleRect, message.type == MessageType::Left);

    // 绘制头像
    drawAvatar(painter, avatarRect, message.avatar);

    // 绘制内容（文本、图片或混合内容）
    QRectF contentRect = bubbleRect.adjusted(ChatConstants::BUBBLE_PADDING,
                                             ChatConstants::BUBBLE_PADDING,
                                             -ChatConstants::BUBBLE_PADDING,
                                             -ChatConstants::BUBBLE_PADDING);
    
    // 检查是否是当前选中的消息
    bool isCurrentMessage = (index == m_currentMessageIndex);
    
    if (message.hasImage() && message.hasText()) {
        // 混合内容：图片在上，文字在下
        QSize imageSize = calculateImageSize(message.imagePath, contentRect.width(), contentRect.height() * 0.7);
        QRectF imageRect(contentRect.left(), contentRect.top(), imageSize.width(), imageSize.height());
        QRectF textRect(contentRect.left(), imageRect.bottom() + 4, contentRect.width(), contentRect.height() - imageSize.height() - 4);
        
        drawImage(painter, imageRect, message.imagePath);
        painter->setPen(ThemeManager::instance().color("colorText"));
        drawTextWithSelection(painter, textRect, message.text, option.fontMetrics, isCurrentMessage);
    } else if (message.hasImage()) {
        // 纯图片消息
        drawImage(painter, contentRect, message.imagePath);
    } else {
        // 纯文本消息
        painter->setPen(ThemeManager::instance().color("colorText"));
        drawTextWithSelection(painter, contentRect, message.text, option.fontMetrics, isCurrentMessage);
    }
}

QSize ChatMessageDelegate::sizeHint(const QStyleOptionViewItem &option,
                                    const QModelIndex &index) const
{
    const ChatMessage message = index.data().value<ChatMessage>();
    QSize contentSize = calculateContentSize(message, option.fontMetrics);

    // 系统消息特殊处理
    if (message.type == MessageType::System) {
        int width = qMin(contentSize.width() + 2 * ChatConstants::BUBBLE_PADDING, viewportWidth() / 2);
        int height = contentSize.height() + 2 * ChatConstants::BUBBLE_PADDING
                     + ChatConstants::TIMESTAMP_HEIGHT + 2 * ChatConstants::BUBBLE_SPACING;
        return QSize(width, height);
    }

    // 计算名字高度
    QFont nameFont = option.font;
    nameFont.setPointSize(std::max(option.font.pointSize() - 2, 8));
    QFontMetrics nameFm(nameFont);
    int nameHeight = message.senderName.isEmpty() ? 0 : nameFm.height();
    int nameSpacing = message.senderName.isEmpty() ? 0 : 2;

    int width = contentSize.width() + 2 * ChatConstants::BUBBLE_PADDING + ChatConstants::AVATAR_SIZE
                + 2 * ChatConstants::BUBBLE_SPACING;
    int height = qMax(contentSize.height() + 2 * ChatConstants::BUBBLE_PADDING,
                      ChatConstants::AVATAR_SIZE)
                 + ChatConstants::TIMESTAMP_HEIGHT
                 + nameHeight + nameSpacing;

    return QSize(qMin(width, viewportWidth()), height + ChatConstants::BUBBLE_SPACING);
}

void ChatMessageDelegate::setViewportWidth(int width)
{
    m_viewportWidth = width - 2 * ChatConstants::BUBBLE_PADDING - ChatConstants::AVATAR_SIZE
                      - 2 * ChatConstants::BUBBLE_SPACING;
}

void ChatMessageDelegate::drawBubble(QPainter *painter, const QRectF &rect, bool isLeft) const
{
    QPainterPath path;
    path.addRoundedRect(rect, ChatConstants::BUBBLE_RADIUS, ChatConstants::BUBBLE_RADIUS);

    // 添加小三角
    const int triangleSize = 6;
    if (isLeft) {
        path.moveTo(rect.left(), rect.top() + ChatConstants::AVATAR_SIZE / 2 - triangleSize);
        path.lineTo(rect.left() - triangleSize, rect.top() + ChatConstants::AVATAR_SIZE / 2);
        path.lineTo(rect.left(), rect.top() + ChatConstants::AVATAR_SIZE / 2 + triangleSize);
    } else {
        path.moveTo(rect.right(), rect.top() + ChatConstants::AVATAR_SIZE / 2 - triangleSize);
        path.lineTo(rect.right() + triangleSize, rect.top() + ChatConstants::AVATAR_SIZE / 2);
        path.lineTo(rect.right(), rect.top() + ChatConstants::AVATAR_SIZE / 2 + triangleSize);
    }

    // 设置气泡颜色
    if (isLeft) {
        painter->fillPath(path, ThemeManager::instance().color("colorFillQuaternary"));
    } else {
        painter->fillPath(path, ThemeManager::instance().color("colorPrimaryBg"));
    }
}

void ChatMessageDelegate::drawAvatar(QPainter *painter,
                                     const QRectF &rect,
                                     const QString &avatarPath) const
{
    // 检查缓存中是否已有头像
    if (!m_avatarCache.contains(avatarPath)) {
        QPixmap avatar(avatarPath);
        if (!avatar.isNull()) {
            avatar = avatar.scaled(ChatConstants::AVATAR_SIZE,
                                   ChatConstants::AVATAR_SIZE,
                                   Qt::KeepAspectRatio,
                                   Qt::SmoothTransformation);
            const_cast<ChatMessageDelegate *>(this)->m_avatarCache.insert(avatarPath, avatar);
        }
    }

    // 创建圆形裁剪区域
    QPainterPath path;
    path.addEllipse(rect);
    painter->setClipPath(path);

    if (m_avatarCache.contains(avatarPath)) {
        // 绘制缓存的头像
        painter->drawPixmap(rect.toRect(), m_avatarCache[avatarPath]);
    } else {
        // 绘制默认头像
        painter->setPen(Qt::NoPen);
        painter->setBrush(ThemeManager::instance().color("colorFill"));
        painter->drawEllipse(rect);
    }

    painter->setClipping(false);
}

void ChatMessageDelegate::drawSystemMessage(QPainter *painter,
                                            const QStyleOptionViewItem &option,
                                            const ChatMessage &message) const
{
    // 为系统消息单独计算文本大小
    int maxWidth = viewportWidth() / (2.0 / 3.0);

    // 使用QTextDocument计算系统消息的实际大小
    QFont font = painter->font();
    int size = font.pointSize();

    font.setPointSize(std::max(size - 2, 8));

    QTextDocument doc;
    doc.setDefaultFont(font);
    doc.setDocumentMargin(0);
    doc.setTextWidth(maxWidth - 2 * ChatConstants::BUBBLE_PADDING);
    doc.setHtml(message.text.toHtmlEscaped().replace("\n", "<br>"));

    QSize textSize(doc.idealWidth(), doc.size().height());

    // 系统消息居中显示
    int bubbleWidth = qMin(textSize.width() + 2 * ChatConstants::BUBBLE_PADDING, maxWidth);

    // 计算气泡位置（居中）
    QRectF bubbleRect(option.rect.left() + (option.rect.width() - bubbleWidth) / 2,
                      option.rect.top() + ChatConstants::BUBBLE_SPACING,
                      bubbleWidth,
                      textSize.height() + 2 * ChatConstants::BUBBLE_PADDING);

    // 绘制系统消息气泡（使用特殊样式）
    QPainterPath path;
    path.addRoundedRect(bubbleRect, ChatConstants::BUBBLE_RADIUS, ChatConstants::BUBBLE_RADIUS);

    // 使用半透明灰色背景
    painter->fillPath(path, QColor(200, 200, 200, 60));

    // 绘制文本
    QRectF textRect = bubbleRect.adjusted(ChatConstants::BUBBLE_PADDING,
                                          ChatConstants::BUBBLE_PADDING,
                                          -ChatConstants::BUBBLE_PADDING,
                                          -ChatConstants::BUBBLE_PADDING);

    // 使用特殊颜色
    painter->setPen(QColor(255, 0, 0));

    QTextCharFormat defaultFormat;
    defaultFormat.setForeground(ThemeManager::instance().color("colorText"));

    QTextCursor cursor(&doc);
    cursor.select(QTextCursor::Document);
    cursor.mergeCharFormat(defaultFormat);

    painter->save();
    painter->translate(textRect.topLeft());
    doc.drawContents(painter);
    painter->restore();

    // // // 绘制时间戳
    // QRectF timestampRect(bubbleRect.left(),
    //                      bubbleRect.bottom(),
    //                      bubbleRect.width(),
    //                      ChatConstants::TIMESTAMP_HEIGHT);

    // painter->setPen(ThemeManager::instance().color("colorTextSecondary"));
    // painter->setFont(QFont(option.font.family(), option.font.pointSize() - 2));
    // painter->drawText(timestampRect, Qt::AlignCenter, message.timestamp.toString("HH:mm"));
}

// 添加绘制带选择的文本方法
void ChatMessageDelegate::drawTextWithSelection(QPainter *painter,
                                                const QRectF &rect,
                                                const QString &text,
                                                const QFontMetrics &fm,
                                                bool isCurrentMessage) const
{
    // 如果不是当前消息或没有选择，直接绘制文本

    // 使用QTextDocument绘制多行文本
    QTextDocument doc;
    doc.setDefaultFont(painter->font());
    doc.setDocumentMargin(0);
    doc.setTextWidth(rect.width());
    doc.setHtml(text.toHtmlEscaped().replace("\n", "<br>"));

    // 设置默认文本格式（应用主题颜色）
    QTextCharFormat defaultFormat;
    defaultFormat.setForeground(ThemeManager::instance().color("colorText"));

    if (!isCurrentMessage || m_selectionStart < 0 || m_selectionEnd < 0
        || m_selectionStart == m_selectionEnd) {
        // 将普通文本转换为HTML，保留换行符
        QString htmlText = text.toHtmlEscaped().replace("\n", "<br>");
        doc.setHtml(htmlText);

        // 应用默认格式到整个文档
        QTextCursor cursor(&doc);
        cursor.select(QTextCursor::Document);
        cursor.mergeCharFormat(defaultFormat);

        painter->save();
        painter->translate(rect.topLeft());
        painter->setPen(ThemeManager::instance().color("colorText"));
        doc.drawContents(painter);
        painter->restore();
        return;
    }

    // 确保选择范围有效
    int start = qMin(m_selectionStart, m_selectionEnd);
    int end = qMax(m_selectionStart, m_selectionEnd);

    if (start >= text.length() || end <= 0) {
        QString htmlText = text.toHtmlEscaped().replace("\n", "<br>");
        doc.setHtml(htmlText);
        // 应用默认格式到整个文档
        QTextCursor cursor(&doc);
        cursor.select(QTextCursor::Document);
        cursor.mergeCharFormat(defaultFormat);

        painter->save();
        painter->translate(rect.topLeft());
        painter->setPen(ThemeManager::instance().color("colorText"));
        doc.drawContents(painter);
        painter->restore();
        return;
    }

    // 限制选择范围在文本长度内
    start = qMax(0, start);
    end = qMin(text.length(), end);

    // 将普通文本转换为HTML，保留换行符
    QString htmlText = text.toHtmlEscaped().replace("\n", "<br>");
    doc.setHtml(htmlText);

    // 首先应用默认格式到整个文档
    QTextCursor cursor(&doc);
    cursor.select(QTextCursor::Document);
    cursor.mergeCharFormat(defaultFormat);

    // 设置选择格式
    cursor.setPosition(start);
    cursor.setPosition(end, QTextCursor::KeepAnchor);

    QTextCharFormat selectionFormat;
    selectionFormat.setBackground(QColor(0, 120, 215, 128)); // 半透明蓝色背景
    selectionFormat.setForeground(Qt::white);                // 白色文本
    cursor.mergeCharFormat(selectionFormat);

    // 绘制文本
    painter->save();
    painter->translate(rect.topLeft());
    doc.drawContents(painter);
    painter->restore();
}

QSize ChatMessageDelegate::calculateTextSize(const QFontMetrics &fm, const QString &text) const
{
    int maxWidth = viewportWidth() - 2 * ChatConstants::BUBBLE_PADDING - ChatConstants::AVATAR_SIZE
                   - 2 * ChatConstants::BUBBLE_SPACING;
    QRect textRect = fm.boundingRect(0,
                                     0,
                                     maxWidth,
                                     INT_MAX,
                                     Qt::TextWordWrap | Qt::AlignLeft | Qt::AlignVCenter,
                                     text);
    return textRect.size();
}

int ChatMessageDelegate::getPositionFromPoint(const QPoint &pos,
                                              const QString &text,
                                              const QFontMetrics &fm)
{
    if (text.isEmpty() || pos.x() < 0 || pos.y() < 0)
        return -1;

    int maxWidth = viewportWidth() - 2 * ChatConstants::BUBBLE_PADDING;

    // 使用QTextDocument处理多行文本
    QTextDocument doc;
    doc.setDefaultFont(QFont());
    doc.setDocumentMargin(0);
    doc.setTextWidth(maxWidth - 52); // AVATAR_SIZE + BUBBLE_PADDING
    doc.setHtml(text.toHtmlEscaped().replace("\n", "<br>"));

    test.setDocument(&doc);
    // 获取点击位置对应的文本位置
    QAbstractTextDocumentLayout *layout = doc.documentLayout();
    int position = layout->hitTest(pos, Qt::FuzzyHit);
    return position;
}

void ChatMessageDelegate::drawImage(QPainter *painter, const QRectF &rect, const QString &imagePath) const
{
    if (imagePath.isEmpty())
        return;

    // 检查缓存中是否已有图片
    if (!m_imageCache.contains(imagePath)) {
        QPixmap image(imagePath);
        if (!image.isNull()) {
            // 计算合适的缩放尺寸
            QSize rectSize = rect.size().toSize();
            QSize targetSize = image.size().scaled(rectSize.width(), rectSize.height(), Qt::KeepAspectRatio);
            image = image.scaled(targetSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
            const_cast<ChatMessageDelegate *>(this)->m_imageCache.insert(imagePath, image);
        }
    }

    if (m_imageCache.contains(imagePath)) {
        const QPixmap &image = m_imageCache[imagePath];
        // 居中绘制图片
        QRectF imageRect = rect;
        if (image.width() < rect.width()) {
            imageRect.setX(rect.x() + (rect.width() - image.width()) / 2);
            imageRect.setWidth(image.width());
        }
        if (image.height() < rect.height()) {
            imageRect.setY(rect.y() + (rect.height() - image.height()) / 2);
            imageRect.setHeight(image.height());
        }
        
        painter->setRenderHint(QPainter::SmoothPixmapTransform);
        painter->drawPixmap(imageRect.toRect(), image);
        
        // 绘制图片边框
        painter->setPen(QPen(QColor(200, 200, 200), 1));
        painter->setBrush(Qt::NoBrush);
        painter->drawRoundedRect(imageRect, 4, 4);
    } else {
        // 绘制占位符
        painter->setPen(Qt::NoPen);
        painter->setBrush(QColor(240, 240, 240));
        painter->drawRoundedRect(rect, 4, 4);
        
        painter->setPen(QColor(150, 150, 150));
        painter->drawText(rect, Qt::AlignCenter, "图片加载失败");
    }
}

QSize ChatMessageDelegate::calculateImageSize(const QString &imagePath, int maxWidth, int maxHeight) const
{
    if (imagePath.isEmpty())
        return QSize(100, 100); // 默认尺寸

    QPixmap image(imagePath);
    if (image.isNull())
        return QSize(100, 100);

    QSize imageSize = image.size();
    
    // 限制最大尺寸
    if (imageSize.width() > maxWidth || imageSize.height() > maxHeight) {
        imageSize = imageSize.scaled(maxWidth, maxHeight, Qt::KeepAspectRatio);
    }
    
    // 限制最小尺寸
    if (imageSize.width() < 50) imageSize.setWidth(50);
    if (imageSize.height() < 50) imageSize.setHeight(50);
    
    return imageSize;
}

QSize ChatMessageDelegate::calculateContentSize(const ChatMessage &message, const QFontMetrics &fm) const
{
    if (message.hasImage() && message.hasText()) {
        // 混合内容：图片 + 文本
        int maxWidth = viewportWidth() - 2 * ChatConstants::BUBBLE_PADDING - ChatConstants::AVATAR_SIZE - 2 * ChatConstants::BUBBLE_SPACING;
        
        QSize imageSize = calculateImageSize(message.imagePath, maxWidth, 200);
        QSize textSize = calculateTextSize(fm, message.text);
        
        int width = qMax(imageSize.width(), textSize.width());
        int height = imageSize.height() + textSize.height() + 4; // 4px间距
        
        return QSize(width, height);
    } else if (message.hasImage()) {
        // 纯图片消息
        int maxWidth = viewportWidth() - 2 * ChatConstants::BUBBLE_PADDING - ChatConstants::AVATAR_SIZE - 2 * ChatConstants::BUBBLE_SPACING;
        return calculateImageSize(message.imagePath, maxWidth, 300);
    } else {
        // 纯文本消息
        return calculateTextSize(fm, message.text);
    }
}
