#include "CivInpHelperAbs.h"
#include "CivConnection.h"
#include "CivPgDbConnection.h"
#include "CivTableFields.h"
#include "StringUtils.h"

CivInpHelperAbs::CivInpHelperAbs(const std::string& uri)
{
	mDbConn = new CivPgDbConnection();
	mDbConn->connect(uri);
	mQualityType = Age;
}

CivInpHelperAbs::~CivInpHelperAbs()
{
	mDbConn->disconnect();
	delete mDbConn;
}

bool CivInpHelperAbs::getEmitters(CivEmitters& emitter)
{
	return true;
}

bool CivInpHelperAbs::getMixing(CivMixing& mixing)
{
	return true;
}

bool CivInpHelperAbs::getParameter(std::vector<CivParameter>& params)
{
	ParametorTable restemTable;

	std::vector<std::string> fields = {
		 restemTable.name,
		 restemTable.val,
		 restemTable.type
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(OPTIONTTABLE, fields, resultVector);

	std::map<std::string, std::vector<CivParameter::ParamTable>> tempMap;
	for (int i = 0; i < resultVector.size(); i++)
	{
		CivParameter::ParamTable pTable;
		std::map<std::string, std::string> map = resultVector[i];
		pTable.name = map.find(fields[0])->second;
		pTable.val = map.find(fields[1])->second;

		std::string type = map.find(fields[2])->second;
		tempMap[type].push_back(pTable);
	}

	// 遍历临时存储的数据拼接参数对象
	for (auto iter = tempMap.begin(); iter != tempMap.end(); iter++)
	{
		CivParameter param;
		std::string type = iter->first;
		std::vector<CivParameter::ParamTable> paramTables = iter->second;

		param.setType(type);

		size_t total = paramTables.size();
		for (int i = 0; i < total; i++)
			param.addItem(paramTables[i]);

		params.push_back(param);
	}

	return true;
}

bool CivInpHelperAbs::getPatterns(CivPatterns& patterns)
{
	//延时不需要需水量模式
	if (!isDelayTime)
	{
		convertPatterns();
		return true;
	}
		

	PatternTable patternTable;

	std::vector<std::string> fields = {
		patternTable.modelName,
		patternTable.modelData,
		patternTable.modelType
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(PATTERNTABLE, fields, resultVector);

	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		std::map<std::string, std::string> map = resultVector[i];
		CivPatterns::PatternTable pTable;

		pTable.name = map.find(fields[0])->second;
		pTable.val = map.find(fields[1])->second;

		patterns.addItem(pTable);
	}

	return true;
}

bool CivInpHelperAbs::getCurves(CivCurves& curves)
{
	CurveTable curveTable;

	std::vector<std::string> fields = {
		curveTable.CurveName,
		curveTable.CurveType,
		curveTable.CurveData
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(CURVETABLE, fields, resultVector);

	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		CivCurves::CurvesTable cTable;
		std::map<std::string, std::string> map = resultVector[i];

		cTable.ID = map.find(fields[0])->second;
		cTable.XCoord = map.find(fields[1])->second;
		cTable.YCoord = map.find(fields[2])->second;

		curves.addItem(cTable);
	}

	return true;
}

bool CivInpHelperAbs::getDemands(CivDemands& demands)
{
	return true;
}

bool CivInpHelperAbs::getSources(CivSources& sources)
{
	return true;
}

bool CivInpHelperAbs::getLabels(CivLabels& labels)
{
	return true;
}

bool CivInpHelperAbs::getTags(CivTags& tags)
{
	return true;
}

void CivInpHelperAbs::getSnToCode(std::map<std::string, std::string>& coord)
{
	JunctionTable nodeTable;

	std::vector<std::string> fields = {
		nodeTable.sn,
		nodeTable.code
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(PIPENODE, fields, resultVector);
	mDbConn->query(TANK, fields, resultVector);
	mDbConn->query(RESIVOIR, fields, resultVector);

	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		CivCoordinates::CoordTable coordTable;
		std::map<std::string, std::string> map = resultVector[i];

		std::string sn = map.find(nodeTable.sn)->second;
		std::string code  = map.find(nodeTable.code)->second;
		

		coord.insert(std::pair<std::string, std::string>(sn,code));
	}

	
}

void CivInpHelperAbs::setQualityType(QualityType qualiType)
{
	mQualityType = qualiType;
}

void CivInpHelperAbs::setPatternTime(std::string time)
{
	std::vector<std::string> vec;
	StringUtils::split(time, vec);

	if (vec.size() < 2)
		return;

	std::string pattern = vec[1];

	std::vector<std::string> timeVec;
	StringUtils::split(pattern, timeVec, ":");

	if (timeVec.size() < 3)
		return;

	std::string timetemp = timeVec[0];
	mPatternTime = std::atoi(timetemp.c_str());
}

void CivInpHelperAbs::convertPatterns()
{
	PatternTable patternTable;

	std::vector<std::string> fields = {
		patternTable.modelName,
		patternTable.modelData,
	};

	std::vector<std::map<std::string, std::string>> resultVector;
	mDbConn->query(PATTERNTABLE, fields, resultVector);

	size_t totals = resultVector.size();
	for (int i = 0; i < totals; i++)
	{
		std::map<std::string, std::string> map = resultVector[i];
		CivPatterns::PatternTable pTable;

		std::string name = map.find(patternTable.modelName)->second;
		std::string val = map.find(patternTable.modelData)->second;

		// 解析模式
		std::vector<std::string> res;
		StringUtils::split(val, res);
		mPatterns.insert(std::pair<std::string, std::vector<std::string>>(name, res));
	}
}

void CivInpHelperAbs::isDelayTimeSimul(bool isDelay)
{
	isDelayTime = isDelay;
}

void CivInpHelperAbs::handleDelayPattern(const std::string& demand, const std::string& patternID, std::string& destDemand, std::string& pattern)
{
	// 是否做延时模拟
	if (isDelayTime)
	{
		destDemand = demand;
		pattern = patternID;
	}
	else
	{
		auto iter = mPatterns.find(patternID);
		if (iter != mPatterns.end())
		{
			std::vector<std::string> mulitiers = iter->second;
			if (mPatternTime > mulitiers.size())
				mPatternTime = mulitiers.size() - 1;

			if (mPatternTime < 0)
				mPatternTime = 0;

			std::string mulitier = mulitiers[mPatternTime];

			float intMul = std::atof(mulitier.c_str());
			float dem = std::atof(demand.c_str());

			destDemand = std::to_string(dem * intMul);
		}
	}
}