#include "titleinscriptionsdialog.h"
#include <QApplication>
#include <QScreen>
#include <QToolTip>
#include <QMessageBox>
#include <QDebug>

// Инициализация статических данных о графах ГОСТ
QMap<int, QString> TitleInscriptionsDialog::s_fieldNames;
QMap<int, QString> TitleInscriptionsDialog::s_fieldDescriptions;

void TitleInscriptionsDialog::initializeFieldData()
{
    if (!s_fieldNames.isEmpty()) {
        qDebug() << "TitleInscriptionsDialog::initializeFieldData: Данные полей уже инициализированы";
        return; // Уже инициализировано
    }
    
    qDebug() << "TitleInscriptionsDialog::initializeFieldData: Инициализируем данные полей ГОСТ";
    
    s_fieldNames[1] = "Наименование изделия и документа";
    s_fieldNames[2] = "Обозначение документа";
    s_fieldNames[3] = "Обозначение материала детали";
    s_fieldNames[4] = "Литера";
    s_fieldNames[5] = "Масса изделия";
    s_fieldNames[6] = "Масштаб";
    s_fieldNames[7] = "Порядковый номер листа";
    s_fieldNames[8] = "Общее количество листов";
    s_fieldNames[9] = "Наименование организации";
    s_fieldNames[10] = "Характер работы";
    s_fieldNames[11] = "Фамилии лиц";
    s_fieldNames[12] = "Подписи лиц";
    s_fieldNames[13] = "Дата подписания";
    s_fieldNames[14] = "Сведения об изменениях";
    s_fieldNames[15] = "Сведения об изменениях";
    s_fieldNames[16] = "Сведения об изменениях";
    s_fieldNames[17] = "Сведения об изменениях";
    s_fieldNames[18] = "Сведения об изменениях";
    s_fieldNames[19] = "Инвентарный номер подлинника";
    s_fieldNames[20] = "Сведения о приемке подлинника";
    s_fieldNames[21] = "Инвентарный номер подлинника (взамен)";
    s_fieldNames[22] = "Инвентарный номер дубликата";
    s_fieldNames[23] = "Сведения о приемке дубликата";
    s_fieldNames[24] = "Обозначение документа (взамен)";
    s_fieldNames[25] = "Обозначение соответствующего документа";
    s_fieldNames[26] = "Обозначение документа (повернутое)";
    s_fieldNames[27] = "Знак заказчика";
    s_fieldNames[28] = "Номер решения и год утверждения";
    s_fieldNames[29] = "Номер решения и год утверждения";
    s_fieldNames[30] = "Индекс заказчика";
    s_fieldNames[31] = "Подпись лица, копировавшего документ";
    s_fieldNames[32] = "Обозначение формата листа";
    s_fieldNames[33] = "Обозначение зоны";
    s_fieldNames[34] = "Номера авторских свидетельств";
    s_fieldNames[35] = "Номер версии документа";
    s_fieldNames[36] = "Единица измерения";
    s_fieldNames[37] = "Метод проецирования";
    s_fieldNames[38] = "Имя файла";
    s_fieldNames[39] = "Признак аутентичного документа";
    s_fieldNames[40] = "Код документа";
    s_fieldNames[41] = "Обозначение документа аналогичного изделия";
    
    // Описания граф согласно ГОСТ
    s_fieldDescriptions[1] = "Наименование изделия и наименование документа, если этому документу присвоен код. Наименование изделия должно соответствовать принятой терминологии и быть по возможности кратким.";
    s_fieldDescriptions[2] = "Обозначение документа по ГОСТ 2.201 и код, если его код определен ГОСТ 2.102, ГОСТ 2.601, ГОСТ 2.602, ГОСТ 2.701.";
    s_fieldDescriptions[3] = "Обозначение материала детали (графу заполняют только на чертежах деталей).";
    s_fieldDescriptions[4] = "Литера, присвоенная данному документу (на документе в бумажной форме графу заполняют последовательно, начиная с крайней левой клетки).";
    s_fieldDescriptions[5] = "Масса изделия по ГОСТ 2.109.";
    s_fieldDescriptions[6] = "Масштаб (проставляется в соответствии с ГОСТ 2.302 и ГОСТ 2.109).";
    s_fieldDescriptions[7] = "Порядковый номер листа (на документах, состоящих из одного листа, графу не заполняют).";
    s_fieldDescriptions[8] = "Общее количество листов документа (указывают только на первом листе).";
    s_fieldDescriptions[9] = "Наименование или код организации, выпускающей документ (графу не заполняют, если код содержится в обозначении документа).";
    s_fieldDescriptions[10] = "Характер работы, выполняемой лицом, подписывающим документ, в соответствии с формами 1 и 2.";
    s_fieldDescriptions[11] = "Фамилии лиц, подписавших документ.";
    s_fieldDescriptions[12] = "Подписи лиц, фамилии которых указаны в графе 11.";
    s_fieldDescriptions[13] = "Дата подписания документа.";
    s_fieldDescriptions[14] = "Сведения об изменениях, которые заполняют в соответствии с требованиями ГОСТ 2.503.";
    s_fieldDescriptions[15] = "Сведения об изменениях, которые заполняют в соответствии с требованиями ГОСТ 2.503.";
    s_fieldDescriptions[16] = "Сведения об изменениях, которые заполняют в соответствии с требованиями ГОСТ 2.503.";
    s_fieldDescriptions[17] = "Сведения об изменениях, которые заполняют в соответствии с требованиями ГОСТ 2.503.";
    s_fieldDescriptions[18] = "Сведения об изменениях, которые заполняют в соответствии с требованиями ГОСТ 2.503.";
    s_fieldDescriptions[19] = "Инвентарный номер подлинника по ГОСТ 2.501.";
    s_fieldDescriptions[20] = "Сведения о приемке подлинника в службу технической документации (подпись и дата приемки).";
    s_fieldDescriptions[21] = "Инвентарный номер подлинника, взамен которого выпущен данный подлинник по ГОСТ 2.503.";
    s_fieldDescriptions[22] = "Инвентарный номер дубликата по ГОСТ 2.502.";
    s_fieldDescriptions[23] = "Сведения о приемке дубликата в службу технической документации (подпись и дата приемки).";
    s_fieldDescriptions[24] = "Обозначение документа, взамен или на основании которого выпущен данный документ.";
    s_fieldDescriptions[25] = "Обозначение соответствующего документа, в котором впервые записан данный документ. Обязательный реквизит для всех документов, заимствованных из документации других изделий.";
    s_fieldDescriptions[26] = "Обозначение документа, повернутое на 180° для формата А4 и для форматов больше А4 при расположении основной надписи вдоль длинной стороны листа и на 90° для форматов больше А4 при расположении основной надписи вдоль короткой стороны листа.";
    s_fieldDescriptions[27] = "Знак, установленный заказчиком в соответствии с требованиями нормативной документации и проставляемый заказчиком или представительством заказчика.";
    s_fieldDescriptions[28] = "Номер решения и год утверждения документации соответствующей литеры. Год утверждения указывают четырьмя цифрами.";
    s_fieldDescriptions[29] = "Номер решения и год утверждения документации. Год утверждения указывают четырьмя цифрами.";
    s_fieldDescriptions[30] = "Индекс заказчика в соответствии с нормативной документацией.";
    s_fieldDescriptions[31] = "Подпись лица, копировавшего документ. При копировании электронного документа обязательный реквизит.";
    s_fieldDescriptions[32] = "Обозначение формата листа по ГОСТ 2.301. Для электронного документа указывают формат листа, на котором будет соответствовать указанный в графе 6 масштаб.";
    s_fieldDescriptions[33] = "Обозначение зоны, в которой находится изменяемая часть изделия.";
    s_fieldDescriptions[34] = "Номера авторских свидетельств на изобретения, использованные в данном изделии.";
    s_fieldDescriptions[35] = "Номер версии документа в электронной форме, с которого на устройствах вывода ЭВМ получен документ в бумажной форме. Графу заполняют только для документов, изготавливаемых с применением ЭВМ.";
    s_fieldDescriptions[36] = "Единица измерения (метрическая или дюймовая).";
    s_fieldDescriptions[37] = "Метод проецирования. Способ расположения проекций детали на чертеже. Обязательный, если проецирование не соответствует ГОСТ 2.305.";
    s_fieldDescriptions[38] = "Имя файла, содержащего документ в электронной форме. Графу заполняют только для документов, изготавливаемых с помощью ЭВМ.";
    s_fieldDescriptions[39] = "Признак аутентичного документа (обязательный для аутентичных документов).";
    s_fieldDescriptions[40] = "Код документа в зависимости от характера использования. Для электронных документов в соответствии с ГОСТ 2.102 применяют коды: 1 — оригинал, 2 — подлинник, 3 — дубликат, 4 — копия.";
    s_fieldDescriptions[41] = "Обозначение документа аналогичного изделия, для которого ранее изготовлены средства технологического оснащения, необходимые для данного изделия.";
    
    qDebug() << "TitleInscriptionsDialog::initializeFieldData: Инициализировано" << s_fieldNames.size() << "названий полей и" << s_fieldDescriptions.size() << "описаний";
}

TitleInscriptionsDialog::TitleInscriptionsDialog(ProjectParamTableModel *projectParamModel, QWidget *parent)
    : QDialog{parent}
    , m_projectParamModel{projectParamModel}
    , m_titleInscriptionsModel{nullptr}
{
    qDebug() << "TitleInscriptionsDialog: Конструктор, projectParamModel:" << (projectParamModel ? "доступен" : "nullptr");
    initializeFieldData();
    setUp();
    qDebug() << "TitleInscriptionsDialog: Конструктор завершен, создано полей:" << s_fieldNames.size();
}

void TitleInscriptionsDialog::setUp()
{
    qDebug() << "TitleInscriptionsDialog::setUp: Начинаем настройку диалога";
    setWidgets();
    setUpLayout();
    setUpConnections();
    createInscriptionFields();
    createImagePreview();
    
    // Устанавливаем размер окна
    resize(1200, 800);
    setWindowTitle("Настройка основных надписей документа");
    qDebug() << "TitleInscriptionsDialog::setUp: Настройка диалога завершена";
}

void TitleInscriptionsDialog::setWidgets()
{
    qDebug() << "TitleInscriptionsDialog::setWidgets: Создаем виджеты";
    m_scrollArea = new QScrollArea(this);
    m_scrollContent = new QWidget();
    m_scrollArea->setWidget(m_scrollContent);
    m_scrollArea->setWidgetResizable(true);
    
    m_imageView = new QGraphicsView(this);
    m_imageScene = new QGraphicsScene(this);
    m_imageView->setScene(m_imageScene);
    m_imageView->setRenderHint(QPainter::Antialiasing);
    m_imageView->setDragMode(QGraphicsView::ScrollHandDrag);
    
    m_zoomSlider = new QSlider(Qt::Horizontal, this);
    m_zoomSlider->setRange(25, 200);
    m_zoomSlider->setValue(100);
    m_zoomSlider->setTickPosition(QSlider::TicksBelow);
    m_zoomSlider->setTickInterval(25);
    
    m_okButton = new QPushButton("ОК", this);
    m_cancelButton = new QPushButton("Отмена", this);
    qDebug() << "TitleInscriptionsDialog::setWidgets: Виджеты созданы";
}

void TitleInscriptionsDialog::setUpLayout()
{
    qDebug() << "TitleInscriptionsDialog::setUpLayout: Настраиваем компоновку";
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    
    // Создаем горизонтальный layout для разделения на две части
    QHBoxLayout *contentLayout = new QHBoxLayout();
    
    // Левая часть - поля надписей
    QVBoxLayout *leftLayout = new QVBoxLayout();
    leftLayout->addWidget(new QLabel("Настройка надписей:", this));
    leftLayout->addWidget(m_scrollArea);
    
    // Правая часть - изображение
    QVBoxLayout *rightLayout = new QVBoxLayout();
    rightLayout->addWidget(new QLabel("Предварительный просмотр:", this));
    rightLayout->addWidget(m_imageView);
    rightLayout->addWidget(new QLabel("Масштаб:", this));
    rightLayout->addWidget(m_zoomSlider);
    
    contentLayout->addLayout(leftLayout, 1);
    contentLayout->addLayout(rightLayout, 1);
    
    // Кнопки
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->addStretch();
    buttonLayout->addWidget(m_okButton);
    buttonLayout->addWidget(m_cancelButton);
    
    mainLayout->addLayout(contentLayout);
    mainLayout->addLayout(buttonLayout);
    qDebug() << "TitleInscriptionsDialog::setUpLayout: Компоновка настроена";
}

void TitleInscriptionsDialog::setUpConnections()
{
    qDebug() << "TitleInscriptionsDialog::setUpConnections: Настраиваем соединения сигналов";
    connect(m_okButton, &QPushButton::clicked, this, &TitleInscriptionsDialog::onAccept);
    connect(m_cancelButton, &QPushButton::clicked, this, &TitleInscriptionsDialog::onCancel);
    connect(m_zoomSlider, &QSlider::valueChanged, this, &TitleInscriptionsDialog::onZoomChanged);
    qDebug() << "TitleInscriptionsDialog::setUpConnections: Соединения сигналов настроены";
}

void TitleInscriptionsDialog::createInscriptionFields()
{
    QVBoxLayout *fieldsLayout = new QVBoxLayout(m_scrollContent);
    
    qDebug() << "TitleInscriptionsDialog::createInscriptionFields: Начинаем создание полей";
    
    // Создаем поля для всех граф ГОСТ (1-41)
    int createdFields = 0;
    for (int i = 1; i <= 41; ++i) {
        if (!s_fieldNames.contains(i)) continue;
        
        QGroupBox *fieldGroup = new QGroupBox(QString("Графа %1: %2").arg(i).arg(s_fieldNames[i]), m_scrollContent);
        QHBoxLayout *fieldLayout = new QHBoxLayout(fieldGroup);
        
        // Метка с описанием
        QLabel *descriptionLabel = new QLabel(s_fieldDescriptions[i], fieldGroup);
        descriptionLabel->setWordWrap(true);
        descriptionLabel->setToolTip(s_fieldDescriptions[i]);
        fieldLayout->addWidget(descriptionLabel, 1);
        
        // Комбобокс для выбора значения
        QComboBox *comboBox = new QComboBox(fieldGroup);
        comboBox->addItem("Пусто", "");
        
        // Добавляем параметры проекта
        if (m_projectParamModel) {
            QList<ProjectParamTableData> params = m_projectParamModel->getData();
            qDebug() << "TitleInscriptionsDialog::createInscriptionFields: Добавляем" << params.size() << "параметров проекта для поля" << i;
            for (const auto &param : params) {
                comboBox->addItem(param.name, param.name);
            }
        } else {
            qDebug() << "TitleInscriptionsDialog::createInscriptionFields: Модель параметров проекта недоступна для поля" << i;
        }
        
        comboBox->addItem("Кастомное значение", "custom");
        fieldLayout->addWidget(comboBox);
        
        // Поле для кастомного значения (изначально скрыто)
        QLineEdit *customEdit = new QLineEdit(fieldGroup);
        customEdit->setPlaceholderText("Введите значение...");
        customEdit->setVisible(false);
        fieldLayout->addWidget(customEdit);
        
        // Сохраняем ссылки на виджеты
        m_comboBoxes[i] = comboBox;
        m_customEdits[i] = customEdit;
        m_fieldLabels[i] = descriptionLabel;
        
        // Создаем структуру поля
        TitleInscriptionField field;
        field.number = i;
        field.name = s_fieldNames[i];
        field.description = s_fieldDescriptions[i];
        field.currentValue = "";
        field.isCustom = false;
        m_fields[i] = field;
        
        // Подключаем сигналы
        connect(comboBox, QOverload<const QString &>::of(&QComboBox::currentTextChanged),
                [this, i](const QString &value) { onComboBoxChanged(i, value); });
        connect(customEdit, &QLineEdit::textChanged,
                [this, i](const QString &value) { onCustomValueChanged(i, value); });
        
        fieldsLayout->addWidget(fieldGroup);
        createdFields++;
    }
    
    qDebug() << "TitleInscriptionsDialog::createInscriptionFields: Создано полей:" << createdFields;
    qDebug() << "TitleInscriptionsDialog::createInscriptionFields: Размер m_fields:" << m_fields.size();
    qDebug() << "TitleInscriptionsDialog::createInscriptionFields: Размер m_comboBoxes:" << m_comboBoxes.size();
    qDebug() << "TitleInscriptionsDialog::createInscriptionFields: Размер m_customEdits:" << m_customEdits.size();
    
    fieldsLayout->addStretch();
}

void TitleInscriptionsDialog::createImagePreview()
{
    qDebug() << "TitleInscriptionsDialog::createImagePreview: Создаем предварительный просмотр изображения";
    // Загружаем изображение из ресурсов
    QPixmap pixmap(":/assets/Title.PNG");
    if (pixmap.isNull()) {
        qDebug() << "TitleInscriptionsDialog::createImagePreview: Не удалось загрузить изображение Title.PNG";
        return;
    }
    
    m_imageItem = m_imageScene->addPixmap(pixmap);
    m_imageScene->setSceneRect(m_imageItem->boundingRect());
    
    // Устанавливаем начальный масштаб
    m_imageView->fitInView(m_imageItem, Qt::KeepAspectRatio);
    qDebug() << "TitleInscriptionsDialog::createImagePreview: Предварительный просмотр создан, размер изображения:" << pixmap.size();
}

void TitleInscriptionsDialog::onComboBoxChanged(int fieldNumber, const QString &value)
{
    QComboBox *comboBox = m_comboBoxes[fieldNumber];
    QLineEdit *customEdit = m_customEdits[fieldNumber];
    
    qDebug() << "TitleInscriptionsDialog::onComboBoxChanged: Поле" << fieldNumber << "комбобокс изменен на:" << value;
    
    if (value == "custom") {
        // Показываем поле для кастомного значения
        customEdit->setVisible(true);
        customEdit->setFocus();
        // Очищаем значение поля, так как теперь оно кастомное
        updateFieldValue(fieldNumber, "");
    } else {
        // Скрываем поле для кастомного значения
        customEdit->setVisible(false);
        customEdit->clear();
        
        // Обновляем значение поля
        updateFieldValue(fieldNumber, value);
    }
}

void TitleInscriptionsDialog::onCustomValueChanged(int fieldNumber, const QString &value)
{
    qDebug() << "TitleInscriptionsDialog::onCustomValueChanged: Поле" << fieldNumber << "кастомное значение изменено на:" << value;
    updateFieldValue(fieldNumber, value);
}

void TitleInscriptionsDialog::updateFieldValue(int fieldNumber, const QString &value)
{
    if (m_fields.contains(fieldNumber)) {
        QString oldValue = m_fields[fieldNumber].currentValue;
        m_fields[fieldNumber].currentValue = value;
        m_fields[fieldNumber].isCustom = (m_comboBoxes[fieldNumber]->currentText() == "custom");
        
        qDebug() << "TitleInscriptionsDialog::updateFieldValue: Поле" << fieldNumber 
                 << "изменено с" << oldValue << "на" << value 
                 << "(кастомное:" << m_fields[fieldNumber].isCustom << ")";
    } else {
        qDebug() << "TitleInscriptionsDialog::updateFieldValue: Поле" << fieldNumber << "не найдено в m_fields";
    }
}

void TitleInscriptionsDialog::onZoomChanged(int value)
{
    qreal scale = value / 100.0;
    m_imageView->setTransform(QTransform::fromScale(scale, scale));
    qDebug() << "TitleInscriptionsDialog::onZoomChanged: Масштаб изменен на" << value << "% (коэффициент:" << scale << ")";
}

void TitleInscriptionsDialog::onAccept()
{
    qDebug() << "TitleInscriptionsDialog::onAccept: Принимаем диалог, собираем значения для сохранения";
    QMap<int, QString> values = getInscriptionValues();
    qDebug() << "TitleInscriptionsDialog::onAccept: Готово к сохранению" << values.size() << "значений";
    accept();
}

void TitleInscriptionsDialog::onCancel()
{
    qDebug() << "TitleInscriptionsDialog::onCancel: Отменяем диалог, изменения не сохраняются";
    reject();
}

QMap<int, QString> TitleInscriptionsDialog::getInscriptionValues() const
{
    QMap<int, QString> values;
    qDebug() << "TitleInscriptionsDialog::getInscriptionValues: Собираем значения из" << m_fields.size() << "полей";
    
    int nonEmptyCount = 0;
    for (auto it = m_fields.begin(); it != m_fields.end(); ++it) {
        QString fieldValue = it.value().currentValue;
        values[it.key()] = fieldValue;
        if (!fieldValue.isEmpty()) {
            qDebug() << "TitleInscriptionsDialog::getInscriptionValues: Поле" << it.key() << "=" << fieldValue;
            nonEmptyCount++;
        }
    }
    
    qDebug() << "TitleInscriptionsDialog::getInscriptionValues: Возвращаем" << values.size() << "значений, из них непустых:" << nonEmptyCount;
    return values;
}

void TitleInscriptionsDialog::setInscriptionValues(const QMap<int, QString> &values)
{
    qDebug() << "TitleInscriptionsDialog::setInscriptionValues: Устанавливаем" << values.size() << "значений";
    
    int nonEmptyCount = 0;
    for (auto it = values.begin(); it != values.end(); ++it) {
        int fieldNumber = it.key();
        QString value = it.value();
        
        if (!value.isEmpty()) {
            nonEmptyCount++;
            qDebug() << "TitleInscriptionsDialog::setInscriptionValues: Устанавливаем поле" << fieldNumber << "=" << value;
        }
        
        if (m_fields.contains(fieldNumber)) {
            m_fields[fieldNumber].currentValue = value;
            
            // Обновляем комбобокс
            if (m_comboBoxes.contains(fieldNumber)) {
                QComboBox *comboBox = m_comboBoxes[fieldNumber];
                
                // Ищем значение в списке параметров проекта
                int index = comboBox->findData(value);
                if (index >= 0) {
                    comboBox->setCurrentIndex(index);
                    qDebug() << "TitleInscriptionsDialog::setInscriptionValues: Найдено в комбобоксе, индекс" << index;
                } else if (!value.isEmpty()) {
                    // Если значение не найдено, устанавливаем кастомное
                    comboBox->setCurrentText("custom");
                    if (m_customEdits.contains(fieldNumber)) {
                        m_customEdits[fieldNumber]->setText(value);
                        m_customEdits[fieldNumber]->setVisible(true);
                        qDebug() << "TitleInscriptionsDialog::setInscriptionValues: Установлено кастомное значение";
                    }
                }
            } else {
                qDebug() << "TitleInscriptionsDialog::setInscriptionValues: Комбобокс для поля" << fieldNumber << "не найден";
            }
        } else {
            qDebug() << "TitleInscriptionsDialog::setInscriptionValues: Поле" << fieldNumber << "не найдено в m_fields";
        }
    }
    
    qDebug() << "TitleInscriptionsDialog::setInscriptionValues: Установлено" << nonEmptyCount << "непустых значений";
}

void TitleInscriptionsDialog::setTitleInscriptionsModel(TitleInscriptionsModel *model)
{
    qDebug() << "TitleInscriptionsDialog::setTitleInscriptionsModel: Устанавливаем модель надписей:" << (model ? "доступна" : "nullptr");
    m_titleInscriptionsModel = model;
}

TitleInscriptionsModel* TitleInscriptionsDialog::getTitleInscriptionsModel() const
{
    qDebug() << "TitleInscriptionsDialog::getTitleInscriptionsModel: Возвращаем модель надписей:" << (m_titleInscriptionsModel ? "доступна" : "nullptr");
    return m_titleInscriptionsModel;
}

 