#include <tc/tc.h>
#include "epm_handler_common.h"
#include <ict/ict_userservice.h>
#include <tccore/custom.h>
#include <epm/epm_toolkit_tc_utils.h>
#include <tccore/aom.h>
#include <tccore/aom_prop.h>
#include <tccore/item.h>
#include <bom/bom.h>
#include "ps/ps.h";
#include "ps/vrule.h"
#include "sstream"
#include <tccore/grm.h>
#include "epm/epm.h"
#include "sa/sa.h"
#include "libxl.h"
#include <map>
#include "epm/signoff.h"
#include <ctime>
#include <vector>
#include <locale>
#include <codecvt>
#include "ae/dataset.h"
#include <iostream>
#include <stdlib.h>
#include <tccore/aom.h>
#include <tc/emh.h>
#include <ict/ict_userservice.h>
#include <tc/tc.h>
#include <tccore/tctype.h>
#include <sa/tcfile.h>
#include <ss/ss_errors.h>
#include <ae/datasettype.h>
// #include "hx_custom.h"
#include "tc_log.h"
// #include "jk_custom.h"
#include "chint_Handler.h"
#include "tc_util.h"
#include <regex>
#include <ics/ics.h>
#include "ocilib.h"
#include <cfm/cfm.h>
#include <me/me.h>
#include <property/nr.h>
#include <tccore/aom.h>
#include <tccore/item.h>
#include <tccore/workspaceobject.h>
using namespace std;

typedef struct {
	string cpxh;//产品型号 低、中、高、调、稳
	string dyxq;
	string zyxq;
	string gyxq;
	string tyxq;
	string wyxq;
}ByqBean2;
typedef struct {
	string rgsj;//产品型号 低、中、高、调、稳
	string jqsj;
	string zbsj;
	string zrsczq;
}TimeBean2;
typedef struct {
	string temGxCode;
	string temGxName;

}TemGxBean2;
//获取分类属性 判断是否整除
string getClassVal2(tag_t top_rev_tag, string& errMessage, ByqBean2 &bean) {
	//, string className
	tag_t top_classificationObject, item;
	ITKCALL(ITEM_ask_item_of_rev(top_rev_tag, &item));
	ICS_ask_classification_object(item, &top_classificationObject);
	if (top_classificationObject == NULL_TAG)
	{
		errMessage.append("顶层对象没有发送到分类\n");
		return  "";
	}
	char* top_class_id = NULL, *top_class_name = NULL;
	//ICS_ask_class_of_classification_obj(top_classificationObject, &top_class_tag);
	//ICS_ask_id_name(top_class_tag, &top_class_id, &top_class_name);
	printf("BOM TOP LINE CLASS ID = %s | NAME = %s \n", top_class_id, top_class_name);
	int n_attrs;
	char** attr_names;
	char** attr_vals;
	ITKCALL(ICS_ask_attributes_of_classification_obj(top_classificationObject, &n_attrs, &attr_names, &attr_vals));
	cout << n_attrs << endl;
	//	int num = 1;
	string cpxh;
	for (int ii = 0; ii < n_attrs; ii++)
	{
		if (strcmp(attr_names[ii], "产品型号") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				errMessage.append("分类属性产品型号为空，请检查。\n");
				//return "";
			}
			else {
				cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "低压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性低压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.dyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "中压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性中压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.zyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "高压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性高压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.gyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "调压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//errMessage.append("分类属性调压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.tyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		else if (strcmp(attr_names[ii], "稳压线圈绕线方式") == 0) {
			if (strcmp(attr_vals[ii], "") == 0) {
				//	errMessage.append("分类属性稳压线圈绕线方式为空，请检查。\n");
				//return "";
			}
			else {
				bean.wyxq = attr_vals[ii];//cpxh = (attr_vals[ii]);
			}
			//break;
		}
		//五柱铁心
		cout << attr_names[ii] << "\t"
			<< attr_vals[ii] << endl;
	}
	return cpxh;
}
//实体且有BOM往下
boolean isXnj(tag_t matnr) {
	int cnt2, numFac, cnt3;
	boolean flag = false;
	char** procureType, ** factorys, ** specialProcureType;
	AOM_ask_value_strings(matnr, "zt2_SZSpecialProcuretype", &cnt3, &specialProcureType); //为/
	AOM_ask_value_strings(matnr, "zt2_SZProcuretype", &cnt2, &procureType); //包含自制
	AOM_ask_value_strings(matnr, "zt2_SZFactory", &numFac, &factorys);
	for (int i = 0; i < numFac; i++) {
		if (strcmp(factorys[i], "M060") == 0 && cnt2 > i && cnt3 > i) {
			if (strstr(procureType[i], "自制") != NULL && strcmp(specialProcureType[i], "/") == 0) {
				flag = true;
			}
		}
	}
	return flag;
}
string sqlGyRule2 = "select GYID from \"CHINT_WORKHOUR_WhGYRule\" where \"ProductZu\" = '%s' and \"TuHao\" = '%s' and COMPANYCODE ='M060'";
string sqlCpxh2 = "SELECT \"ProductZu\" FROM \"CHINT_WORKHOUR_WhProductXH\" where \"ProductXH\" = '%s' and COMPANYCODE ='M060'";
string sqlGxTime2Nor = "select GXCODE,ARTIFICIALTIME,MACHINETIME,READINESSTIME,\"ProCycle\" from CHINT_WORKHOUR where \"PRODUCTXH\" = '%s' and GYID = '%s' and COMPANYCODE ='M060'";
string sqlGxTime2Xq = "select GXCODE,ARTIFICIALTIME,MACHINETIME,READINESSTIME,\"ProCycle\" from CHINT_WORKHOUR where \"PRODUCTXH\" = '%s' and GYID = '%s' and JSASK = '%s' and COMPANYCODE ='M060'";

void getGxbmMap22(tag_t processTag, map<string, TimeBean2 > timebeans) {
	int bvr_count = 0;
	tag_t ebom_window = NULLTAG;
	tag_t bom_line = NULLTAG;
	tag_t item_tag = NULLTAG, *c_line_tags;
	(BOM_create_window(&ebom_window));
	tag_t* bvr_list = NULL;
	(ITEM_rev_list_bom_view_revs(processTag, &bvr_count, &bvr_list));
	printf("bvr_count=%d", bvr_count);

	(BOM_set_window_top_line_bvr(ebom_window, bvr_list[0], &bom_line)); //顶层bom获取
	//bom_line工艺
	int c_line_count;
	ITKCALL(BOM_line_ask_all_child_lines(bom_line, &c_line_count, &c_line_tags)); // 一级工序

	for (int i = 0; i < c_line_count; i++) {
		tag_t oneGx = c_line_tags[i], *towGxLines;
		char* gxbm1;
		AOM_ask_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm1);
		if (timebeans.count(gxbm1) > 0) {
			AOM_lock(oneGx);
			TimeBean2 tbean = timebeans[gxbm1];
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ArtificialTime", tbean.rgsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_MachineTime", tbean.jqsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ReadinessTime", tbean.zbsj.c_str()));
			ITKCALL(AOM_set_value_string(oneGx, "bl_ZT2_FirstOPRevision_zt2_ProCycle", tbean.zrsczq.c_str()));
			AOM_save(oneGx);
			AOM_unlock(oneGx);
		}
		int c_cnt = 0;
		BOM_line_ask_all_child_lines(oneGx, &c_cnt, &towGxLines);
		for (int j = 0; j < c_cnt; j++) {
			tag_t towGxLine = towGxLines[j];
			tag_t towGx;
			char* gxbm2;
			ITKCALL(AOM_ask_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ClassificationCode", &gxbm2));
			if (timebeans.count(gxbm2) > 0) {
				AOM_lock(towGxLine);
				TimeBean2 tbean = timebeans[gxbm2];
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ArtificialTime", tbean.rgsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_MachineTime", tbean.jqsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ReadinessTime", tbean.zbsj.c_str()));
				ITKCALL(AOM_set_value_string(towGxLine, "bl_ZT2_FirstOPRevision_zt2_ProCycle", tbean.zrsczq.c_str()));
				AOM_save(towGxLine);
				AOM_unlock(towGxLine);
			}
		}
	}
	BOM_save_window(ebom_window);
	BOM_close_window(ebom_window);
}
void updateTime(char* process_item_id, boolean isXq, string productZu, string xqfs, string th,tag_t processTag)
{
	char selectGyId[200];
	if (isXq) {
		sprintf(selectGyId, sqlGxTime2Xq.c_str(), productZu.c_str(), process_item_id, xqfs.c_str());
	}
	else {
		sprintf(selectGyId, sqlGxTime2Nor.c_str(), productZu.c_str(), process_item_id);
	}

	int outputColumn1 = 0, outputValueCount1 = 0;
	char*** outputValue1 = NULL;
	string gyId;
	printf("search3 ===> %s\n", selectGyId);
	map<string, TimeBean2 > beanMap;
	QuerySQLNoInputParam(selectGyId, &outputColumn1, &outputValueCount1, &outputValue1);
	//查询结果
	for (int num = 0; num < outputValueCount1; num++) {
		string gxbm = outputValue1[num][0];
		string rgsj = outputValue1[num][1];
		if (rgsj.rfind(".", 0) == 0) {
			string a = "0";
			rgsj = a.append(rgsj);
			printf("rgsj === >%s\n", rgsj.c_str());
		}
		string jqsj = outputValue1[num][2];
		if (jqsj.rfind(".", 0) == 0) {
			string a = "0";
			jqsj = a.append(jqsj);
			printf("jqsj === >%s\n", jqsj.c_str());
		}
		string zbsj = outputValue1[num][3];
		if (zbsj.rfind(".", 0) == 0) {
			string a = "0";
			zbsj = a.append(zbsj);
			printf("zbsj === >%s\n", zbsj.c_str());
		}
		string zrsczq = outputValue1[num][4];
		if (zrsczq.rfind(".", 0) == 0) {
			string a = "0";
			zrsczq = a.append(zrsczq);
			printf("zrsczq === >%s\n", zrsczq.c_str());
		}
		TimeBean2 bean;
		bean.rgsj = rgsj;
		bean.jqsj = jqsj;
		bean.zbsj = zbsj;
		bean.zrsczq = zrsczq;
		beanMap[gxbm] = bean;
	}
	getGxbmMap22(processTag, beanMap);

	return;
}

void getTmpProcessUp(string cpxh, string th, string& errBuff, boolean isXq, string xqfs, tag_t processTag) {
	char selectCPZ[200], selectGyId[200];
	sprintf(selectCPZ, sqlCpxh2.c_str(), cpxh.c_str());
	int outputColumn = 0, outputValueCount = 0;
	char*** outputValue = NULL;
	string productZu;
	printf("search1\n");
	QuerySQLNoInputParam(selectCPZ, &outputColumn, &outputValueCount, &outputValue);
	printf("search11\n");
	if (outputValueCount == 0) {
		string buffMsg = "";
		buffMsg.append("当前变压器产品型号:").append(cpxh).append(",在数据库表中无对应典型产品族值，请联系管理员维护.\n");
		size_t found = errBuff.find(buffMsg);
		if (found == std::string::npos) {
			errBuff.append(buffMsg);
		}
		//errBuff.append("当前变压器产品型号:").append(cpxh).append(",在数据库表中无对应典型产品族值，请联系管理员维护.\n");
		return;
	}
	for (int j = 0; j < outputValueCount; j++) {
		productZu = outputValue[j][0];
		printf("productZu===>%s\n", productZu.c_str());
	}

	sprintf(selectGyId, sqlGyRule2.c_str(), productZu.c_str(), th.c_str());

	int outputColumn1 = 0, outputValueCount1 = 0;
	char*** outputValue1 = NULL;
	string gyId;
	printf("search2 %s \n", selectGyId);
	QuerySQLNoInputParam(selectGyId, &outputColumn1, &outputValueCount1, &outputValue1);
	if (outputValueCount1 == 0) {
		errBuff.append("图号:").append(th).append("无对应工艺模板ID,请维护后再更新.\n");
		return;
	}
	for (int j = 0; j < outputValueCount1; j++) {
		gyId = outputValue1[j][0];
		printf("gyId===>%s\n", gyId.c_str());
	}
	updateTime((char*)gyId.c_str(), isXq, productZu, xqfs, th, processTag);
	//tag_t clone_tag = clone_process_from_template((char*)gyId.c_str(), isXq, productZu, xqfs, th);
	return;
}

void updateAllProcess(tag_t bom_line, string& errorBuff) {

	int c_line_count = 0;
	char* objName = NULL;
	tag_t mantr = NULLTAG, *c_line_tags = NULLTAG;
	ITKCALL(AOM_ask_value_tag(bom_line, "bl_line_object", &mantr));
	ITKCALL(AOM_ask_value_string(mantr, "object_name", &objName));
	ITKCALL(BOM_line_ask_all_child_lines(bom_line, &c_line_count, &c_line_tags));
	if (c_line_count > 0 && (strstr(objName, "变压器") != NULL || isXnj(mantr))) {
		char* os = NULL;
		ITKCALL(AOM_ask_value_string(mantr, "object_string", &os));
		printf("实体：%s\n", os);
		//检查是否有工艺路线
		int n_references = 0;
		int* levels = 0;
		tag_t* references_tag = NULLTAG;
		char** relation_type_name = NULL;
		//通过引用关系查找到变更单
		ITKCALL(WSOM_where_referenced(mantr, 1, &n_references, &levels, &references_tag, &relation_type_name));
		boolean hasProcess = false;
		char* bl_desc, *itemID;
		ITKCALL(AOM_ask_value_string(mantr, "item_id", &itemID));
		tag_t processTag;
		for (int i = 0; i < n_references; i++)
		{
			char* refType;
			tag_t refTag = references_tag[i];
			ITKCALL(AOM_ask_value_string(refTag, "object_type", &refType));
			if (strcmp(refType, "MEProcessRevision") == 0) {
				hasProcess = true;
				processTag = refTag;
				break;
			}
		}
		if (!hasProcess) {
			errorBuff.append("实体未指派工艺路线,请检查:").append(itemID).append("/").append(objName);
		}
		else {
			printf("objName：%s\n", objName);
			if (strstr(objName, "变压器") != NULL) {
				tag_t *byqRev;
				char *uid;
				int cnt3 = 0;
				ITKCALL(AOM_ask_value_tags(mantr, "TC_Is_Represented_By", &cnt3, &byqRev));
				ByqBean2 bean;
				ITK__convert_tag_to_uid(byqRev[0], &uid);
				printf("objName%s %s\n", objName, uid);
				string cpxh = getClassVal2(byqRev[0], errorBuff, bean);
				printf("cpxh===>%s\n", cpxh.c_str());
				if (strstr(objName, "线圈") == NULL) {
					getTmpProcessUp(cpxh, "1ZDB300000P", errorBuff, false, "", processTag);
					//processTag = getTmpProcessUp(cpxh, "1ZDB300000P", errorBuff, tmpGyId, false, "");
				}
			}
			else {
				ITKCALL(AOM_ask_value_string(bom_line, "bl_rev_object_desc", &bl_desc));
				printf("bl_rev_object_desc：%s\n", bl_desc);
				vector<string> descVec1;
				Split(bl_desc, " ", descVec1);
				if (descVec1.size() > 1) {
					string drawNos = descVec1[1];
					vector<string> drawNoVec1;
					Split(drawNos, "-", drawNoVec1);
					if (drawNoVec1.size() > 1) {
						string wordNo = drawNoVec1[1]; //工程号 拼接1ZDB300000P 查找分类属性
						string drawNo = drawNoVec1[0]; //图号
						if (drawNoVec1.size() == 3) {
							drawNo = drawNoVec1[0].append("-").append(drawNoVec1[1]);
							wordNo = drawNoVec1[2];
						}
						printf("drawNo：%s，%s\n", drawNo, wordNo);
						string byqId = "1ZDB300000P-", tmpGyId;
						tag_t byqTag, byqRev;
						byqId.append(wordNo);
						ITKCALL(ITEM_find_item(byqId.c_str(), &byqTag));
						ITKCALL(ITEM_ask_latest_rev(byqTag, &byqRev));
						ByqBean2 bean;
						string cpxh = getClassVal2(byqRev, errorBuff, bean);
						printf("cpxh===>%s\n", cpxh.c_str());
						//获取查询模板
						if (strstr(objName, "线圈") == NULL) {
							getTmpProcessUp(cpxh, drawNo, errorBuff, false, "", processTag);
						}
						else {
							string xqfs;
							if (strstr(objName, "低压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.dyxq.empty()) {
									errorBuff.append("当前低压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.dyxq;
							}
							else if (strstr(objName, "中压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.zyxq.empty()) {
									errorBuff.append("当前中压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.zyxq;
							}
							else if (strstr(objName, "高压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.gyxq.empty()) {
									errorBuff.append("当前高压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.gyxq;
							}
							else if (strstr(objName, "调压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.tyxq.empty()) {
									errorBuff.append("当前调压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.tyxq;
							}
							else if (strstr(objName, "稳压线圈") != NULL) {
								//当前XXX线圈未在变压器参数表中维护绕线方式分类属性，请前往维护
								if (bean.wyxq.empty()) {
									errorBuff.append("当前稳压线圈未在变压器参数表中维护绕线方式分类属性，请前往维护\n");
									return;
								}
								xqfs = bean.wyxq;
							}
							getTmpProcessUp(cpxh, drawNo, errorBuff, true, xqfs, processTag);
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < c_line_count; i++) {
		tag_t c_line_tag = c_line_tags[i];
		updateAllProcess(c_line_tag, errorBuff);
	}
}

int UpdateWorkTime(void *returnValue)
{
	int ifail = ITK_ok;
	char* sql = NULL, *revUid;
	tag_t designRev;
	ITKCALL(ifail = USERARG_get_string_argument(&revUid));
	ITK__convert_uid_to_tag(revUid, &designRev);
	int bvr_count = 0, c_line_count;
	tag_t ebom_window = NULLTAG;
	tag_t bom_line = NULLTAG;
	tag_t item_tag = NULLTAG, *c_line_tags;
	(BOM_create_window(&ebom_window));
	tag_t* bvr_list = NULL;
	(ITEM_rev_list_bom_view_revs(designRev, &bvr_count, &bvr_list));
	printf("bvr_count=%d", bvr_count);

	(BOM_set_window_top_line_bvr(ebom_window, bvr_list[0], &bom_line)); //顶层bom获取
	string errorBuff;
	//char *bl_desc;
//	AOM_ask_value_string(bom_line, "bl_rev_object_desc", &bl_desc);

	//int n_references = 0;
	//int* levels = 0;
	//tag_t* references_tag = NULLTAG;
	//char** relation_type_name = NULL;
	//通过引用关系查找到变更单
	//ITKCALL(WSOM_where_referenced(designRev, 1, &n_references, &levels, &references_tag, &relation_type_name));
	/*boolean hasProcess = false;
	tag_t processTagTop = NULLTAG;
	for (int i = 0; i < n_references; i++)
	{
		char* refType;
		tag_t refTag = references_tag[i];
		AOM_ask_value_string(refTag, "object_type", &refType);
		if (strcmp(refType, "MEProcessRevision") == 0) {
			hasProcess = true;
			processTagTop = refTag;
			break;
		}
	}*/
	//tag_t meProcess = NULLTAG;
	/*char *objName, *topId;
	AOM_ask_value_string(designRev, "object_name", &objName);
	AOM_ask_value_string(designRev, "item_id", &topId);
	map<string, tag_t> mapByq;

	printf("mapByq===>%d\n", mapByq.size());*/
	//遍历获取工艺路线
	{
		POM_AM__set_application_bypass(true);
		int url_num = 0;
		char** url_vals = NULL;
		PREF_ask_char_values("database_tc", &url_num, &url_vals);
		string url = url_vals[0];
		url.append("/").append(url_vals[2]);

		//map<string,
		printf("url ==> %s \n", url.c_str());
		if (ConnServer(url_vals[3], url_vals[4], (char*)url.c_str()) == -1)
		{
			printf("提示:中间数据表访问失败\n");
			ifail = 1;
		}
		tag_t topProcess = NULLTAG;

		printf("errorBuff==>%s\n", errorBuff.c_str());
		updateAllProcess(bom_line, errorBuff);

		DisConnServer();
		POM_AM__set_application_bypass(false);
	}

	if (errorBuff.empty()) {
		errorBuff = "succ";
	}
	printf("errorBuff==>%s\n", errorBuff.c_str());
	BOM_close_window(ebom_window);
	*((char**)returnValue) = (char*)MEM_alloc((strlen(errorBuff.c_str()) + 1) * sizeof(char));
	tc_strcpy(*((char**)returnValue), errorBuff.c_str());
	return ifail;
}