//
// Created by Krad on 2021/10/11.
//

#include "SQLHelper.h"
#include <QSqlQuery>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <qdebug.h>
QSqlDatabase* SQLHelper::defaultDatabase= nullptr;
QHash<QString,QSqlQueryModel*>* SQLHelper::cache= new QHash<QString,QSqlQueryModel*>;
bool SQLHelper::Open() {
    if (defaultDatabase) return true;
    defaultDatabase=  new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", "USCTDB"));
    defaultDatabase->setDatabaseName("USCTDB.data");
    return defaultDatabase->open();
}

bool SQLHelper::Open(QSqlDatabase *base) {
    if(base && base != defaultDatabase){
        defaultDatabase = base;
    }
    return defaultDatabase->open();
}

void SQLHelper::Close() {
    for(auto item : cache->values())
    {
        delete item;
    }
    cache->clear();
    if(defaultDatabase->isValid() && defaultDatabase->isOpen())
    {
        defaultDatabase->close();
        delete defaultDatabase;
        defaultDatabase = nullptr;
    }
}

void prepareSQL(QSqlQuery& query,QMap<QString,QVariant>* params)
{
    if (!params) return;
    for (auto key : params->keys())
    {
        query.bindValue(key,params->value(key));
    }
}


QSqlTableModel* SQLHelper::getTable(const QString &tableName) {
    if (cache->contains(tableName)) return (QSqlTableModel*)(*cache)[tableName];
    CenterAlignSqlTableModel *model = new CenterAlignSqlTableModel(nullptr,*defaultDatabase);
    model->setTable(tableName);
    (*cache)[tableName] = model;
    return (QSqlTableModel*)(*cache)[tableName];
}

int SQLHelper::QueryCount(QString sql, QMap<QString,QVariant>* params) {
    QSqlQuery query(*defaultDatabase);
    prepareSQL(query, params);
    if (query.exec(sql))
    {
        query.last();
        return query.at()+1;
    }
    return 0;
}

int SQLHelper::ExecuteNoQuery(QString sql, QMap<QString,QVariant>* params) {
    QSqlQuery query(*defaultDatabase);
    query.prepare(sql);
    prepareSQL(query, params);
    if (query.exec())
    {
        return query.numRowsAffected();
    }
    return 0;
}

void SQLHelper::QueryFirst(QString sql, QMap<QString,QVariant>& result, QMap<QString,QVariant>* params) {
    QSqlQuery query(*defaultDatabase);
    query.prepare(sql);
    prepareSQL(query, params);
    if (query.exec())
    {
        if(query.next())
        {
            for(int i=0; i<query.record().count(); i++)
            {
                result[query.record().fieldName(i)]=query.record().value(i);
            }
        }
    }
}

QSqlQueryModel *SQLHelper::QueryModel(QString queryName, QString sql, QMap<QString, QVariant> *params) {
    if (cache->contains(queryName)) return (*cache)[queryName];
    QSqlQueryModel* model = new QSqlQueryModel;

    QSqlQuery query(*defaultDatabase);
    query.prepare(sql);
    prepareSQL(query, params);
    model->setQuery(query);
    if (model->lastError().isValid()){
        qDebug() << model->lastError();
        delete model;
        return nullptr;
    }
    (*cache)[queryName] = model;
    return model;
}

QSqlQueryModel *SQLHelper::QueryModel(QString queryName) {
    if (cache->contains(queryName)) return (*cache)[queryName];
    return nullptr;
}

void SQLHelper::QueryMap(QString sql, QMap<QString, QVariant> &result, QMap<QString, QVariant> *params) {
    QSqlQuery query(*defaultDatabase);
    query.prepare(sql);
    prepareSQL(query, params);
    if (query.exec())
    {
        while(query.next())
        {
            result[query.record().value(0).toString()]=query.record().value(1);
        }
    }
}
