#ifndef PERECHENTABLEMODEL_H
#define PERECHENTABLEMODEL_H

#include <QAbstractTableModel>
#include <QObject>
#include <QString>
#include <QList>
#include <QMap>
#include <QSet>
#include <QPair>

// Forward declaration
class ComponentModel;

// Forward declaration структуры для информации о переносе заголовков
struct PageBreakInfo;

// Структура для хранения данных ячейки
struct PerechenCellData
{
    QString value;           // Значение ячейки
    int rowNumber;          // Номер строки в документе
    int pageNumber;         // Номер страницы
    bool isHeader;          // Является ли заголовком
    bool isAutoGenerated;   // Автоматически сгенерированное значение
    bool isEmpty;           // Пустая ячейка
    int stretch;            // Поджим по ширине (100 = нормальный, по умолчанию 100)
    bool isUnderline;       // Подчеркивать ли текст (по умолчанию true для заголовков)
    
    PerechenCellData() : rowNumber(0), pageNumber(1), isHeader(false), 
                         isAutoGenerated(false), isEmpty(true), stretch(100), isUnderline(false) {}
    
    PerechenCellData(const QString &val, int row = 0, int page = 1, 
                     bool header = false, bool autoGen = false, bool empty = false, int cellStretch = 100, bool underline = false)
        : value(val), rowNumber(row), pageNumber(page), isHeader(header),
          isAutoGenerated(autoGen), isEmpty(empty), stretch(cellStretch), isUnderline(underline) {}
};

// Структура для хранения строки таблицы
struct PerechenRowData
{
    PerechenCellData position;      // Поз.обозначение
    PerechenCellData designation;   // Наименование
    PerechenCellData quantity;      // Кол.
    PerechenCellData note;          // Примечание
    bool isHeader;                  // Является ли заголовком
    bool isEmpty;                   // Пустая строка
    int rowNumber;                  // Номер строки в документе
    int pageNumber;                 // Номер страницы
    
    PerechenRowData() : isHeader(false), isEmpty(false), rowNumber(0), pageNumber(1) {}
};

class PerechenTableModel : public QAbstractTableModel
{
    Q_OBJECT
    Q_PROPERTY(QStringList columnMappings READ columnMappings WRITE setColumnMappings NOTIFY columnMappingsChanged FINAL)
    
public:
    explicit PerechenTableModel(QObject *parent = nullptr);
    
    // Константы для разбивки на страницы
    static const int ROWS_PER_FIRST_PAGE = 25;
    static const int ROWS_PER_OTHER_PAGE = 32;
    
    // Методы QAbstractTableModel
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    
    // Методы для работы с данными
    void setColumnMappings(const QStringList &mappings);
    QStringList columnMappings() const;
    
    // Методы для работы со строками
    void addRow(const PerechenRowData &rowData);
    void insertRow(int position, const PerechenRowData &rowData);
    void removeRow(int row);
    void clear();
    
    // Новые методы для управления строками
    void addEmptyRow();
    void addEmptyRowAt(int position);
    PerechenRowData createEmptyRow() const;
    bool canEditRow(int row) const;
    
    // Методы для работы с компонентами
    void setComponents(const QList<ComponentModel*> &components);
    
    // Методы для работы с настройками
    void setPropertyNames(const QStringList &propertyNames);
    QStringList availableProperties() const;
    
    // Методы для сохранения/загрузки
    QByteArray saveToDatabase() const;
    void loadFromDatabase(const QByteArray &data);
    
    // Методы для экспорта
    QString getDocumentTitle() const;
    QString getDocumentType() const;
    
    // Методы для проверки статуса строки
    bool isRowHeader(int row) const;
    
    // Метод для установки поджима ячейки
    bool setCellStretch(int row, int column, int stretch);
    
    // Метод для установки флага заголовка ячейки
    bool setCellHeader(int row, int column, bool isHeader);
    
    // Метод для установки флага подчеркивания ячейки
    bool setCellUnderline(int row, int column, bool isUnderline);
    
    // Метод для проверки переполнения ячейки (для подсветки в UI)
    bool isCellOverflow(int row, int column, qreal columnWidth, int fontSize = 12) const;
    
    // Метод для пометки ячейки как переполненной (вызывается из PDFController)
    void setCellOverflow(int row, int column, bool overflow);
    
    // Метод для очистки всех пометок о переполнении
    void clearOverflowMarks();
    
    // Методы для работы с переносом страниц
    bool needsPageBreakProtection(int rowIndex) const;
    void addPageBreakProtection();
    void optimizePageBreaks();
    void updatePageDisplay();
    
    // Новые методы для работы с разрывами страниц
    void updatePageNumbers();
    void updateRowNumbers();
    int getPageForRow(int rowNumber) const;
    
signals:
    void columnMappingsChanged();
    void modelDataChanged();
    void requestPageBreakConfirmation(const QList<PageBreakInfo> &pageBreakInfos);
    
private:
    void updateRowEmptyStatus(int row);
    PerechenCellData createCellData(const QString &value, bool isHeader = false, 
                                   bool isAuto = false, bool isEmpty = false);
    
    QList<PerechenRowData> m_rows;
    QStringList m_columnMappings;  // Маппинг колонок на свойства компонентов
    QStringList m_propertyNames;   // Доступные свойства компонентов
    QList<ComponentModel*> m_components;  // Компоненты для генерации
    QSet<QPair<int, int>> m_overflowCells;  // Множество переполненных ячеек (row, column)
    
    static const int COLUMN_COUNT = 4;
    static const QStringList DEFAULT_HEADERS;
};

#endif // PERECHENTABLEMODEL_H 