package com.cim.idm.mwmsextend.erpinterface.service;

import java.io.ByteArrayOutputStream;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.StringJoiner;

import com.cim.idm.wmsextend.generic.GenericServiceProxy;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.springframework.dao.DataAccessException;

import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.framework.util.time.TimeStampUtil;
import com.cim.idm.framework.util.xml.JdomUtils;
//import com.cim.idm.mwmsextend.customer.service.CustomerServiceImpl;
import com.cim.idm.wmsextend.generic.errorHandler.CustomException;
import com.cim.idm.mwmsextend.generic.util.CommonValidation;
import com.cim.idm.wmsextend.generic.util.SMessageUtil;
import com.cim.idm.mwmsextend.materialpacking.service.MaterialPackingServiceImpl;
import com.cim.idm.mwmsextend.materialpackingstockin.service.MaterialPackingStockInUtil;
import com.cim.idm.mwmsextend.materialpackingstockin.service.MaterialStockInClass;
import com.cim.idm.wmspackage.inbounddeliveryorder.data.InnerRequestDetailInfo;
import com.cim.idm.wmspackage.material.MaterialServiceProxy;
import com.cim.idm.wmspackage.material.management.data.MaterialSpec;
import com.cim.idm.wmspackage.material.management.data.MaterialSpecKey;
import com.cim.idm.wmspackage.materialpacking.MaterialPackingServiceProxy;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPacking;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPackingFromTQMS;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPackingKey;
import com.cim.idm.wmspackage.materialpacking.management.info.MaterialPackingMakeOnHoldInfo;
import com.cim.idm.wmspackage.materialpacking.management.info.SetEventInfo;
import com.cim.idm.wmspackage.materialprocessgroup.MaterialProcessGroupServiceProxy;
import com.cim.idm.wmspackage.materialprocessgroup.management.info.MaterialProcessGroupCreateInfo;
import com.cim.idm.wmspackage.materialreceiverequestact.MaterialReceiveRequestActServiceProxy;
import com.cim.idm.wmspackage.materialshiprequestdetail.management.data.MaterialShipRequestDetail;
import com.cim.idm.wmspackage.materialundo.info.MaterialUnDoinfo;
import com.cim.idm.wmspackage.receiverequestbatch.management.data.MaterialReceiveActKey;
import com.cim.idm.wmspackage.receiverequestdetail.management.data.MaterialReceiveRequestDetail;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;


public class ERPInterfaceServiceImpl {

	private static Log log = LogFactory.getLog(ERPInterfaceServiceImpl.class);

	static String WebUrl = "";
	static String UserName = "";
	static String Password = "";
	static String factory = "B20";
	static String ERPSender=factory+"WMS";

	static String undoIDPath="";
	static String undoIDElement="";
	static String TqmsPath="";
	static String TqmsName="";
	static String TqmsPWD="";

	// 14789 wsdl https://poqscs.boe.com.cn:443/dir/wsdl?p=ic/7efbaf9849473fec8873938741a14261
	static String HK14789Url = "";
	static String HK14789UserName = "";
	static String HK14789Pwd = "";


	/**
	 * 2024.09.26
	 */
	public void QM013(EventInfo eventInfo, String WMS_INSMK, String SEQ,
					  String MATNR, String MEINS,
					  String LGORT, String WERKS,
					  String ZF_BOXID, String ZF_BOXIDNUM, String ZF_NEWBOXID) throws CustomException {
		String siteName = GenericServiceProxy.getConstantMap().SiteName_B20;
		SetEventInfo setEventInfo = new SetEventInfo();

		// 找到相应Box
		MaterialPackingKey keyInfo = new MaterialPackingKey(siteName, ZF_NEWBOXID);
		Map<String, Object> map = new HashMap<>();
		// 非限制
		if (StringUtils.isEmpty(WMS_INSMK)) {
			map.put("packingGrade", "OK");
			map.put("oqaResult", "OK");
			map.put("oqaResultState", "END");
			map.put("messageId", SEQ);
			setEventInfo.setUserColumns(map);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(keyInfo, eventInfo, setEventInfo);
		}
		// 冻结
		else if ("S".equalsIgnoreCase(WMS_INSMK)) {
			map.put("packingGrade", "NG");
			map.put("oqaResult", "NG");
			map.put("oqaResultState", "END");
			map.put("messageId", SEQ);
			setEventInfo.setUserColumns(map);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(keyInfo, eventInfo, setEventInfo);
		}
		// holding
		else if ("H".equalsIgnoreCase(WMS_INSMK)) {
			MaterialPackingMakeOnHoldInfo holdInfo = new MaterialPackingMakeOnHoldInfo();
			MaterialPackingServiceProxy.getMaterialPackingService().makeOnHold(keyInfo, eventInfo, holdInfo);
		}
		// 质检
		else if ("Q".equalsIgnoreCase(WMS_INSMK)) {
			map.put("packingGrade", "");
			map.put("oqaResult", "");
			map.put("oqaResultState", "PREOQA");
			map.put("messageId", SEQ);
			setEventInfo.setUserColumns(map);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(keyInfo, eventInfo, setEventInfo);
		}
	}

	/**
	 * 2024.09.26
	 */
	public Document generateWMSSTOCKSTATEInfo(Document message, String werks, String matnr, String lifnr,
											  String zf_werkstri, List<String> boxs) {

		List<String> boxList=new ArrayList<String>();

		Element root = message.getDocument().getRootElement();
		Element bodyElement = root.getChild("Body");
		Element olditemElement = bodyElement.getChild("item");
		Element boxsElement = olditemElement.getChild("BOXS");
		if(boxsElement != null){

			for(Iterator<?> iterator = boxsElement.getChildren().iterator();iterator.hasNext();){
				Element mpelement = (Element)iterator.next();
				String materialpacking = mpelement.getText();
				boxList.add(materialpacking);
			}

		}

		StringJoiner joiner = new StringJoiner(", ", "IN (", ")");

		for (String value : boxList) {
			joiner.add("'" + value + "'");
		}


		String getSQL=" SELECT\r\n" +
				"	m.ERPFACTORY ,\r\n" +
				"	m.MATERIALSPECNAME ,\r\n" +
				"	m.SUPPLIERNAME ,\r\n" +
				"	m.MATERIALPACKINGNAME ,\r\n" +
				"	m.OQARESULT ,\r\n" +
				"	m.MATERIALQUANTITY ,\r\n" +
				"	m.STOCKSTATE ,\r\n" +
				"	m.HOLDSTATE \r\n" +
				"FROM\r\n" +
				"	MATERIALPACKING m\r\n" +
				"WHERE\r\n" +
				"	m.SITENAME =:SITENAME \r\n" +
				"	AND (:MATERIALSPECNAME IS NULL\r\n" +
				"	OR m.MATERIALSPECNAME =:MATERIALSPECNAME)\r\n" +
				"	AND (:SUPPLIERNAME IS NULL\r\n" +
				"	OR SUPPLIERNAME =:SUPPLIERNAME)\r\n" +
				"	AND  MATERIALPACKINGNAME  "+joiner.toString()+ "  ";
		Map<String, Object> getMap=new HashMap<>();
		getMap.put("SITENAME", werks);
		getMap.put("MATERIALSPECNAME", matnr);
		getMap.put("SUPPLIERNAME", lifnr);
		getMap.put("MATERIALPACKINGNAME", boxList);
		List<Map<String,Object>> sqlResult =IDMFrameServiceProxy.getSqlTemplate()
				.queryForList(getSQL.toString(), getMap);

		if (sqlResult.size()<1) {
			return message;
		}

		org.jdom.Document newMessage = (Document) message.clone();
		Element newroot = newMessage.getDocument().getRootElement();

		newroot.removeChild("Body");
		// MessageName change

		bodyElement.detach();
		Element newbodyElement = new Element("Body");
		newroot.addContent(newbodyElement);

		Element itemElement = new Element("item");
		newbodyElement.addContent(itemElement);

		Element MATNRE = new Element("MATNR");
		MATNRE.setText(matnr);
		itemElement.addContent(MATNRE);

		Element WERKSE = new Element("WERKS");
		WERKSE.setText(werks);
		itemElement.addContent(WERKSE);

		Element LIFNRE = new Element("LIFNR");
		LIFNRE.setText(lifnr);
		itemElement.addContent(LIFNRE);

		Element ZF_WERKSTRI = new Element("ZF_WERKSTRI");
		ZF_WERKSTRI.setText(zf_werkstri);
		itemElement.addContent(ZF_WERKSTRI);


		int ii = sqlResult.size();
		for (int i = 0; i < sqlResult.size(); i++) {
			Map<String,Object> orderMap =  sqlResult.get(i);
			try {
				Element data = new Element("BOXS");

				String MATNR =  sqlResult.get(i).get("MATERIALSPECNAME") == null ? "" : sqlResult.get(i).get("MATERIALSPECNAME") .toString();
				String WERKS  =  sqlResult.get(i).get("ERPFACTORY") == null ? "" : sqlResult.get(i).get("ERPFACTORY").toString();
				String LIFNR =  sqlResult.get(i).get("SUPPLIERNAME")== null ? "": sqlResult.get(i).get("SUPPLIERNAME").toString();
				String MATERIALPACKINGNAME =  sqlResult.get(i).get("MATERIALPACKINGNAME") == null ?  "": sqlResult.get(i).get("MATERIALPACKINGNAME").toString();
				String OQARESULT =  sqlResult.get(i).get("OQARESULT") == null ?  "": sqlResult.get(i).get("OQARESULT").toString();
				String MATERIALQUANTITY =  sqlResult.get(i).get("MATERIALQUANTITY") == null ?  "": sqlResult.get(i).get("MATERIALQUANTITY").toString();
				String HOLDSTATE =  sqlResult.get(i).get("HOLDSTATE") == null ?  "": sqlResult.get(i).get("HOLDSTATE").toString();
				String STOCKSTATE =  sqlResult.get(i).get("STOCKSTATE") == null ?  "": sqlResult.get(i).get("STOCKSTATE").toString();


				Element ZF_BOXIDE = new Element("ZF_BOXID");
				ZF_BOXIDE.setText(MATERIALPACKINGNAME);
				data.addContent(ZF_BOXIDE);

				Element ZF_BOXIDNUME = new Element("ZF_BOXIDNUM");
				ZF_BOXIDNUME.setText(MATERIALQUANTITY);
				data.addContent(ZF_BOXIDNUME);

				Element ZF_ZKZTE = new Element("ZF_ZKZT");
				ZF_ZKZTE.setText(STOCKSTATE);
				data.addContent(ZF_ZKZTE);


				//库存状态
				Element WMS_INSMKE = new Element("WMS_INSMK");
				if ("Y".equalsIgnoreCase(HOLDSTATE)) {
					WMS_INSMKE.setText("Holding");
				}else if ("NG".equalsIgnoreCase(OQARESULT)) {
					WMS_INSMKE.setText("冻结");
				}else if ("OK".equalsIgnoreCase(OQARESULT)) {
					WMS_INSMKE.setText("非限制");
				}
				data.addContent(WMS_INSMKE);
				itemElement.addContent(data);
			} catch (Exception e) {
				e.printStackTrace();
				break;
			}

		}
		//bodyElement.addContent(dataList);
		//newMessage.addContent(bodyElement);
		log.info(newMessage);
		return newMessage;
	}




	public static String erpInterface_WMS02(String invoiceNo,EventInfo eventInfo)throws Exception
	{
		return "";
	}

	public static String erpInterface_WMS05(String invoiceNo,EventInfo eventInfo)throws Exception
	{
		return "";
	}



	public static void updateBSMessageLogUtil(String eventName,String eventTimeKey,String resultcode,String replymessage,String messageid){
		try {
			String sql = "UPDATE BS_ERPMESSAGELOG SET RESULTCODE=:resultcode,RESULTMESSAGE=:resultdata,MESSAGEID=:messageid WHERE SERVERNAME=:serverName AND EVENTNAME=:eventName AND EVENTTIMEKEY=:eventTimeKey";
			Map<String, Object> bindMap = new HashMap<String, Object>();
			bindMap.put("serverName", "ERPsvr");
			bindMap.put("eventName", eventName);
			bindMap.put("eventTimeKey", eventTimeKey);
			bindMap.put("resultcode", resultcode);
			bindMap.put("resultdata", replymessage);
			bindMap.put("messageid", messageid);


			IDMFrameServiceProxy.getSqlTemplate().update(sql, bindMap);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void insertSAPMessageLogUtil(String eventName,String eventTimeKey,String resultcode,String requestMessage,String messageid,String eventUser,String receiveActNo,String replyMessage,String receiveRequestName,String shipRequestName,String failMessage,String siteName){
		try {
			String sql = "INSERT INTO BS_SAPMESSAGELOG(MESSAGEID, EVENTNAME, EVENTTIMEKEY, EVENTUSER, MESSAGELOG,RECEIVEACTNO,RESULTMESSAGE,RESULTCODE,RECEIVEREQUESTNAME,SHIPREQUESTNAME,FAILMESSAGE,SITENAME,REPEATCOUNT) "
					+ "VALUES(:messageID, :eventName, :eventTimeKey, :eventUser, :messageLog, :receiveActNo, :replyMessage, :resultcode,:receiveRequestName,:shipRequestName,:failMessage,:siteName,:REPEATCOUNT)";
			Map<String, Object> bindMap = new HashMap<String, Object>();
			bindMap.put("messageID", messageid);
			bindMap.put("eventName", eventName);
			bindMap.put("eventTimeKey", eventTimeKey);
			bindMap.put("eventUser", eventUser);
			bindMap.put("messageLog", requestMessage);
			bindMap.put("receiveActNo", receiveActNo);
			bindMap.put("resultcode", resultcode);
			bindMap.put("replyMessage", replyMessage);
			bindMap.put("receiveRequestName", receiveRequestName);
			bindMap.put("shipRequestName", shipRequestName);
			bindMap.put("failMessage", failMessage);
			bindMap.put("siteName", siteName);
			bindMap.put("REPEATCOUNT", 0);
			IDMFrameServiceProxy.getSqlTemplate().update(sql, bindMap);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
	}

	public static void updateSAPMessageLogUtil(String eventName,String eventTimeKey,String resultcode,String messageid,String replyMessage){
		try {


			String sql = "UPDATE BS_SAPMESSAGELOG SET RESULTCODE=:resultcode,RESULTMESSAGE=:replyMessage  WHERE MESSAGEID=:messageID AND EVENTNAME=:eventName AND EVENTTIMEKEY=:eventTimeKey";
			Map<String, Object> bindMap = new HashMap<String, Object>();
			bindMap.put("messageID", messageid);
			bindMap.put("eventName", eventName);
			bindMap.put("eventTimeKey", eventTimeKey);
			//bindMap.put("eventUser", eventUser);
			//bindMap.put("receiveActNo", receiveActNo);
			bindMap.put("resultcode", resultcode);
			bindMap.put("replyMessage", replyMessage);
			IDMFrameServiceProxy.getSqlTemplate().update(sql, bindMap);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
	}
	public static void updateUndoInfo(String unDoId,String messageID,String SEQ,String unDoDetailName,String newMessageID){
		try {
			String sql = "UPDATE BS_MATERIALPACKINGUNDOINFO SET UNDOID=:unDoId,UNDODETAILNAME=:unDoDetailName,PREUNDOID=:PREUNDOID WHERE UNDOID=:messageID AND UNDODETAILNAME=:SEQ";
			Map<String, Object> bindMap = new HashMap<String, Object>();
			bindMap.put("unDoId", unDoId);
			bindMap.put("unDoDetailName", unDoDetailName);
			bindMap.put("messageID", messageID);
			bindMap.put("SEQ", messageID+SEQ.substring(15));
			bindMap.put("PREUNDOID", messageID);
			IDMFrameServiceProxy.getSqlTemplate().update(sql, bindMap);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
	}
	public static void updateprocessGroupName(String unDoId,String messageID,String SEQ,String unDoDetailName,String newMessageID,String processGroupName,String siteName){
		try {
			String sql = "UPDATE MATERIALPACKING SET UNDOID=:unDoId,UNDODETAILNAME=:unDoDetailName,MATERIALPROCESSGROUPNAME=:processGroupName,MESSAGEID=:newMessageID WHERE MESSAGEID=:messageID AND UNDODETAILNAME=:SEQ";
			Map<String, Object> bindMap = new HashMap<String, Object>();
			bindMap.put("unDoId", unDoId);
			bindMap.put("unDoDetailName", unDoDetailName);
			bindMap.put("messageID", messageID);
			bindMap.put("SEQ", messageID+SEQ.substring(15));
			bindMap.put("processGroupName", processGroupName);
			bindMap.put("newMessageID", newMessageID);
			IDMFrameServiceProxy.getSqlTemplate().update(sql, bindMap);
			String sql1 =" SELECT MATERIALPROCESSGROUPNAME FROM MATERIALPROCESSGROUP WHERE  MATERIALPROCESSGROUPNAME =:MATERIALPROCESSGROUPNAME ";

			Map<String, Object> bindMap1 = new HashMap<String, Object>();
			bindMap1.put("MATERIALPROCESSGROUPNAME", processGroupName);
			List<Map<String, Object>> queryResult = IDMFrameServiceProxy
					.getSqlTemplate()
					.queryForList(sql1, bindMap1);
			if(queryResult==null||queryResult.size()<0){
				MaterialProcessGroupCreateInfo mpg = new MaterialProcessGroupCreateInfo();
				mpg.setSiteName(siteName);
				mpg.setMaterialProcessGroupName(processGroupName);
				mpg.setContentMaterialType("");
				mpg.setProcessGroupState(GenericServiceProxy
						.getConstantMap().OQA_State_Pre);
				EventInfo eventInfo=new EventInfo();
				eventInfo.setEventName("GetPIReturn");
				MaterialProcessGroupServiceProxy
						.getMaterialProcessGroupService().create(
								eventInfo, mpg);
			}
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
	}
	//瓒呮椂杩囪处鍐嶆鍙戦?佹垚鍔熷悗鏇存柊 hf
	public static void updateMaterialPacking(String unDoId, String messageID,
											 String SEQ, String unDoDetailName, String newMessageID,
											 String siteName) {

		String sql = "UPDATE MATERIALPACKING SET UNDOID=:unDoId,UNDODETAILNAME=:unDoDetailName,MESSAGEID=:newMessageID WHERE MESSAGEID=:messageID AND UNDODETAILNAME=:SEQ";
		Map<String, Object> bindMap = new HashMap<String, Object>();
		bindMap.put("unDoId", unDoId);
		bindMap.put("unDoDetailName", unDoDetailName);
		bindMap.put("messageID", messageID);
		bindMap.put("SEQ", messageID + SEQ.substring(15));
		bindMap.put("newMessageID", newMessageID);
		IDMFrameServiceProxy.getSqlTemplate()
				.update(sql, bindMap);
	}




	public static List<MaterialUnDoinfo> erpInterface_TEST(String shipType,String shipRequestName,String erpEventTime,EventInfo eventInfo,String messageID,String receiveActNo)throws Exception
	{
		List<MaterialUnDoinfo> materialUnDoinfoList=new ArrayList<MaterialUnDoinfo>();
		String newUnDoID="test";
		String newUnDoDetailName="test";
		String seq="test";
		String unDoIdDate="test";
		MaterialUnDoinfo materialUnDoinfo=new MaterialUnDoinfo();
		materialUnDoinfo.setUnDoID(newUnDoID);
		materialUnDoinfo.setUnDoDetailName(newUnDoDetailName);
		materialUnDoinfo.setSeq(seq);
		materialUnDoinfo.setUnDoIdDate(unDoIdDate);
		materialUnDoinfoList.add(materialUnDoinfo);

		return materialUnDoinfoList;
	}






	public void QM013( EventInfo eventInfo,String WMS_INSMK,String SEQ,
					   String MATNR, String MEINS,
					   String LGORT, String WERKS,
					   String ZF_BOXID, String ZF_BOXIDNUM, String ZF_NEWBOXID,String ZF_QNUM,List<Map<String,Object>> returnElement) throws CustomException {
		String siteName= factory;
		SetEventInfo setEventInfo=new SetEventInfo();

		if(!ZF_NEWBOXID.isEmpty())
		{
			ZF_NEWBOXID = ZF_NEWBOXID;
		}else
		{
			ZF_NEWBOXID = ZF_BOXID;
		}

		//找到相应Box
		MaterialPackingKey keyInfo=new MaterialPackingKey(siteName,ZF_NEWBOXID);
		Map<String, Object> map=new HashMap<String, Object>();
		//非限制
		if ("F".equalsIgnoreCase(WMS_INSMK)) {
			map.put("packingGrade", "OK");
			map.put("oqaResult", "OK");
			map.put("oqaResultState", "END");
			map.put("messageId", SEQ);
			setEventInfo.setUserColumns(map);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(keyInfo, eventInfo, setEventInfo);
		}
		//冻结
		else if ("S".equalsIgnoreCase(WMS_INSMK)) {
			map.put("packingGrade", "NG");
			map.put("oqaResult", "NG");
			map.put("oqaResultState", "END");
			map.put("messageId", SEQ);
			setEventInfo.setUserColumns(map);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(keyInfo, eventInfo, setEventInfo);
		}
		//holding
		else if ("H".equalsIgnoreCase(WMS_INSMK)) {
			map.put("HoldState", "Y");
			setEventInfo.setUserColumns(map);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(keyInfo, eventInfo, setEventInfo);
		}
		//质检
		else if ("Q".equalsIgnoreCase(WMS_INSMK)) {
			map.put("packingGrade", "");
			map.put("oqaResult", "");
			map.put("oqaResultState", "PREOQA");
			map.put("messageId", SEQ);
			setEventInfo.setUserColumns(map);
			MaterialPackingServiceProxy.getMaterialPackingService().setEvent(keyInfo, eventInfo, setEventInfo);
		}

	}



}


