#include "syscontactthread.h"
#include <tbaseutil/tdataresponse.h>
#include <tbaseutil/tdataparse.h>
#include <tdatabaseutil/tsqlconnectionpoolv2.h>
#include <tdatabaseutil/tsqlqueryv2.h>
#include <tdatabaseutil/tsqlselectorv2.h>

SysContactThread::SysContactThread(QObject *iParent) :
    TopClassThreadAbs(iParent)
{

}

SysContactThread::~SysContactThread()
{

}

void SysContactThread::run()
{
    if (invokeName() == "LOAD_DATA") {
        loadData(invokeParameter().toMap());
    } else if (invokeName() == "SAVE_DATA") {
        saveData(invokeParameter().toMap());
    }
}

void SysContactThread::loadData(QVariantMap iArgMap)
{
    int contactId = iArgMap.value("id").toInt();
    QString type = iArgMap.value("type").toString();
    TDataResponse dataRes;

    TSqlQueryV2 sqlQuery(T_SQLCNT_POOL->getSqlDatabase());
    sqlQuery.begin();
    try {
        TSqlSelectorV2 sqlSelector;
        sqlSelector.setTable("pub_contacts");
        sqlSelector.setField("*");
        QVariantMap formatMap;
        formatMap["tags"] = "array";
        formatMap["category"] = "array";
        formatMap["other_mail"] = "json";
        formatMap["phone"] = "json";
        formatMap["fax"] = "json";
        formatMap["address"] = "json";
        formatMap["other_contact"] = "json";
        formatMap["attr_data"] = "json";
        sqlSelector.setFieldFormat(formatMap);
        sqlSelector.setWhere("id", QVariant(contactId));
        QVariantMap dataMap = sqlQuery.selectMap(sqlSelector);
        if (sqlQuery.lastError().isValid()) {
            throw sqlQuery.lastError();
        }

        if (type != "contact") {
            sqlSelector.clear();
            sqlSelector.setTable("pub_contacts_lnk_related AS RELATED INNER JOIN pub_contacts AS CONTACT ON RELATED.related_id = CONTACT.id");
            sqlSelector.fieldRef() << "RELATED.relation" << "RELATED.related_id" << "CONTACT.name"
                                   << "CONTACT.sex" << "CONTACT.status" << "CONTACT.source"
                                   << "CONTACT.source_serial" << "CONTACT.company" << "CONTACT.department"
                                   << "CONTACT.title" << "CONTACT.remark";
            sqlSelector.setWhere("RELATED.contact_id", contactId);
            sqlSelector.setOrder("RELATED.seq",Qt::AscendingOrder);
            QVariantList contactList = sqlQuery.selectArrayMap(sqlSelector);
            if (sqlQuery.lastError().isValid()) {
                throw sqlQuery.lastError();
            }

            dataMap.insert("CONTACT_RELATED_LIST", contactList);
        }

        sqlQuery.commit();
        dataRes.setData(dataMap);
        setInvokeResult(dataRes.toVariantMap());
        return;
    } catch (const TError &err) {
        dataRes.setError(err);
    } catch (...) {
        dataRes.setErrText(ttr("Unknow Error!"));
    }
    sqlQuery.rollback();
    setInvokeResult(dataRes.toVariantMap());
}

void SysContactThread::saveData(const QVariantMap &iDataMap)
{
    TDataResponse dataRes;

    TSqlQueryV2 sqlQuery(T_SQLCNT_POOL->getSqlDatabase());
    sqlQuery.begin();
    try {
//        TSqlSelectorV2 sqlSelector;
//        sqlSelector.setTable("pub_contacts");
//        sqlSelector.setField("COUNT(1)");
//        sqlSelector.addWhere("name", iDataMap.value("name"));
//        sqlSelector.addWhere("id", iDataMap.value("id"), "!=");
//        int count = sqlQuery.selectCount(sqlSelector);
//        if (count > 0)
//        {
//            throw TError(ttr("'%1' already exists!").arg(iDataMap.value("name").toString()), "ERROR", "ALREADY_EXISTS");
//        }

        /*int id = iDataMap.value("id").toInt();
        QString log = iDataMap.value("log").toString();
        if(id != 0)
        {
            TSqlSelectorV2 sqlSelector;
            sqlSelector.clear();
            sqlSelector.setTable("pub_contacts");
            sqlSelector.setField("log");
            sqlSelector.setWhere("id",id);
            QString oldLog = sqlQuery.selectValue(sqlSelector).toString();
            if(oldLog.isEmpty())
            {
                dataMap.insert("log",log);
            }
            else
            {
                dataMap.insert("log",QString("%1,%2").arg(oldLog).arg(log));
            }
        }
        */

        QVariantMap dataMap = iDataMap;
        QStringList fieldLst = dataMap.keys();
        fieldLst.removeOne("CONTACT_RELATED_LIST");
        fieldLst.removeOne("id");

        TSqlInserterV2 sqlInserter;
        sqlInserter.setTable("pub_contacts");
        sqlInserter.setData(dataMap);
        sqlInserter.setField(fieldLst);
        sqlInserter.setUniqueField("id");
        sqlInserter.setAutoIncrementField("id");

        QVariant contactId = sqlQuery.replaceRow(sqlInserter);
        if (sqlQuery.lastError().isValid()) {
            throw sqlQuery.lastError();
        }

        TSqlDeleterV2 sqlDeleter;
        sqlDeleter.setTable("pub_contacts_lnk_related");
        sqlDeleter.setWhere("contact_id", contactId);
        sqlQuery.deleteRow(sqlDeleter);
        if (sqlQuery.lastError().isValid()) {
            throw sqlQuery.lastError();
        }

        TSqlInserterV2 roleInserter;
        roleInserter.setTable("pub_contacts_lnk_related");
        roleInserter.fieldRef() << "related_id" << "relation" << "contact_id" << "seq";

        int count = dataMap.value("CONTACT_RELATED_LIST").toList().count();
        for (int i = 0 ; i < count; ++i) {
            QVariant role = dataMap.value("CONTACT_RELATED_LIST").toList().at(i);
            QVariantMap roleMap = role.toMap();
            QVariantMap insertMap;
            insertMap.insert("contact_id", contactId.toString());
            insertMap.insert("related_id", roleMap.value("related_id").toString());
            insertMap.insert("relation", roleMap.value("relation").toString());
            insertMap.insert("seq", i);
            roleInserter.setData(insertMap);
            sqlQuery.insertRow(roleInserter);
            if (sqlQuery.lastError().isValid()) {
                throw sqlQuery.lastError();
            }
        }

        sqlQuery.commit();
        dataRes.setData(contactId);
        setInvokeResult(dataRes.toVariantMap());
        return;
    } catch (const TError &err) {
        dataRes.setError(err);
    } catch (...) {
        dataRes.setErrText(ttr("Unknow Error!"));
    }
    sqlQuery.rollback();
    setInvokeResult(dataRes.toVariantMap());
}