#include "simplelisttablemodel.h"
#include "componentmodel.h"
#include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

// Регистрируем структуры для работы с QVariant
Q_DECLARE_METATYPE(SimpleListCellData)
Q_DECLARE_METATYPE(SimpleListRowData)

// Статические константы
const QStringList SimpleListTableModel::DEFAULT_HEADERS = QStringList() << "Поз.обозначение" << "Наименование" << "Кол.";

SimpleListTableModel::SimpleListTableModel(QObject *parent)
    : QAbstractTableModel(parent)
    , m_techReservePercent(10)
{
    qDebug() << "SimpleListTableModel::SimpleListTableModel: Создана модель";
}

int SimpleListTableModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return m_rows.size();
}

int SimpleListTableModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return COLUMN_COUNT;
}

QVariant SimpleListTableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= m_rows.size())
        return QVariant();

    const SimpleListRowData &row = m_rows[index.row()];
    
    if (role == Qt::DisplayRole || role == Qt::EditRole) {
        switch (index.column()) {
        case 0: return row.designator.value;
        case 1: return row.name.value;
        case 2: return row.quantity.value;
        default: return QVariant();
        }
    } else if (role == Qt::UserRole) {
        // Возвращаем структуру ячейки для дополнительной информации
        switch (index.column()) {
        case 0: return QVariant::fromValue(row.designator);
        case 1: return QVariant::fromValue(row.name);
        case 2: return QVariant::fromValue(row.quantity);
        default: return QVariant();
        }
    }
    
    return QVariant();
}

QVariant SimpleListTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole)
        return QVariant();

    if (orientation == Qt::Horizontal) {
        if (section < DEFAULT_HEADERS.size()) {
            QString header = DEFAULT_HEADERS[section];
            // Для столбца "Кол." (индекс 2) добавляем процент тех запаса
            if (section == 2) {
                header = QString("Кол-во (+%1%)").arg(m_techReservePercent);
            }
            return header;
        }
    } else {
        return section + 1;
    }

    return QVariant();
}

bool SimpleListTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid() || index.row() >= m_rows.size() || role != Qt::EditRole)
        return false;

    if (!canEditRow(index.row())) {
        qDebug() << "SimpleListTableModel::setData: Строка" << index.row() << "не может быть отредактирована";
        return false;
    }

    SimpleListRowData &row = m_rows[index.row()];
    QString newValue = value.toString();
    
    switch (index.column()) {
    case 0:
        row.designator.value = newValue;
        row.designator.isAutoGenerated = false;
        row.designator.isEmpty = newValue.isEmpty();
        break;
    case 1:
        row.name.value = newValue;
        row.name.isAutoGenerated = false;
        row.name.isEmpty = newValue.isEmpty();
        break;
    case 2:
        row.quantity.value = newValue;
        row.quantity.isAutoGenerated = false;
        row.quantity.isEmpty = newValue.isEmpty();
        break;
    default:
        return false;
    }

    // Обновляем флаг isEmpty для строки
    updateRowEmptyStatus(index.row());

    emit dataChanged(index, index, QVector<int>() << role);
    return true;
}

Qt::ItemFlags SimpleListTableModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::NoItemFlags;

    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    
    // Разрешаем редактирование только для редактируемых строк
    if (canEditRow(index.row())) {
        flags |= Qt::ItemIsEditable;
    }
    
    return flags;
}

void SimpleListTableModel::addRow(const SimpleListRowData &rowData)
{
    beginInsertRows(QModelIndex(), m_rows.size(), m_rows.size());
    m_rows.append(rowData);
    endInsertRows();
    emit modelDataChanged();
}

void SimpleListTableModel::insertRow(int position, const SimpleListRowData &rowData)
{
    if (position < 0 || position > m_rows.size())
        return;

    beginInsertRows(QModelIndex(), position, position);
    m_rows.insert(position, rowData);
    endInsertRows();
    emit modelDataChanged();
}

void SimpleListTableModel::removeRow(int row)
{
    if (row < 0 || row >= m_rows.size())
        return;

    beginRemoveRows(QModelIndex(), row, row);
    m_rows.removeAt(row);
    endRemoveRows();
    emit modelDataChanged();
}

void SimpleListTableModel::clear()
{
    qDebug() << "SimpleListTableModel::clear: Очищаем таблицу, строк:" << m_rows.size();
    
    if (m_rows.isEmpty()) {
        return;
    }

    beginResetModel();
    m_rows.clear();
    endResetModel();
    
    emit modelDataChanged();
}

void SimpleListTableModel::setComponents(const QList<ComponentModel*> &components)
{
    qDebug() << "SimpleListTableModel::setComponents: Получено" << components.size() << "компонентов";
    
    // Проверяем компоненты на null
    QList<ComponentModel*> validComponents;
    for (ComponentModel *component : components) {
        if (component) {
            validComponents.append(component);
        }
    }
    
    m_components = validComponents;
    qDebug() << "SimpleListTableModel::setComponents: Сохранено" << m_components.size() << "валидных компонентов";
}

QByteArray SimpleListTableModel::saveToDatabase() const
{
    qDebug() << "SimpleListTableModel::saveToDatabase: Начинаем сохранение в БД";
    qDebug() << "SimpleListTableModel::saveToDatabase: Количество строк:" << m_rows.size();
    
    QJsonObject root;
    QJsonArray rowsArray;
    
    for (const SimpleListRowData &row : m_rows) {
        QJsonObject rowObj;
        
        // Сохраняем данные ячеек
        QJsonObject designatorObj;
        designatorObj["value"] = row.designator.value;
        designatorObj["isAutoGenerated"] = row.designator.isAutoGenerated;
        designatorObj["isEmpty"] = row.designator.isEmpty;
        rowObj["designator"] = designatorObj;
        
        QJsonObject nameObj;
        nameObj["value"] = row.name.value;
        nameObj["isAutoGenerated"] = row.name.isAutoGenerated;
        nameObj["isEmpty"] = row.name.isEmpty;
        rowObj["name"] = nameObj;
        
        QJsonObject quantityObj;
        quantityObj["value"] = row.quantity.value;
        quantityObj["isAutoGenerated"] = row.quantity.isAutoGenerated;
        quantityObj["isEmpty"] = row.quantity.isEmpty;
        rowObj["quantity"] = quantityObj;
        
        rowObj["isEmpty"] = row.isEmpty;
        
        rowsArray.append(rowObj);
    }
    
    root["rows"] = rowsArray;
    
    QJsonDocument doc(root);
    QByteArray result = doc.toJson();
    
    qDebug() << "SimpleListTableModel::saveToDatabase: Сохранение завершено, размер данных:" << result.size() << "байт";
    return result;
}

void SimpleListTableModel::loadFromDatabase(const QByteArray &data)
{
    qDebug() << "SimpleListTableModel::loadFromDatabase: Начинаем загрузку из БД, размер данных:" << data.size();
    
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (!doc.isObject()) {
        qDebug() << "SimpleListTableModel::loadFromDatabase: Ошибка парсинга JSON";
        return;
    }
    
    QJsonObject root = doc.object();
    
    // Загружаем строки
    clear();
    if (root.contains("rows")) {
        QJsonArray rowsArray = root["rows"].toArray();
        for (const QJsonValue &value : rowsArray) {
            QJsonObject rowObj = value.toObject();
            SimpleListRowData row;
            
            if (rowObj.contains("designator")) {
                QJsonObject desObj = rowObj["designator"].toObject();
                row.designator = SimpleListCellData(
                    desObj["value"].toString(),
                    desObj["isAutoGenerated"].toBool(),
                    desObj["isEmpty"].toBool()
                );
            }
            
            if (rowObj.contains("name")) {
                QJsonObject nameObj = rowObj["name"].toObject();
                row.name = SimpleListCellData(
                    nameObj["value"].toString(),
                    nameObj["isAutoGenerated"].toBool(),
                    nameObj["isEmpty"].toBool()
                );
            }
            
            if (rowObj.contains("quantity")) {
                QJsonObject qtyObj = rowObj["quantity"].toObject();
                row.quantity = SimpleListCellData(
                    qtyObj["value"].toString(),
                    qtyObj["isAutoGenerated"].toBool(),
                    qtyObj["isEmpty"].toBool()
                );
            }
            
            row.isEmpty = rowObj["isEmpty"].toBool();
            
            addRow(row);
        }
    }
    
    qDebug() << "SimpleListTableModel::loadFromDatabase: Загружено строк:" << m_rows.size();
}

QString SimpleListTableModel::getDocumentTitle() const
{
    return "Список элементов";
}

QString SimpleListTableModel::getDocumentType() const
{
    return "SimpleList";
}

void SimpleListTableModel::addEmptyRow()
{
    SimpleListRowData emptyRow = createEmptyRow();
    addRow(emptyRow);
}

void SimpleListTableModel::addEmptyRowAt(int position)
{
    SimpleListRowData emptyRow = createEmptyRow();
    insertRow(position, emptyRow);
}

SimpleListRowData SimpleListTableModel::createEmptyRow() const
{
    SimpleListRowData row;
    row.isEmpty = false;
    
    row.designator = SimpleListCellData("", false, true);
    row.name = SimpleListCellData("", false, true);
    row.quantity = SimpleListCellData("", false, true);
    
    return row;
}

bool SimpleListTableModel::canEditRow(int row) const
{
    if (row < 0 || row >= m_rows.size())
        return false;
    
    return true;
}

void SimpleListTableModel::updateRowEmptyStatus(int row)
{
    if (row < 0 || row >= m_rows.size())
        return;
    
    SimpleListRowData &rowData = m_rows[row];
    
    // Проверяем, пустые ли все ячейки
    bool allEmpty = rowData.designator.value.isEmpty() &&
                   rowData.name.value.isEmpty() &&
                   rowData.quantity.value.isEmpty();
    
    // Обновляем флаг isEmpty для строки
    if (rowData.isEmpty != allEmpty) {
        rowData.isEmpty = allEmpty;
    }
}

SimpleListCellData SimpleListTableModel::createCellData(const QString &value, bool isAuto, bool isEmpty)
{
    return SimpleListCellData(value, isAuto, isEmpty);
}

void SimpleListTableModel::setTechReservePercent(int percent)
{
    if (m_techReservePercent != percent) {
        m_techReservePercent = percent;
        // Обновляем заголовок столбца количества
        emit headerDataChanged(Qt::Horizontal, 2, 2);
    }
}

int SimpleListTableModel::getTechReservePercent() const
{
    return m_techReservePercent;
}

