#include "modelInfoEditDialog.h"
#include "./ui_modelInfoEditDialog.h"
#include "mainwindow.h"
#include "sqlQueryExecutor.h"
#include <QRegularExpressionValidator>
#include <QSqlDatabase>
#include <QSqlQuery>

#define itemRole_groupID 1
#define itemRole_isPublic 2

ModelInfoEditDialog::ModelInfoEditDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::ModelInfoEditDialog)
    , m_pMainWindow(nullptr)
{
    ui->setupUi(this);
    initialize();
}

ModelInfoEditDialog::~ModelInfoEditDialog()
{
    delete ui;
}

void ModelInfoEditDialog::showEvent(QShowEvent* e)
{
    refreshGroupList();
    if(m_state == DS_New)
    {
        resetUI();
    }
    else //获取指定Model信息
    {

    }
}

void ModelInfoEditDialog::initialize()
{
    m_state = DS_New;
    m_curModelID = -1;
    ui->btnAddGroup->setVisible(false);
    //正则表达式，只能属于字母
    QRegularExpression regExp("[A-Za-z0-9]+");
    QRegularExpressionValidator* validator = new QRegularExpressionValidator(regExp, this);
    ui->lineEdit_modelType->setValidator(validator);

    connect(ui->btnSave, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_save);
    connect(ui->btnCancle, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_cancle);
    connect(ui->btnAddGroup, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_addGroup);
    connect(ui->btnRemoveSelected, &QPushButton::clicked, this, &ModelInfoEditDialog::onBtnClicked_removeSelected);

    connect(ui->sourceList, &QListWidget::itemDoubleClicked, this, &ModelInfoEditDialog::onItemDblCliked_sourceList);
}

void ModelInfoEditDialog::resetUI()
{
    ui->tabWidget->setCurrentIndex(0);
    ui->tabWidget->setCurrentIndex(0);
    ui->lineEdit_modelName->setText("");
    ui->lineEdit_modelType->setText("");
    ui->plainTextEdit_modelComment->setPlainText("");
    ui->label_error->setText("");
}

void ModelInfoEditDialog::refreshGroupList()
{
    if(m_pMainWindow)
    {
        ui->sourceList->clear();
        ui->selectedList->clear();
        if(!m_pMainWindow)
            return;
        QString connection = m_pMainWindow->getCurConnection();
        //考虑写一个专门用来返回相关数据的类，可以减少多处调用同样SQL语句的状况，也可以避免SQL语句变更时需要更改同步多处
        const QVector<AttributeGroup> groups = SqlQueryExecutor::instance().getAttributeGroup(connection);
        for(const AttributeGroup& group : groups)
        {
            QListWidgetItem* sourceItem = new QListWidgetItem(group.name);
            sourceItem->setFlags(sourceItem->flags() & ~Qt::ItemIsEditable);
            sourceItem->setData(Qt::UserRole + itemRole_groupID, group.id);
            sourceItem->setData(Qt::UserRole + itemRole_isPublic, group.isPublic);
            ui->sourceList->addItem(sourceItem);
            if(group.isPublic)
            {
                QListWidgetItem* selectedItem = new QListWidgetItem(*sourceItem);
                //selectedItem->setIcon(QIcon(":/img/images/icon_no.png"));
                selectedItem->setForeground(QBrush(QColor(128,128,128)));
                ui->selectedList->addItem(selectedItem);
            }
        }
    }
}

void ModelInfoEditDialog::setErrorInfo(const QString& info)
{
    if(m_pMainWindow)
        m_pMainWindow->showMessageDialog(type_warning, QString::fromWCharArray(L"错误"),info);
    else
        ui->label_error->setText(info);
}

void ModelInfoEditDialog::setMainWindow(MainWindow* window)
{
    m_pMainWindow = window;
}

void ModelInfoEditDialog::onItemDblCliked_sourceList(QListWidgetItem* item)
{
    if(item->data(Qt::UserRole + itemRole_isPublic).toBool())
        return;

    QList<QListWidgetItem*> foundItems = ui->selectedList->findItems(item->text(), Qt::MatchFixedString);
    if(foundItems.isEmpty())
    {
        QListWidgetItem* selectedItem = new QListWidgetItem(*item);
        ui->selectedList->addItem(selectedItem);
    }
}

void ModelInfoEditDialog::onBtnClicked_save()
{
    if(ui->lineEdit_modelName->text() == "" || ui->lineEdit_modelType->text() == "")
    {
        setErrorInfo(QString::fromWCharArray(L"除‘备注’外不能有信息为空"));
        return;
    }

    QString modelName = ui->lineEdit_modelName->text();
    QString modeType = ui->lineEdit_modelType->text();
    QString remark = ui->plainTextEdit_modelComment->toPlainText();
    QVector<int> groups;
    for(int i = 0; i < ui->selectedList->count(); i++)
    {
        QListWidgetItem* item = ui->selectedList->item(i);
        groups.append(item->data(Qt::UserRole + itemRole_groupID).toInt());
    }

    if(!m_pMainWindow)
    {
        setErrorInfo(QString::fromWCharArray(L"无法获取当前数据库链接"));
        resetUI();
        return;
    }

    //先判断是否存在同名
    QString connection = m_pMainWindow->getCurConnection();
    bool nameExists = SqlQueryExecutor::instance().modelNameExistsInDB(connection, modelName);
    if(nameExists)
    {
        setErrorInfo(QString::fromWCharArray(L"已存同名的模型，请修改模型名称"));
        ui->tabWidget->setCurrentIndex(0);
        return;
    }
    else //然后判断类型是否存在相同
    {
        bool typeExists = SqlQueryExecutor::instance().modelTypeExistsInDB(connection, modeType);
        if(typeExists)
        {
            setErrorInfo(QString::fromWCharArray(L"已存同类型的模型，请修改模型类型"));
            ui->tabWidget->setCurrentIndex(0);
            return;
        }
    }
    //插入数据
    Model modle(-1, modelName, modeType, remark, groups);
    bool result = SqlQueryExecutor::instance().addModel(connection, modle);

    if(result)
    {
        emit addModel(modle);
        m_pMainWindow->showMessageDialog(type_question, QString::fromWCharArray(L"成功"),QString::fromWCharArray(L"信息存储完成，是否继续添加模型"));
        if(g_msgDlgBtn == btn_No)
            close();
        else
        {
            resetUI();
            refreshGroupList();
        }
    }
    else
        setErrorInfo(QString::fromWCharArray(L"信息存储失败，详情可见日志文件"));
}

void ModelInfoEditDialog::onBtnClicked_cancle()
{
    close();
}

void ModelInfoEditDialog::onBtnClicked_addGroup()
{
    setErrorInfo(QString::fromWCharArray(L"该功能暂未开放"));
}

void ModelInfoEditDialog::onBtnClicked_removeSelected()
{
    QListWidgetItem* item = ui->selectedList->currentItem();
    if(item && item->data(Qt::UserRole + itemRole_isPublic).toBool())
    {
        setErrorInfo(QString::fromWCharArray(L"该组别为必选组别，不可移除"));
        return;
    }

    int row = ui->selectedList->currentRow();
    item = ui->selectedList->takeItem(row);
    if(item)
        delete item;
}
