#include "stickytableview_fixed.h"
#include <QScrollBar>
#include <QHeaderView>
#include <QPainter>
#include <QApplication>
#include <QDebug>

StickyTableViewFixed::StickyTableViewFixed(QWidget *parent)
    : QTableView(parent)
    , m_stickyColumns(1)
    , m_stickyColumnWidth(0)
{
    // Настройка горизонтального скроллбара
    setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
}

void StickyTableViewFixed::setStickyColumns(int count)
{
    if (m_stickyColumns != count) {
        m_stickyColumns = count;
        updateStickyColumnGeometry();
        viewport()->update();
    }
}

void StickyTableViewFixed::paintEvent(QPaintEvent *event)
{
    // Сначала рисуем обычную таблицу
    QTableView::paintEvent(event);
    
    // Затем рисуем липкие столбцы поверх
    if (m_stickyColumns > 0 && model()) {
        QPainter painter(viewport());
        paintStickyColumns(&painter);
    }
}

void StickyTableViewFixed::scrollContentsBy(int dx, int dy)
{
    QTableView::scrollContentsBy(dx, dy);
    
    // Обновляем геометрию липких столбцов после скролла
    updateStickyColumnGeometry();
}

void StickyTableViewFixed::resizeEvent(QResizeEvent *event)
{
    QTableView::resizeEvent(event);
    updateStickyColumnGeometry();
}

QModelIndex StickyTableViewFixed::indexAt(const QPoint &point) const
{
    // Проверяем, находится ли точка в области липких столбцов
    if (point.x() < m_stickyColumnWidth) {
        // Ищем в липких столбцах
        for (int row = 0; row < model()->rowCount(); ++row) {
            for (int col = 0; col < m_stickyColumns; ++col) {
                QRect rect = stickyColumnRect(row, col);
                if (rect.contains(point)) {
                    return model()->index(row, col);
                }
            }
        }
    }
    
    // Иначе используем стандартную логику
    return QTableView::indexAt(point);
}

QRect StickyTableViewFixed::visualRect(const QModelIndex &index) const
{
    if (!index.isValid())
        return QRect();
    
    // Если это липкий столбец, возвращаем его координаты
    if (index.column() < m_stickyColumns) {
        return stickyColumnRect(index.row(), index.column());
    }
    
    // Иначе используем стандартную логику
    return QTableView::visualRect(index);
}

void StickyTableViewFixed::updateStickyColumnGeometry()
{
    if (!model() || m_stickyColumns <= 0)
        return;
    
    // Вычисляем ширину липких столбцов
    m_stickyColumnWidth = 0;
    for (int i = 0; i < m_stickyColumns && i < model()->columnCount(); ++i) {
        m_stickyColumnWidth += columnWidth(i);
    }
    
    // НЕ устанавливаем отступы для viewport - это вызывает проблемы
    // Вместо этого будем правильно обрабатывать координаты
}

void StickyTableViewFixed::paintStickyColumns(QPainter *painter)
{
    if (!model() || m_stickyColumns <= 0)
        return;
    
    // Сохраняем состояние painter
    painter->save();
    
    // Получаем видимые строки
    QRect visibleRect = viewport()->rect();
    int topRow = rowAt(visibleRect.top());
    int bottomRow = rowAt(visibleRect.bottom());
    
    if (topRow < 0) topRow = 0;
    if (bottomRow < 0) bottomRow = model()->rowCount() - 1;
    
    // Рисуем липкие столбцы
    for (int row = topRow; row <= bottomRow && row < model()->rowCount(); ++row) {
        for (int col = 0; col < m_stickyColumns && col < model()->columnCount(); ++col) {
            QRect cellRect = stickyColumnRect(row, col);
            
            // Рисуем фон ячейки
            QModelIndex index = model()->index(row, col);
            QStyleOptionViewItem option;
            option.initFrom(this);
            option.rect = cellRect;
            option.state = QStyle::State_Enabled;
            
            if (selectionModel() && selectionModel()->isSelected(index)) {
                option.state |= QStyle::State_Selected;
            }
            
            if (index == currentIndex()) {
                option.state |= QStyle::State_HasFocus;
            }
            
            style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter);
            
            // Рисуем текст ячейки
            QVariant data = model()->data(index, Qt::DisplayRole);
            if (data.isValid()) {
                painter->drawText(cellRect.adjusted(4, 0, -4, 0), 
                                Qt::AlignVCenter | Qt::AlignLeft,
                                data.toString());
            }
        }
    }
    
    // Рисуем границы липких столбцов
    painter->setPen(QPen(Qt::black, 1));
    painter->drawLine(m_stickyColumnWidth - 1, 0, m_stickyColumnWidth - 1, viewport()->height());
    
    // Восстанавливаем состояние painter
    painter->restore();
}

QRect StickyTableViewFixed::stickyColumnRect(int row, int col) const
{
    if (!model() || row < 0 || col < 0 || col >= m_stickyColumns)
        return QRect();
    
    int y = rowViewportPosition(row);
    int currentRowHeight = rowHeight(row);
    
    int x = 0;
    for (int i = 0; i < col; ++i) {
        x += columnWidth(i);
    }
    
    return QRect(x, y, columnWidth(col), currentRowHeight);
} 