package com.cim.idm.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.util.time.TimeStampUtil;
import com.cim.idm.model.ErpMessageLog;
import com.cim.idm.service.NCWService;
import com.cim.idm.util.NCHttpUtil;
import com.cim.idm.wmsextend.generic.util.ConvertUtil;
import com.cim.idm.wmspackage.materialpacking.MaterialPackingServiceProxy;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPacking;
import com.cim.idm.wmspackage.materialpacking.management.data.MaterialPackingKey;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.jdom.Element;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


//@Service
public class NCWServiceImpl implements NCWService {

	@Autowired
	NCHttpUtil ncHttpUtil;

	// 192.168.1.35:8079  NC量产环境
	private static String baseUrl = "http://192.168.1.35:8079/service/ToNCServlet";

	private static String djUrl = "http://192.168.1.30:8079/uapws/rest/nc/api/freezeThaw/freeze";

	private String vbillcode;

	// 其他入
	private static String qtr = "http://192.168.1.30:8079/uapws/rest/nc/api/ortherIn/insert";

	public String qtrNoInvoice(String receiveRequestName, String siteName, String reActo, String user, String commitDate, String opCode) {
		String rcode;
		String rmsg = null;
		String vbillcode = null;
		StringBuffer sql = new StringBuffer();
		sql.append(" ");
		sql.append(" SELECT  'ZK4A'  billtype,'4A-01' iotype, ");
		sql.append(" M2.STOCKORGNO org, T.ERPFACTORY, ");
		sql.append(" 'Y' issign, ");
		sql.append(" T.ERPLOCATION store, ");
		sql.append(" :commitDate billtime, ");
		sql.append(" T.LASTEVENTUSER manager, ");
		sql.append(" T.LASTEVENTUSER maker, ");
		sql.append(" M2.ERPID srcbillid, ");
		sql.append(" 'N' freplenishflag, ");
		sql.append(" M.ERPDETAILID srcbillbid, ");
		sql.append(" T.MATERIALSPECNAME mat, ");
		sql.append(" '1' matversion, ");
		sql.append(" M.MATERIALUNIT unit, ");
		sql.append("  M.MATERIALUNIT astunit, ");
		sql.append(" '1.00/1.00' changerate, ");
		sql.append(" TO_CHAR(T.MAKEDATE, 'YYYY-MM-DD HH24:MI:SS') proddate, ");
		sql.append(" TO_CHAR(T.EXPIRINGDATE, 'YYYY-MM-DD HH24:MI:SS') expdate, ");
		sql.append(" T.CHARGE batchcode, ");
		sql.append(" T.MATERIALQUANTITY num, ");
		sql.append(" T.MATERIALQUANTITY astnum, ");
		sql.append(" TO_CHAR(T.RECEIVETIME, 'YYYY-MM-DD HH24:MI:SS') indate, ");
		sql.append(" T.PHASE jd, ");
		sql.append(" NVL( T.SDK_ID,'~') sdk, ");
		sql.append(" T.LOCATIONNAME loc ");
		sql.append(" FROM MATERIALPACKING T ");
		sql.append(" LEFT JOIN MATERIALRECEIVEREQUESTDETAIL M ");
		sql.append(" ON T.RECEIVEREQUESTNAME = M.RECEIVEREQUESTNAME ");
		sql.append("  AND T.RECEIVEREQUESTDETAILNAME = M.RECEIVEREQUESTDETAILNAME ");
		sql.append(" LEFT JOIN MATERIALRECEIVEREQUEST M2 ");
		sql.append("  ON T.RECEIVEREQUESTNAME = M2.RECEIVEREQUESTNAME ");
		sql.append("  LEFT JOIN MATERIALRECEIVEACT M3 ON T.RECEIVEACTNO = M3.RECEIVEACTNO  ");
		sql.append(" WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME ");
		sql.append(" AND T.SITENAME = :SITENAME ");
		sql.append(" AND T.RECEIVEACTNO = :RECEIVEACTNO ");
		sql.append(" AND M3.RECEIVEACTSTATE = 'Created' ");
		Map<String, Object> hashMap = new HashMap<String, Object>();
		hashMap.put("RECEIVEREQUESTNAME", receiveRequestName);
		hashMap.put("SITENAME", siteName);
		hashMap.put("RECEIVEACTNO", reActo);
		hashMap.put("commitDate", commitDate);
		List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql.toString(), hashMap);
		try {
			JSONObject jsonObject2 = new JSONObject(true);
			JSONArray dataArray = new JSONArray();
			JSONObject main = new JSONObject(true);
			main.put("orgcode", queryForList.get(0).get("ERPFACTORY"));
			main.put("storecode", queryForList.get(0).get("STORE"));
			main.put("dbilldate", TimeStampUtil.getCurrentTime("yyyy-MM-dd hh:mm:ss"));
			main.put("ctrantype", "4A-01");
			main.put("manager", user);
			main.put("issign", "Y");
			main.put("opcode", opCode);
			JSONObject mains = new JSONObject(true);
			mains.put("main", main);


			JSONArray itemArray = new JSONArray();

			for (Map<String, Object> mm : queryForList) {
				JSONObject item = new JSONObject(true);
				item.put("material", mm.get("MAT"));
				item.put("location", mm.get("LOC"));
				item.put("dbizdate", mm.get("INDATE"));
				item.put("dproducedate", mm.get("PRODDATE"));
				item.put("dvalidate", mm.get("EXPDATE"));
				item.put("vbatchcode", mm.get("BATCHCODE"));
				item.put("sdk", mm.get("SDK"));
				item.put("wmsid", UUID.randomUUID() + "");
				item.put("stage", mm.get("JD"));
				item.put("num", mm.get("NUM") + "");
				itemArray.add(item);

			}
			jsonObject2.put("user_code", user);
			mains.put("items", itemArray);
			dataArray.add(mains);
			jsonObject2.put("data", dataArray);
			String httpPost = NCHttpUtil.httpPost(qtr, jsonObject2.toJSONString());
			org.json.JSONObject jsonObject = new org.json.JSONObject(httpPost);
			rcode = jsonObject.get("code").toString();
			rmsg = jsonObject.get("message").toString();
			vbillcode = jsonObject.get("vbillcode").toString();
			Thread t = new Thread(new Runnable() {
				public void run() {
					// run方法具体重写
					UUID uuid = UUID.randomUUID();
					ErpMessageLog erplog = new ErpMessageLog();
					erplog.setEventUser("");
					erplog.setServerName("WmsToErp");
					erplog.setEventName("qtr");
					erplog.setId(uuid.toString());
					erplog.setSendMsg(jsonObject2.toJSONString());
					erplog.setInterfaceTime(ConvertUtil.getCurrTime("yyyy-MM-dd HH:mm:ss"));
					erplog.setMessageId(reActo);
					erplog.setSendMsg2(jsonObject2.toJSONString());
					erplog.setReturnMsg2(httpPost);
					erplog.setResultCode(rcode);
					saveMessageLog(erplog);
				}
			});
			t.start();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("NC返回" + rmsg);
		}
		if (!"1".equals(rcode)) {
			throw new RuntimeException("NC返回" + rmsg);
		}
		return vbillcode;
	}

	public String hold(List<Element> m, String siteName, String user) {
		String rcode;
		//		pk_org	String	是	库存组织
		//		cwarehouseid	String	是	仓库
		//		clocationid	String	是	货位
		//		cmaterialvid		String	是	物料编码
		//		vbatchcode	String	是	批次号
		//		vfree1	String	是	sdk规格
		//		vfree2	String	是	阶段
		//		nfrznum	String	是	冻结主数量
		//			nfrzastnum	String	是	冻结数量
		//		cfreezerid	String	是	冻结人
		//			dfreezedate	String	是	冻结日期
		String rmsg = "";
		try {
			JSONObject jsonObject2 = new JSONObject(true);
			JSONArray jsonArray = new JSONArray();
			for (Element mm : m) {
				String textTrim = mm.getTextTrim();
				MaterialPacking materialPacking = MaterialPackingServiceProxy.getMaterialPackingService().selectByKey(new MaterialPackingKey(siteName, mm.getTextTrim()));
				JSONObject jsonObject = new JSONObject(true);
				jsonObject.put("orgcode", materialPacking.getErpFactory());
				jsonObject.put("storecode", materialPacking.getErpLocation());
				jsonObject.put("material", materialPacking.getMaterialSpecName());
				jsonObject.put("vbatchcode", materialPacking.getCharge());
				jsonObject.put("wmsid", UUID.randomUUID() + "");
				jsonArray.add(jsonObject);
			}
			jsonObject2.put("user_code", user);
			jsonObject2.put("head", jsonArray);
			String httpPost = NCHttpUtil.httpPost(djUrl, jsonObject2.toJSONString());
			org.json.JSONObject jsonObject = new org.json.JSONObject(httpPost);
			rcode = jsonObject.get("code").toString();
			rmsg = jsonObject.get("message").toString();
//			vbillcode= jsonObject.get("vbillcode") == null ? "" : jsonObject.get("vbillcode").toString();
			Thread t = new Thread(new Runnable() {
				public void run() {
					// run方法具体重写
					UUID uuid = UUID.randomUUID();
					ErpMessageLog erplog = new ErpMessageLog();
					erplog.setEventUser("");
					erplog.setServerName("WmsToErp");
					erplog.setEventName("hold");
					erplog.setId(uuid.toString());
					erplog.setInterfaceTime(ConvertUtil.getCurrTime("yyyy-MM-dd HH:mm:ss"));
					erplog.setMessageId(m.toString());
					erplog.setSendMsg(jsonArray.toJSONString());
					erplog.setReturnMsg2(httpPost);
					erplog.setResultCode(rcode);
					saveMessageLog(erplog);
				}
			});
			t.start();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("NC返回" + rmsg);
		}
		return vbillcode;
	}


	/**
	 * 不按批次采购入库接口
	 *
	 * @param receiveRequestName
	 * @return
	 */
//	@Override
	public String PurStockIn(String receiveRequestName, String siteName, String eventUser, String receiveActno, String commitDate, String opCode) throws Exception {
		StringBuffer sql = new StringBuffer();
		sql.append(" ");
		sql.append(" SELECT  '45'  billtype,'45-01' iotype, ");
		sql.append(" M2.STOCKORGNO org, ");
		sql.append(" 'Y' issign, ");
		sql.append(" T.ERPLOCATION store, ");
		sql.append(" :commitDate billtime, ");
		sql.append(" T.LASTEVENTUSER manager, ");
		sql.append(" T.LASTEVENTUSER maker, ");
		sql.append(" M2.ERPID srcbillid, ");
		sql.append(" 'N' freplenishflag, ");
		sql.append(" M.ERPDETAILID srcbillbid, ");
		sql.append(" T.MATERIALSPECNAME mat, ");
		sql.append(" '1' matversion, ");
		sql.append(" M.MATERIALUNIT unit, ");
		sql.append("  M.MATERIALUNIT astunit, ");
		sql.append(" '1.00/1.00' changerate, ");
		sql.append(" TO_CHAR(T.MAKEDATE, 'YYYY-MM-DD') proddate, ");
		sql.append(" TO_CHAR(T.EXPIRINGDATE, 'YYYY-MM-DD') expdate, ");
		sql.append(" T.CHARGE batchcode, ");
		sql.append(" T.MATERIALQUANTITY num, ");
		sql.append(" T.MATERIALQUANTITY astnum, ");
		sql.append(" TO_CHAR(SYSDATE, 'YYYY-MM-DD') indate, ");
		sql.append(" T.PHASE jd, ");
		sql.append("  T.SDK_ID sdk, ");
		sql.append(" T.LOCATIONNAME loc ");
		sql.append(" FROM MATERIALPACKING T ");
		sql.append(" LEFT JOIN MATERIALRECEIVEREQUESTDETAIL M ");
		sql.append(" ON T.RECEIVEREQUESTNAME = M.RECEIVEREQUESTNAME ");
		sql.append("  AND T.RECEIVEREQUESTDETAILNAME = M.RECEIVEREQUESTDETAILNAME ");
		sql.append(" LEFT JOIN MATERIALRECEIVEREQUEST M2 ");
		sql.append("  ON T.RECEIVEREQUESTNAME = M2.RECEIVEREQUESTNAME ");
		sql.append("  LEFT JOIN MATERIALRECEIVEACT M3 ON T.RECEIVEACTNO = M3.RECEIVEACTNO  ");
		sql.append(" WHERE T.RECEIVEREQUESTNAME = :RECEIVEREQUESTNAME ");
		sql.append(" AND T.SITENAME = :SITENAME ");
		sql.append(" AND T.RECEIVEACTNO = :RECEIVEACTNO ");
		sql.append(" AND M3.RECEIVEACTSTATE = 'Created' ");
		Map<String, Object> hashMap = new HashMap<String, Object>();
		hashMap.put("RECEIVEREQUESTNAME", receiveRequestName);
		hashMap.put("SITENAME", siteName);
		hashMap.put("RECEIVEACTNO", receiveActno);
		hashMap.put("commitDate", commitDate);
		List<Map<String, Object>> queryForList = IDMFrameServiceProxy.getSqlTemplate().queryForList(sql.toString(), hashMap);
		if (queryForList == null || queryForList.size() < 1) {
			throw new Exception("NC返回" + "无需过账");
		}
		String makePurStockInXML = makePurStockInXML(queryForList, eventUser, opCode);
		String replaceAll = makePurStockInXML.replace("<LinkedHashMap>", "").replace("</LinkedHashMap>", "");
		String httpPost = NCHttpUtil.httpPost(baseUrl, replaceAll);
		Document document1 = DocumentHelper.parseText(httpPost);
		org.dom4j.Element rootElement = document1.getRootElement();
		String rcode = rootElement.elementText("rcode");
		String rmsg = rootElement.elementText("rmsg");
		String billcode = rootElement.elementText("billcode");

		Thread t = new Thread(new Runnable() {
			public void run() {
				// run方法具体重写
				UUID uuid = UUID.randomUUID();
				ErpMessageLog erplog = new ErpMessageLog();
				erplog.setEventUser(eventUser);
				erplog.setServerName("WmsToErp");
				erplog.setEventName("PurStockIn");
				erplog.setId(uuid.toString());
				erplog.setInterfaceTime(ConvertUtil.getCurrTime("yyyy-MM-dd HH:mm:ss"));
				erplog.setMessageId(receiveActno.toString());
				erplog.setSendMsg2(replaceAll.toString());
				erplog.setSendMsg(replaceAll.toString());
				erplog.setReturnMsg2(rmsg.toString());
				erplog.setResultCode(rcode.toString());
				saveMessageLog(erplog);
			}
		});
		t.start();
		if ("-1".equals(rcode)) {
			throw new Exception("NC返回" + rmsg);
		}
		return billcode;
	}

	/**
	 * 采购入库
	 * @param list
	 * @param eventUser
	 * @return
	 * @throws JsonMappingException
	 * @throws JsonProcessingException
	 */
	public String makePurStockInXML (List<Map<String, Object>> list, String eventUser, String opcode) throws JsonMappingException, JsonProcessingException {

		if (list == null || list.size() < 1) {
			return "";
		}
		//    	billtype	String	是	单据类型
		//    	org	String	是	库存组织
		//    	issign	String	是	是否签字
		//    	Y 是
		//    	N否
		//    	iotype	String	是	出入库类型编码
		//    	store	String	是	仓库编码
		//    	billtime	String	是	制单日期
		//    	manager	String	是	库管员
		//    	maker	String	是	制单人
		//    	srcbillid	String	是	上游单据到货单主表id
		//    	freplenishflag
		//    		String	是	N
		//先保存成json再转xml
		ObjectMapper objectMapper = new ObjectMapper();
		XmlMapper xmlMapper = new XmlMapper();
		JSONObject bill = new JSONObject(true);
		JSONObject billBody = new JSONObject(true);
		billBody.put("billtype", list.get(0).get("BILLTYPE"));
		billBody.put("org", list.get(0).get("ORG"));
		billBody.put("issign", list.get(0).get("ISSIGN"));
		billBody.put("iotype", list.get(0).get("IOTYPE"));
		billBody.put("store", list.get(0).get("STORE"));
		billBody.put("opcode",opcode);
		billBody.put("billtime", list.get(0).get("BILLTIME"));
		billBody.put("manager", eventUser);
		billBody.put("maker", eventUser);
		billBody.put("srcbillid", list.get(0).get("SRCBILLID"));
		billBody.put("freplenishflag", list.get(0).get("FREPLENISHFLAG"));

		JSONArray jsonArray = new JSONArray();
		JSONArray itemH = new JSONArray();
		JSONObject detail = new JSONObject(true);
		for (int i = 0; i < list.size(); i++) {
			//        	srcbillbid	String	是	上游单据生产报告子表id
			//        	mat	String	是	物料编码
			//        	matversion	String	是	物料版本默认1
			//        	unit	String	是	主单位
			//        	astunit	String	是	辅单位
			//        	changerate	String	是	换算率
			//        	proddate	String	是	生产日期
			//        	expdate	String	是	失效日期
			//        	batchcode	String	是	批次号
			//        	num	String	是	主数量
			//        	astnum	String	是	辅数量
			//        	indate	String	是	入库日期
			//        	jd	String	是	阶段
			//        	sdk	String	否	sdk规格（看具体物料）
			//        	loc	String	是	货位
			JSONObject itemD = new JSONObject(true);
			itemD.put("srcbillbid", list.get(i).get("SRCBILLBID"));
			itemD.put("mat", list.get(i).get("MAT"));
			itemD.put("matversion", list.get(i).get("MATVERSION"));
			itemD.put("unit", list.get(i).get("UNIT"));
			itemD.put("astunit", list.get(i).get("ASTUNIT"));
			itemD.put("changerate", list.get(i).get("CHANGERATE"));
			itemD.put("proddate", list.get(i).get("PRODDATE"));
			itemD.put("expdate", list.get(i).get("EXPDATE"));
			if ( !"105010002".equals(list.get(i).get("MAT"))) {
				
				itemD.put("batchcode", list.get(i).get("BATCHCODE"));
			}

			itemD.put("num", list.get(i).get("NUM"));
			itemD.put("astnum", list.get(i).get("ASTNUM"));
			itemD.put("indate", list.get(0).get("BILLTIME"));

			itemD.put("jd", list.get(i).get("JD"));
			itemD.put("sdk", list.get(i).get("SDK"));
			itemD.put("loc", list.get(i).get("LOC"));
			itemH.add(itemD);
		}
		detail.put("item", itemH);
		billBody.put("detail", detail);
		bill.put("bill", billBody);
		Object readValue = objectMapper.readValue(bill.toJSONString(), Object.class);
		String writeValueAsString = xmlMapper.writeValueAsString(readValue);
		return writeValueAsString;
	}

	/**
	 * 日志保存
	 * @param log
	 */
	public static void saveMessageLog(ErpMessageLog log) {

		String sql = "INSERT INTO BS_ERPMESSAGELOG(INTERFACETIME,SERVERNAME, EVENTNAME, EVENTTIMEKEY, EVENTUSER, MESSAGELOG2,RESULTCODE,MESSAGEID,RESULTMESSAGE,MESSAGELOG,RESULTMESSAGE2)\r\n"
				+ "VALUES(TO_DATE(:INTERFACETIME,'yyyy-mm-dd hh24:mi:ss'),:SERVERNAME, :EVENTNAME, :EVENTTIMEKEY, :EVENTUSER, :MESSAGELOG2,:RESULTCODE,:MESSAGEID,:RESULTMESSAGE,:MESSAGELOG,:RESULTMESSAGE2)";
		Map<String, Object> bindMap = new HashMap<String, Object>();
		bindMap.put("SERVERNAME", log.getServerName());
		bindMap.put("EVENTNAME", log.getEventName());
		bindMap.put("EVENTTIMEKEY", log.getId());
		bindMap.put("EVENTUSER", log.getEventUser());
		bindMap.put("MESSAGEID", log.getMessageId());
		bindMap.put("INTERFACETIME", log.getInterfaceTime());
		bindMap.put("RESULTCODE", log.getResultCode());
		bindMap.put("MESSAGELOG", log.getSendMsg());// 推送ERP的json
		bindMap.put("RESULTMESSAGE", log.getReturnMsg());// 返回结果的json
		bindMap.put("MESSAGELOG2", null);// 推送ERP的json
		bindMap.put("RESULTMESSAGE2", log.getReturnMsg2());// 返回结果的json
		IDMFrameServiceProxy.getSqlTemplate().update(sql, bindMap);
	}

}
