// Copyright (C) 2025-2026 Petr Mironychev
// SPDX-License-Identifier: GPL-3.0-or-later
// Additional attribution terms under GPLv3 §7(b) apply — see LICENSE

#include "RefactorWidget.hpp"
#include "DiffStatistics.hpp"

#include <texteditor/textdocument.h>
#include <texteditor/syntaxhighlighter.h>

#include <QCloseEvent>
#include <QEnterEvent>
#include <QEvent>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QLabel>
#include <QPainter>
#include <QRegion>
#include <QScreen>
#include <QScrollBar>
#include <QSharedPointer>
#include <QSplitter>
#include <QTextBlock>
#include <QVBoxLayout>

#include <coreplugin/icore.h>
#include <utils/differ.h>
#include <utils/theme/theme.h>

#include "settings/QuickRefactorSettings.hpp"

namespace QodeAssist {

CustomSplitterHandle::CustomSplitterHandle(Qt::Orientation orientation, QSplitter *parent)
    : QSplitterHandle(orientation, parent)
{
    if (orientation == Qt::Horizontal) {
        setCursor(Qt::SplitHCursor);
    } else {
        setCursor(Qt::SplitVCursor);
    }
    
    setMouseTracking(true);
}

void CustomSplitterHandle::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    
    QColor bgColor = Utils::creatorColor(Utils::Theme::BackgroundColorHover);
    bgColor.setAlpha(m_hovered ? 150 : 50);
    painter.fillRect(rect(), bgColor);
    
    QColor lineColor = Utils::creatorColor(Utils::Theme::SplitterColor);
    lineColor.setAlpha(m_hovered ? 255 : 180);
    
    const int lineWidth = m_hovered ? 3 : 2;
    const int margin = 10;
    painter.setPen(QPen(lineColor, lineWidth));
    
    if (orientation() == Qt::Horizontal) {
        int x = width() / 2;
        painter.drawLine(x, margin, x, height() - margin);
        
        painter.setBrush(lineColor);
        int centerY = height() / 2;
        const int dotSize = m_hovered ? 3 : 2;
        const int dotSpacing = 8;
        for (int i = -2; i <= 2; ++i) {
            painter.drawEllipse(QPoint(x, centerY + i * dotSpacing), dotSize, dotSize);
        }
    } else {
        int y = height() / 2;
        painter.drawLine(margin, y, width() - margin, y);
    }
}

void CustomSplitterHandle::enterEvent(QEnterEvent *event)
{
    m_hovered = true;
    update();
    QSplitterHandle::enterEvent(event);
}

void CustomSplitterHandle::leaveEvent(QEvent *event)
{
    m_hovered = false;
    update();
    QSplitterHandle::leaveEvent(event);
}

CustomSplitter::CustomSplitter(Qt::Orientation orientation, QWidget *parent)
    : QSplitter(orientation, parent)
{
}

QSplitterHandle *CustomSplitter::createHandle()
{
    return new CustomSplitterHandle(orientation(), this);
}

RefactorWidget::RefactorWidget(TextEditor::TextEditorWidget *sourceEditor, QWidget *parent)
    : QWidget(parent)
    , m_sourceEditor(sourceEditor)
    , m_leftEditor(nullptr)
    , m_rightEditor(nullptr)
    , m_leftContainer(nullptr)
    , m_splitter(nullptr)
    , m_statsLabel(nullptr)
    , m_applyButton(nullptr)
    , m_declineButton(nullptr)
    , m_editorWidth(800)
    , m_syncingScroll(false)
    , m_isClosing(false)
    , m_linesAdded(0)
    , m_linesRemoved(0)
{
    setupUi();
    applyEditorSettings();
    setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
    setAttribute(Qt::WA_DeleteOnClose);
    setFocusPolicy(Qt::StrongFocus);
}

RefactorWidget::~RefactorWidget()
{
}

void RefactorWidget::setupUi()
{
    auto *mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(6, 6, 6, 6);
    mainLayout->setSpacing(4);

    m_statsLabel = new QLabel(this);
    m_statsLabel->setAlignment(Qt::AlignLeft);
    mainLayout->addWidget(m_statsLabel, 0);

    m_leftDocument = QSharedPointer<TextEditor::TextDocument>::create();
    m_rightDocument = QSharedPointer<TextEditor::TextDocument>::create();
    
    Qt::Orientation initialOrientation = Settings::quickRefactorSettings().widgetOrientation.value() == 1 
        ? Qt::Vertical : Qt::Horizontal;
    
    m_splitter = new CustomSplitter(initialOrientation, this);
    m_splitter->setChildrenCollapsible(false);
    m_splitter->setHandleWidth(12);
    m_splitter->setStyleSheet("QSplitter::handle { background-color: transparent; }");
    
    m_leftEditor = new TextEditor::TextEditorWidget();
    m_leftEditor->setTextDocument(m_leftDocument);
    m_leftEditor->setReadOnly(true);
    m_leftEditor->setFrameStyle(QFrame::StyledPanel);
    m_leftEditor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_leftEditor->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_leftEditor->setMinimumWidth(150);
    m_leftEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_leftEditor->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
    
    m_rightEditor = new TextEditor::TextEditorWidget();
    m_rightEditor->setTextDocument(m_rightDocument);
    m_rightEditor->setReadOnly(false);
    m_rightEditor->setFrameStyle(QFrame::StyledPanel);
    m_rightEditor->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_rightEditor->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_rightEditor->setMinimumWidth(150);
    m_rightEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
    m_leftContainer = new QWidget();
    m_leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    auto *leftLayout = new QVBoxLayout(m_leftContainer);
    leftLayout->setSpacing(2);
    leftLayout->setContentsMargins(0, 0, 0, 0);
    
    auto *originalLabel = new QLabel(tr("◄ Original"), m_leftContainer);
    leftLayout->addWidget(originalLabel, 0);
    leftLayout->addWidget(m_leftEditor, 1);
    
    auto *rightContainer = new QWidget();
    rightContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    auto *rightLayout = new QVBoxLayout(rightContainer);
    rightLayout->setSpacing(2);
    rightLayout->setContentsMargins(0, 0, 0, 0);
    
    auto *refactoredLabel = new QLabel(tr("Refactored ►"), rightContainer);
    rightLayout->addWidget(refactoredLabel, 0);
    rightLayout->addWidget(m_rightEditor, 1);
    
    m_splitter->addWidget(m_leftContainer);
    m_splitter->addWidget(rightContainer);
    
    m_splitter->setStretchFactor(0, 1);
    m_splitter->setStretchFactor(1, 1);
    
    mainLayout->addWidget(m_splitter, 1);
    
    connect(m_leftEditor->verticalScrollBar(), &QScrollBar::valueChanged,
            this, &RefactorWidget::syncLeftScroll);
    connect(m_rightEditor->verticalScrollBar(), &QScrollBar::valueChanged,
            this, &RefactorWidget::syncRightScroll);
    connect(m_leftEditor->horizontalScrollBar(), &QScrollBar::valueChanged,
            this, &RefactorWidget::syncLeftHorizontalScroll);
    connect(m_rightEditor->horizontalScrollBar(), &QScrollBar::valueChanged,
            this, &RefactorWidget::syncRightHorizontalScroll);
    
    connect(m_rightDocument->document(), &QTextDocument::contentsChanged,
            this, &RefactorWidget::onRightEditorTextChanged);

    auto *buttonLayout = new QHBoxLayout();
    buttonLayout->setContentsMargins(0, 2, 0, 0);
    buttonLayout->setSpacing(6);

#ifdef Q_OS_MACOS
    m_applyButton = new QPushButton(tr("✓ Apply (⌘+Enter)"), this);
#else
    m_applyButton = new QPushButton(tr("✓ Apply (Ctrl+Enter)"), this);
#endif
    m_applyButton->setFocusPolicy(Qt::NoFocus);
    m_applyButton->setCursor(Qt::PointingHandCursor);
    m_applyButton->setMaximumHeight(24);
    
    m_declineButton = new QPushButton(tr("✗ Decline (Esc)"), this);
    m_declineButton->setFocusPolicy(Qt::NoFocus);
    m_declineButton->setCursor(Qt::PointingHandCursor);
    m_declineButton->setMaximumHeight(24);
    
    buttonLayout->addStretch();
    buttonLayout->addWidget(m_applyButton);
    buttonLayout->addWidget(m_declineButton);
    
    mainLayout->addLayout(buttonLayout, 0);
    
    connect(m_applyButton, &QPushButton::clicked, this, &RefactorWidget::applyRefactoring);
    connect(m_declineButton, &QPushButton::clicked, this, &RefactorWidget::declineRefactoring);
}

void RefactorWidget::setDiffContent(const QString &originalText, const QString &refactoredText)
{
    setDiffContent(originalText, refactoredText, QString(), QString());
}

void RefactorWidget::setDiffContent(const QString &originalText, const QString &refactoredText,
                                     const QString &contextBefore, const QString &contextAfter)
{
    m_originalText = originalText;
    m_refactoredText = refactoredText;
    m_contextBefore = contextBefore;
    m_contextAfter = contextAfter;
    
    m_leftContainer->setVisible(true);
    
    QString leftFullText;
    QString rightFullText;
    
    if (!contextBefore.isEmpty()) {
        leftFullText = contextBefore + "\n";
        rightFullText = contextBefore + "\n";
    }
    
    leftFullText += originalText;
    rightFullText += refactoredText;
    
    if (!contextAfter.isEmpty()) {
        leftFullText += "\n" + contextAfter;
        rightFullText += "\n" + contextAfter;
    }
    
    m_leftDocument->setPlainText(leftFullText);
    m_rightDocument->setPlainText(rightFullText);
    
    applySyntaxHighlighting();
    
    if (!contextBefore.isEmpty() || !contextAfter.isEmpty()) {
        dimContextLines(contextBefore, contextAfter);
    }
    
    Utils::Differ differ;
    m_cachedDiffList = differ.diff(m_originalText, m_refactoredText);
    
    highlightDifferences();
    addLineMarkers();
    
    calculateStats();
    updateStatsLabel();
    
    updateSizeToContent();
}

void RefactorWidget::highlightDifferences()
{
    if (m_cachedDiffList.isEmpty()) {
        return;
    }
    
    QList<Utils::Diff> leftDiffs;
    QList<Utils::Diff> rightDiffs;
    Utils::Differ::splitDiffList(m_cachedDiffList, &leftDiffs, &rightDiffs);
    
    int contextBeforeOffset = m_contextBefore.isEmpty() ? 0 : (m_contextBefore.length() + 1);
    
    QColor normalTextColor = Utils::creatorColor(Utils::Theme::TextColorNormal);
    
    QTextCursor leftCursor(m_leftDocument->document());
    QTextCharFormat removedFormat;
    QColor removedBg = Utils::creatorColor(Utils::Theme::TextColorError);
    removedBg.setAlpha(30);
    removedFormat.setBackground(removedBg);
    removedFormat.setForeground(normalTextColor);
    
    int leftPos = 0;
    for (const auto &diff : leftDiffs) {
        if (diff.command == Utils::Diff::Delete) {
            leftCursor.setPosition(contextBeforeOffset + leftPos);
            leftCursor.setPosition(contextBeforeOffset + leftPos + diff.text.length(), QTextCursor::KeepAnchor);
            leftCursor.setCharFormat(removedFormat);
        }
        if (diff.command != Utils::Diff::Insert) {
            leftPos += diff.text.length();
        }
    }
    
    QTextCursor rightCursor(m_rightDocument->document());
    QTextCharFormat addedFormat;
    QColor addedBg = Utils::creatorColor(Utils::Theme::IconsRunColor);
    addedBg.setAlpha(60);
    addedFormat.setBackground(addedBg);
    addedFormat.setForeground(normalTextColor);
    
    int rightPos = 0;
    for (const auto &diff : rightDiffs) {
        if (diff.command == Utils::Diff::Insert) {
            rightCursor.setPosition(contextBeforeOffset + rightPos);
            rightCursor.setPosition(contextBeforeOffset + rightPos + diff.text.length(), QTextCursor::KeepAnchor);
            rightCursor.setCharFormat(addedFormat);
        }
        if (diff.command != Utils::Diff::Delete) {
            rightPos += diff.text.length();
        }
    }
}

void RefactorWidget::dimContextLines(const QString &contextBefore, const QString &contextAfter)
{
    QTextCharFormat dimFormat;
    dimFormat.setForeground(Utils::creatorColor(Utils::Theme::TextColorDisabled));
    
    auto dimLines = [&](QTextDocument *doc, int lineCount, bool fromStart) {
        QTextCursor cursor(doc);
        if (!fromStart) {
            cursor.movePosition(QTextCursor::End);
        }
        
        for (int i = 0; i < lineCount; ++i) {
            cursor.movePosition(QTextCursor::StartOfBlock);
            cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
            cursor.setCharFormat(dimFormat);
            
            if (fromStart) {
                if (!cursor.block().isValid() || !cursor.movePosition(QTextCursor::NextBlock)) {
                    break;
                }
            } else {
                if (!cursor.movePosition(QTextCursor::PreviousBlock)) {
                    break;
                }
            }
        }
    };
    
    if (!contextBefore.isEmpty()) {
        int lines = contextBefore.count('\n') + (contextBefore.endsWith('\n') ? 0 : 1);
        dimLines(m_leftDocument->document(), lines, true);
        dimLines(m_rightDocument->document(), lines, true);
    }
    
    if (!contextAfter.isEmpty()) {
        int lines = contextAfter.count('\n') + (contextAfter.endsWith('\n') ? 0 : 1);
        dimLines(m_leftDocument->document(), lines, false);
        dimLines(m_rightDocument->document(), lines, false);
    }
}

QString RefactorWidget::getRefactoredText() const
{
    return m_applyText;
}

void RefactorWidget::setRange(const Utils::Text::Range &range)
{
    m_range = range;
}

void RefactorWidget::setEditorWidth(int width)
{
    m_editorWidth = width;
    updateSizeToContent();
}

void RefactorWidget::setApplyCallback(std::function<void(const QString &)> callback)
{
    m_applyCallback = callback;
}

void RefactorWidget::setDeclineCallback(std::function<void()> callback)
{
    m_declineCallback = callback;
}

void RefactorWidget::applyRefactoring()
{
    if (m_isClosing) return;
    m_isClosing = true;
    
    if (m_applyCallback) {
        m_applyCallback(m_applyText);
    }
    emit applied();
    close();
}

void RefactorWidget::declineRefactoring()
{
    if (m_isClosing) return;
    m_isClosing = true;
    
    if (m_declineCallback) {
        m_declineCallback();
    }
    emit declined();
    close();
}

void RefactorWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    
    const QColor bgColor = Utils::creatorColor(Utils::Theme::BackgroundColorNormal);
    const QColor borderColor = Utils::creatorColor(Utils::Theme::SplitterColor);
    
    painter.fillRect(rect(), bgColor);
    painter.setPen(QPen(borderColor, 2));
    painter.drawRoundedRect(rect().adjusted(2, 2, -2, -2), 6, 6);
}

bool RefactorWidget::event(QEvent *event)
{
    if (event->type() == QEvent::ShortcutOverride) {
        auto *keyEvent = static_cast<QKeyEvent *>(event);
        
        if (((keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) && 
             keyEvent->modifiers() == Qt::ControlModifier) ||
            keyEvent->key() == Qt::Key_Escape) {
            event->accept();
            return true;
        }
    }
    
    if (event->type() == QEvent::KeyPress) {
        auto *keyEvent = static_cast<QKeyEvent *>(event);
        
        if ((keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) && 
            keyEvent->modifiers() == Qt::ControlModifier) {
            applyRefactoring();
            return true;
        }
        
        if (keyEvent->key() == Qt::Key_Escape) {
            declineRefactoring();
            return true;
        }
    }
    
    return QWidget::event(event);
}

void RefactorWidget::syncLeftScroll(int value)
{
    if (m_syncingScroll) return;
    m_syncingScroll = true;
    m_rightEditor->verticalScrollBar()->setValue(value);
    m_syncingScroll = false;
}

void RefactorWidget::syncRightScroll(int value)
{
    if (m_syncingScroll) return;
    m_syncingScroll = true;
    m_leftEditor->verticalScrollBar()->setValue(value);
    m_syncingScroll = false;
}

void RefactorWidget::syncLeftHorizontalScroll(int value)
{
    if (m_syncingScroll) return;
    m_syncingScroll = true;
    m_rightEditor->horizontalScrollBar()->setValue(value);
    m_syncingScroll = false;
}

void RefactorWidget::syncRightHorizontalScroll(int value)
{
    if (m_syncingScroll) return;
    m_syncingScroll = true;
    m_leftEditor->horizontalScrollBar()->setValue(value);
    m_syncingScroll = false;
}

void RefactorWidget::onRightEditorTextChanged()
{
    QString fullText = m_rightDocument->plainText();
    int startPos = m_contextBefore.isEmpty() ? 0 : m_contextBefore.length() + 1;
    int endPos = m_contextAfter.isEmpty() ? fullText.length() : fullText.length() - m_contextAfter.length() - 1;
    m_applyText = fullText.mid(startPos, endPos - startPos);
}

void RefactorWidget::closeEvent(QCloseEvent *event)
{
    if (!m_isClosing) {
        declineRefactoring();
    }
    event->accept();
}

void RefactorWidget::calculateStats()
{
    DiffStatistics stats;
    stats.calculate(m_cachedDiffList);
    m_linesAdded = stats.linesAdded();
    m_linesRemoved = stats.linesRemoved();
}

void RefactorWidget::updateStatsLabel()
{
    DiffStatistics stats;
    stats.calculate(m_cachedDiffList);
    m_statsLabel->setText("📊 " + stats.formatSummary());
}

void RefactorWidget::applySyntaxHighlighting()
{
    if (!m_sourceEditor) {
        return;
    }
    
    auto *sourceDoc = m_sourceEditor->textDocument();
    if (!sourceDoc || !sourceDoc->syntaxHighlighter()) {
        return;
    }
    
    m_leftDocument->setMimeType(sourceDoc->mimeType());
    m_rightDocument->setMimeType(sourceDoc->mimeType());
}

void RefactorWidget::addLineMarkers()
{
    if (m_cachedDiffList.isEmpty()) {
        return;
    }
    
    QList<Utils::Diff> leftDiffs;
    QList<Utils::Diff> rightDiffs;
    Utils::Differ::splitDiffList(m_cachedDiffList, &leftDiffs, &rightDiffs);
    
    int contextBeforeOffset = m_contextBefore.isEmpty() ? 0 : (m_contextBefore.length() + 1);
    
    QColor removedMarker = Utils::creatorColor(Utils::Theme::TextColorError);
    QColor addedMarker = Utils::creatorColor(Utils::Theme::IconsRunColor);
    
    QTextCursor leftCursor(m_leftDocument->document());
    int leftPos = 0;
    
    for (const auto &diff : leftDiffs) {
        if (diff.command == Utils::Diff::Delete) {
            leftCursor.setPosition(contextBeforeOffset + leftPos);
            leftCursor.movePosition(QTextCursor::StartOfBlock);
            leftCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
            
            QTextBlockFormat blockFormat;
            blockFormat.setBackground(QBrush(removedMarker.lighter(185)));
            blockFormat.setLeftMargin(4);
            blockFormat.setProperty(QTextFormat::FullWidthSelection, true);
            
            leftCursor.setBlockFormat(blockFormat);
        }
        if (diff.command != Utils::Diff::Insert) {
            leftPos += diff.text.length();
        }
    }
    
    QTextCursor rightCursor(m_rightDocument->document());
    int rightPos = 0;
    
    for (const auto &diff : rightDiffs) {
        if (diff.command == Utils::Diff::Insert) {
            rightCursor.setPosition(contextBeforeOffset + rightPos);
            rightCursor.movePosition(QTextCursor::StartOfBlock);
            rightCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
            
            QTextBlockFormat blockFormat;
            blockFormat.setBackground(QBrush(addedMarker.lighter(195)));
            blockFormat.setLeftMargin(4);
            blockFormat.setProperty(QTextFormat::FullWidthSelection, true);
            
            rightCursor.setBlockFormat(blockFormat);
        }
        if (diff.command != Utils::Diff::Delete) {
            rightPos += diff.text.length();
        }
    }
}

void RefactorWidget::updateSizeToContent()
{
    QFontMetrics fm(m_rightEditor->font());
    int lineHeight = fm.height();
    
    int leftMaxWidth = 0;
    int leftLineCount = 0;
    QTextBlock leftBlock = m_leftDocument->document()->begin();
    while (leftBlock.isValid()) {
        int lineWidth = fm.horizontalAdvance(leftBlock.text());
        leftMaxWidth = qMax(leftMaxWidth, lineWidth);
        leftLineCount++;
        leftBlock = leftBlock.next();
    }
    
    int rightMaxWidth = 0;
    int rightLineCount = 0;
    QTextBlock rightBlock = m_rightDocument->document()->begin();
    while (rightBlock.isValid()) {
        int lineWidth = fm.horizontalAdvance(rightBlock.text());
        rightMaxWidth = qMax(rightMaxWidth, lineWidth);
        rightLineCount++;
        rightBlock = rightBlock.next();
    }
    
    int maxLineWidth = qMax(leftMaxWidth, rightMaxWidth);
    int maxLineCount = qMax(leftLineCount, rightLineCount);
    
    const int editorPadding = 60;
    const int scrollBarWidth = 20;
    const int statsLabelHeight = 30;
    const int buttonLayoutHeight = 35;
    const int layoutMargins = 20;
    const int labelHeight = 20;
    
    int singleEditorWidth = maxLineWidth + editorPadding + scrollBarWidth;
    int contentHeight = maxLineCount * lineHeight + statsLabelHeight + buttonLayoutHeight + layoutMargins + labelHeight;
    
    bool horizontal = m_splitter->orientation() == Qt::Horizontal;
    
    int contentWidth;
    if (horizontal) {
        contentWidth = singleEditorWidth * 2 + m_splitter->handleWidth() + 20;
    } else {
        contentWidth = singleEditorWidth + 20;
    }
    
    QScreen *screen = window()->screen();
    if (!screen) {
        screen = QGuiApplication::primaryScreen();
    }
    int screenWidth = screen ? screen->availableGeometry().width() : 1920;
    int screenHeight = screen ? screen->availableGeometry().height() : 1080;
    
    const int minWidth = Settings::quickRefactorSettings().widgetMinWidth();
    const int maxWidth = qMin(Settings::quickRefactorSettings().widgetMaxWidth(), 
                              qMin(m_editorWidth - 40, screenWidth - 100));
    const int minHeight = Settings::quickRefactorSettings().widgetMinHeight();
    const int maxHeight = qMin(Settings::quickRefactorSettings().widgetMaxHeight(), screenHeight - 100);
    
    int targetWidth = qBound(minWidth, contentWidth, maxWidth);
    int targetHeight = qBound(minHeight, contentHeight, maxHeight);
    
    setFixedSize(targetWidth, targetHeight);
    
    updateGeometry();
}

void RefactorWidget::applyEditorSettings()
{
    if (!m_sourceEditor || !m_leftEditor || !m_rightEditor) {
        return;
    }
    
    QFont editorFont = m_sourceEditor->font();
    m_leftEditor->setFont(editorFont);
    m_rightEditor->setFont(editorFont);
    
    QString labelStyle = QString("color: %1; padding: 2px 4px;")
        .arg(Utils::creatorColor(Utils::Theme::TextColorDisabled).name());
    
    for (auto *label : findChildren<QLabel *>()) {
        if (label != m_statsLabel) {
            QFont labelFont = label->font();
            labelFont.setPointSize(qMax(8, editorFont.pointSize() - 2));
            label->setFont(labelFont);
            label->setStyleSheet(labelStyle);
        }
    }
    
    QFont statsFont = m_statsLabel->font();
    statsFont.setBold(true);
    statsFont.setPointSize(qMax(9, editorFont.pointSize() - 1));
    m_statsLabel->setFont(statsFont);
    
    m_statsLabel->setStyleSheet(QString(
        "color: %1; padding: 4px 6px; background-color: %2; border-radius: 3px;")
        .arg(Utils::creatorColor(Utils::Theme::TextColorNormal).name())
        .arg(Utils::creatorColor(Utils::Theme::BackgroundColorHover).name()));
    
    updateButtonStyles();
}

void RefactorWidget::updateButtonStyles()
{
    if (!m_applyButton || !m_declineButton) {
        return;
    }
    
    int baseFontSize = m_sourceEditor ? qMax(9, m_sourceEditor->font().pointSize() - 2) : 10;
    
    auto createStyle = [&](const QColor &color, bool bold) {
        return QString(
            "QPushButton {"
            "    background-color: %1; color: %2; border: 1px solid %3;"
            "    border-radius: 3px; padding: 2px 8px; font-size: %4pt;%5"
            "}"
            "QPushButton:hover { background-color: %6; border: 1px solid %2; }"
            "QPushButton:pressed { background-color: %7; }")
            .arg(Utils::creatorColor(Utils::Theme::BackgroundColorNormal).name())
            .arg(color.name())
            .arg(Utils::creatorColor(Utils::Theme::SplitterColor).name())
            .arg(baseFontSize)
            .arg(bold ? QLatin1StringView(" font-weight: bold;") : QLatin1StringView(""))
            .arg(Utils::creatorColor(Utils::Theme::BackgroundColorHover).name())
            .arg(Utils::creatorColor(Utils::Theme::BackgroundColorSelected).name());
    };
    
    m_applyButton->setStyleSheet(createStyle(Utils::creatorColor(Utils::Theme::TextColorNormal), true));
    m_declineButton->setStyleSheet(createStyle(Utils::creatorColor(Utils::Theme::TextColorError), false));
}

} // namespace QodeAssist
