#include "freezetablewidget.h"

#include <QScrollBar>
#include <QHeaderView>
#include <QDebug>
#include <qevent.h>

FreezeTableWidget::FreezeTableWidget(QWidget *parent)
    : QTableView(parent)
    , m_frozenColumns(2)  // Всегда замораживаем первые 2 столбца
    , frozenTableView(nullptr)
{
    frozenTableView = new QTableView(this);

    //connect the headers and scrollbars of both tableviews together
    connect(horizontalHeader(),&QHeaderView::sectionResized, this,
            &FreezeTableWidget::updateSectionWidth);
    connect(verticalHeader(),&QHeaderView::sectionResized, this,
            &FreezeTableWidget::updateSectionHeight);

    connect(frozenTableView->verticalScrollBar(), &QAbstractSlider::valueChanged,
            verticalScrollBar(), &QAbstractSlider::setValue);
    connect(verticalScrollBar(), &QAbstractSlider::valueChanged,
            frozenTableView->verticalScrollBar(), &QAbstractSlider::setValue);
}

FreezeTableWidget::~FreezeTableWidget()
{
    delete frozenTableView;
}

void FreezeTableWidget::setFrozenColumns(int count)
{
    // ЗАКОММЕНТИРОВАНО: Динамическое изменение количества замороженных столбцов
    // Всегда используем первые 2 столбца
    // if (m_frozenColumns != count) {
    //     m_frozenColumns = count;
    //     
    //     if (model()) {
    //         // Обновляем видимость столбцов в замороженной таблице
    //         for (int col = 0; col < model()->columnCount(); ++col) {
    //             frozenTableView->setColumnHidden(col, col >= m_frozenColumns);
    //         }
    //         
    //         updateFrozenTableGeometry();
    //     }
    // }
}

void FreezeTableWidget::init()
{
    frozenTableView->setModel(model());
    frozenTableView->setFocusPolicy(Qt::NoFocus);
    frozenTableView->verticalHeader()->hide();
    frozenTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

    viewport()->stackUnder(frozenTableView);

    // Убираем стиль для демонстрации - используем обычный вид
    frozenTableView->setSelectionModel(selectionModel());
    
    // Скрываем все столбцы кроме первых 2 (ID и обозначение)
    for (int col = 0; col < model()->columnCount(); ++col) {
        frozenTableView->setColumnHidden(col, col >= 2);
    }

    // Устанавливаем ширину замороженных столбцов
    for (int col = 0; col < 2 && col < model()->columnCount(); ++col) {
        frozenTableView->setColumnWidth(col, columnWidth(col));
    }

    frozenTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    frozenTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    frozenTableView->show();

    updateFrozenTableGeometry();

    setHorizontalScrollMode(ScrollPerPixel);
    setVerticalScrollMode(ScrollPerPixel);
    frozenTableView->setVerticalScrollMode(ScrollPerPixel);
    
    // Отключаем возможность изменения замороженных столбцов через клики
    frozenTableView->horizontalHeader()->setSectionsClickable(false);
    frozenTableView->horizontalHeader()->setSortIndicatorShown(false);
}

void FreezeTableWidget::setModel(QAbstractItemModel *model)
{
    QTableView::setModel(model);
    
    if (model) {
        init();
    }
}

void FreezeTableWidget::updateSectionWidth(int logicalIndex, int /* oldSize */, int newSize)
{
    // Обновляем ширину только первых 2 столбцов
    if (logicalIndex < 2) {
        frozenTableView->setColumnWidth(logicalIndex, newSize);
        updateFrozenTableGeometry();
    }
}

void FreezeTableWidget::updateSectionHeight(int logicalIndex, int /* oldSize */, int newSize)
{
    frozenTableView->setRowHeight(logicalIndex, newSize);
}

void FreezeTableWidget::resizeEvent(QResizeEvent * event)
{
    QTableView::resizeEvent(event);
    updateFrozenTableGeometry();
}

QModelIndex FreezeTableWidget::moveCursor(CursorAction cursorAction,
                                          Qt::KeyboardModifiers modifiers)
{
    QModelIndex current = QTableView::moveCursor(cursorAction, modifiers);

    if (cursorAction == MoveLeft && current.column() > 0
            && visualRect(current).topLeft().x() < frozenTableView->columnWidth(0) ){
        const int newValue = horizontalScrollBar()->value() + visualRect(current).topLeft().x()
                             - frozenTableView->columnWidth(0);
        horizontalScrollBar()->setValue(newValue);
    }
    return current;
}

void FreezeTableWidget::scrollTo (const QModelIndex & index, ScrollHint hint){
    if (index.column() >= 2)
        QTableView::scrollTo(index, hint);
}

void FreezeTableWidget::updateFrozenTableGeometry()
{
    if (!model())
        return;
    
    // Вычисляем общую ширину первых 2 столбцов
    int frozenWidth = 0;
    for (int col = 0; col < 2 && col < model()->columnCount(); ++col) {
        frozenWidth += columnWidth(col);
    }
    
    frozenTableView->setGeometry(verticalHeader()->width() + frameWidth(),
                               frameWidth(), frozenWidth,
                               viewport()->height()+horizontalHeader()->height());
}

void FreezeTableWidget::mousePressEvent(QMouseEvent *event)
{
    // Проверяем, не кликнули ли мы в области замороженных столбцов
    if (event->x() < frozenTableView->width()) {
        // Если клик в замороженной области, игнорируем его
        // Это предотвращает изменение замороженных столбцов
        return;
    }
    
    // Иначе обрабатываем клик как обычно
    QTableView::mousePressEvent(event);
}

void FreezeTableWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    // Проверяем, не кликнули ли мы в области замороженных столбцов
    if (event->x() < frozenTableView->width()) {
        // Если двойной клик в замороженной области, игнорируем его
        return;
    }
    
    // Иначе обрабатываем двойной клик как обычно
    QTableView::mouseDoubleClickEvent(event);
}

void FreezeTableWidget::contextMenuEvent(QContextMenuEvent *event)
{
    // Проверяем, не кликнули ли мы в области замороженных столбцов
    if (event->x() < frozenTableView->width()) {
        // Если контекстное меню в замороженной области, игнорируем его
        return;
    }
    
    // Иначе обрабатываем контекстное меню как обычно
    QTableView::contextMenuEvent(event);
} 
