#include "CivSimulResDbHelper.h"
#include "CivPgDbConnection.h"
#include "CivTypes.h"
#include "CivTableFields.h"
#include "CivCommonUtils.h"

CivSimulResDbHelper::CivSimulResDbHelper(const std::string& uri)
{
	mConn = new CivPgDbConnection();
	mConn->connect(uri);

	NodeResultTableField tableFields;
	mNodeFields =
	{
		"code",
		//tableFields.Number,	
		tableFields.dDemand,	
		tableFields.dPressure,
		tableFields.dQuality,
		tableFields.dHead,
		tableFields.dDate,
		tableFields.dInterval,
		tableFields.dModifyTime,
		tableFields.chlorine
	};

	// 
	PipeResultTableField pipeFields;
	mLinkFileds = {
		"code",
		//pipeFields.szNo,
		pipeFields.dFlow,
		pipeFields.dVelocity,
		pipeFields.dUnitHeadloss,
		pipeFields.dQuality,
		pipeFields.szStatus,
		pipeFields.dDate,
		pipeFields.dInterval,
		pipeFields.dModifyTime,
		pipeFields.chlorine
	};
}

CivSimulResDbHelper::~CivSimulResDbHelper()
{
	mConn->disconnect();
	delete mConn;
}

bool CivSimulResDbHelper::insertNodes(const NodeResultItems& nodeitems)
{
	std::vector<std::vector<std::string>> vecVec;
	std::string condition;
	for (auto iter = nodeitems.begin(); iter != nodeitems.end(); iter++)
	{
		NodeResultItem nodeItem = iter->second;
		
		std::string sn = nodeItem.code;
		std::vector<std::string> vecRes;
		vecRes.push_back("\'" + sn + "\'");
		vecRes.push_back(std::to_string(nodeItem.dDemand));
		vecRes.push_back(std::to_string(nodeItem.dPressure));
		vecRes.push_back(std::to_string(nodeItem.dQuality));
		vecRes.push_back(std::to_string(nodeItem.dHead));
		vecRes.push_back("\'" + nodeItem.dDate + "\'");
		vecRes.push_back("\'" + nodeItem.dTime + "\'");
		vecRes.push_back("\'" + CurrentTime + "\'");
		vecRes.push_back(std::to_string(nodeItem.dChlorine));
		vecVec.push_back(vecRes);
		condition = "\'" + nodeItem.dTime + "\'";
	}

	if (!mConn->del(NODERESULTTABLE, " 时间点 = "+condition))
		return false;

	if (!mConn->insertBulk(NODERESULTTABLE, mNodeFields, vecVec))
		return false;

	return true;
}

bool CivSimulResDbHelper::insertLinks(const LinkResultItems& linkMap)
{
	std::vector<std::vector<std::string>> vecVec;
	std::string condition;
	for (auto iter = linkMap.begin(); iter != linkMap.end(); iter++)
	{
		LinkResultItem linkItem = iter->second;
		std::string sn = linkItem.code;
		std::string status = linkItem.szStatus;
		std::vector<std::string> vecRes;
	
		vecRes.push_back("\'" + sn + "\'");
		vecRes.push_back(std::to_string(linkItem.dFlow));
		vecRes.push_back(std::to_string(linkItem.dVelocity));
		vecRes.push_back(std::to_string(linkItem.dHeadloss));
		vecRes.push_back(std::to_string(linkItem.dQuality));
		vecRes.push_back("\'" + status + "\'");
		vecRes.push_back("\'" + linkItem.dDate + "\'");
		vecRes.push_back("\'" + linkItem.dTime + "\'");
		vecRes.push_back("\'" + CurrentTime + "\'");
		vecRes.push_back(std::to_string(linkItem.dChlorine));
	
		vecVec.push_back(vecRes);
		condition = "\'" + linkItem.dTime + "\'";
	}


	if (!mConn->del(PIPERESULTTABLE, " 时间点 = " + condition))
		return false;

	if (!mConn->insertBulk(PIPERESULTTABLE, mLinkFileds, vecVec))
		return false;

	return true;
}

bool CivSimulResDbHelper::insertTanks(const TankResultItems& tankMap)
{
	return true;
}

void CivSimulResDbHelper::getAllNodeCoords(NodeCoords& nodeCoords)
{
	std::vector<std::string> fileds = {
		"本点号","横坐标","纵坐标"
	};

	std::vector<std::map<std::string, std::string>> res;
	if (!mConn->query(PIPENODE, fileds, res))
		return;

	size_t total = res.size();
	for (int i = 0; i < total; i++)
	{
		std::map<std::string, std::string> nodeInfo = res[i];
		NodeCoord nodeCoord;

		std::string key = nodeInfo.find(fileds[0])->second;	
		nodeCoord.xCoord = nodeInfo.find(fileds[1])->second;
		nodeCoord.yCoord = nodeInfo.find(fileds[2])->second;

		nodeCoords[key] = nodeCoord;
	}

}

void CivSimulResDbHelper::getAllPipeCoords(PipeCoords& pipeCoords)
{
	std::vector<std::string> fileds = {
		"ST_X(ST_StartPoint(ST_GeometryN(geom,1))) as startx",
		"ST_Y(ST_StartPoint(ST_GeometryN(geom,1))) as starty", 
		"ST_X(ST_EndPoint(ST_GeometryN(geom,1))) as endX" ,
		"ST_Y(ST_EndPoint(ST_GeometryN(geom,1))) as endY",
		"编号"
	};

	std::vector<std::map<std::string, std::string>> res;
	if (!mConn->query(PIPELINE, fileds, res))
		return;

	size_t total = res.size();
	for (int i = 0; i < total; i++)
	{
		std::map<std::string, std::string> nodeInfo = res[i];
		PipeCoord pipeCoord;
		
		std::string key = nodeInfo.find("编号")->second;
		pipeCoord.startX = nodeInfo.find("startx")->second;
		pipeCoord.startY = nodeInfo.find("starty")->second;
		pipeCoord.endX = nodeInfo.find("endx")->second;
		pipeCoord.endY = nodeInfo.find("endy")->second;
		pipeCoords[key] = pipeCoord;
	}
}

void CivSimulResDbHelper::getLinCodeSnMap(std::map<std::string, std::string>& map)
{
	std::vector<std::string> fileds = {
		"\"编号\"",
		"\"code\""
	};

	std::vector<std::map<std::string, std::string>> res;
	if (!mConn->query(PIPELINE, fileds, res))
		return;

	size_t total = res.size();
	for (int i = 0; i < total; i++)
	{
		std::map<std::string, std::string> nodeInfo = res[i];
		PipeCoord pipeCoord;

		std::string sn = nodeInfo.find("编号")->second;
		std::string code = nodeInfo.find("code")->second;
		map[sn] = code;
	}
}

void CivSimulResDbHelper::getNodeCodeSnMap(std::map<std::string, std::string>& map)
{
	std::vector<std::string> fileds = {
		"\"本点号\"",
		"\"code\""
	};

	std::vector<std::map<std::string, std::string>> res;
	if (!mConn->query(PIPENODE, fileds, res))
		return;

	size_t total = res.size();
	for (int i = 0; i < total; i++)
	{
		std::map<std::string, std::string> nodeInfo = res[i];
		PipeCoord pipeCoord;

		std::string sn = nodeInfo.find("本点号")->second;
		std::string code = nodeInfo.find("code")->second;
		map[sn] = code;
	}
}