package com.cim.idm.mwmsextend.generic.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.cim.idm.wmsextend.generic.GenericServiceProxy;
import com.cim.idm.wmsextend.generic.util.SMessageUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.cim.idm.wmsextend.generic.errorHandler.CustomException;
import com.cim.idm.wmspackage.materialshiprequestdetail.management.data.MaterialShipRequestDetail;
import com.cim.idm.wmspackage.materialshiprequestdetail.management.data.MaterialShipRequestDetailKey;
import com.cim.idm.wmspackage.name.NameServiceProxy;
import com.cim.idm.wmspackage.productpacking.management.data.ProductPacking;
import com.cim.idm.wmspackage.receiverequestdetail.management.data.MaterialReceiveRequestDetail;
import com.cim.idm.wmspackage.receiverequestdetail.management.data.MaterialReceiveRequestDetailKey;
import com.cim.idm.wmspackage.user.management.data.UserInfo;
import com.alibaba.fastjson.JSON;
import com.cim.idm.framework.IDMFrameServiceProxy;
import com.cim.idm.framework.data.EventInfo;
import com.cim.idm.framework.util.time.TimeStampUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class CommonValidation implements ApplicationContextAware {

	private ApplicationContext applicationContext;
	
	private static Log log = LogFactory.getLog(CommonValidation.class);

	/*
	 * Name : setApplicationContext Desc : This function is
	 * setApplicationContext Author : ZXY IDM Team Date : 2011.01.09
	 */
	public void setApplicationContext(ApplicationContext arg0)
			throws BeansException {
		// TODO Auto-generated method stub
		applicationContext = arg0;
	}
	
	 public String getMaterialSpecUnit(String materialspec){
			
		String sql = "SELECT MATERIALUNIT FROM MATERIALSPEC WHERE MATERIALSPECNAME=:MATERIALSPECNAME ";
		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("MATERIALSPECNAME",materialspec);
		List<Map<String, Object>> sqlResult= IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, bindMap);
		if(sqlResult.size()==0 || sqlResult.get(0).get("MATERIALUNIT") == null){
			return "";
		}
		return sqlResult.get(0).get("MATERIALUNIT").toString();
	}

	/*
	 * Name : checkNotNull Desc : This function is checkNotNull Author : AIM
	 * Systems, Inc Date : 2011.01.11
	 */
	public static void checkNotNull(String aItem, String aValue)
			throws CustomException {
		if (StringUtils.isEmpty(aValue)) {
			throw new CustomException("COM-9000", aItem, aValue);
		}
	}

	public void print(Object obj) {
		System.out
				.println("==============================================================");
		System.out.println(obj.getClass().getName() + " : " + obj);
		System.out
				.println("==============================================================");
		
		log.info("==============================================================");
		log.info(obj.getClass().getName() + " : " + obj);
		log.info("==============================================================");
	}

	// throw customException ....
	public void throwException(String errorcode, Object para1, Object para2)
			throws CustomException {
		throw new CustomException(errorcode, para1, para2);
	}

	public void throwException(String errorcode, Object para1)
			throws CustomException {
		throw new CustomException(errorcode, para1);
	}

	public void throwException(String errorcode, Object para1, Object para2,
			Object para3) throws CustomException {
		throw new CustomException(errorcode, para1, para2, para3);
	}

	public String getShipRequestType(String shipRequestDetailType) throws CustomException {
		String sql = "SELECT OPERATIONNAME FROM BS_ERPSHIPTYPEINFO WHERE SHIPREQUESTDETAILTYPE=:SHIPREQUESTDETAILTYPE ORDER BY REASONCODE ASC";

		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("SHIPREQUESTDETAILTYPE", shipRequestDetailType);
		String shipRequestType="";
		List<Map<String, Object>> queryResult = IDMFrameServiceProxy
				.getSqlTemplate()
				.queryForList(sql, bindMap);
		if(queryResult == null || queryResult.isEmpty())
			throw new CustomException("INT-shipRequestType",shipRequestDetailType);
		else
			shipRequestType = queryResult.get(0).get("OPERATIONNAME")
				.toString();
		return shipRequestType;
	}
	public static String setFlagInfo(String shipRequestName,String shipRequestDetailName,String flag)
	{
		if("X".equalsIgnoreCase(flag))
		{
			return "3";
		}
		else
		{
			String sql_request="SELECT * FROM MATERIALSHIPREQUESTDETAIL C WHERE C.SHIPREQUESTNAME=:SHIPREQUESTNAME AND C.SHIPREQUESTDETAILNAME=:SHIPREQUESTDETAILNAME ";
			Map<String,Object> requestMap=new HashMap<String, Object>();
			requestMap.put("SHIPREQUESTNAME", shipRequestName);
			requestMap.put("SHIPREQUESTDETAILNAME", shipRequestDetailName);
			List<Map<String,Object>> result=IDMFrameServiceProxy.getSqlTemplate().queryForList(sql_request, requestMap);
			if(result.isEmpty())
			{
				return "1";
			}
			else
			{
				return "2";
			}
		}
		
	}
	public String getSiteName(String erpFactoryName) {
		String sql = "SELECT distinct sitename FROM BS_ERPLOCATION WHERE ERPFACTORYNAME=:ERPFACTORYNAME AND  SITENAME IS NOT NULL";

		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("ERPFACTORYNAME", erpFactoryName);

		List<Map<String, Object>> queryResult = IDMFrameServiceProxy
				.getSqlTemplate()
				.queryForList(sql, bindMap);

		String returnSiteName = erpFactoryName;
		if (queryResult.size()>0) {
			returnSiteName = queryResult.get(0).get("sitename").toString();
		}
		return returnSiteName;
	}
	
	
	public String GetPOType(String sitename,String rrn){
		String potype = "";
		String sql = "select * from materialreceiverequesttype t where t.sitename=:SITENAME and t.poprefix=:POPREFIX";

		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("SITENAME", sitename);
		bindMap.put("POPREFIX", rrn.substring(0, 2));

		List<Map<String, Object>> queryResult = IDMFrameServiceProxy
				.getSqlTemplate()
				.queryForList(sql, bindMap);

		potype = queryResult.get(0).get("POGROUP").toString();
		return potype;
		
	}
	
	public boolean getIQCFlagOfMaterialSpec(String materialspec,String erpfactory){
		String sql = "SELECT INSPECTA,INSPECTP,INSPECTV FROM BS_MATERIALSPECCHARGEFLAG WHERE ERPFACTORYNAME=:ERPFACTORYNAME AND MATERIALSPECNAME=:MATERIALSPECNAME ";
		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("ERPFACTORYNAME", erpfactory);
		bindMap.put("MATERIALSPECNAME",materialspec);
		List<Map<String, Object>> sqlResult= IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, bindMap);
		if(sqlResult==null||sqlResult.size()!=3){
			return false;
		}
		Object returnflaga = sqlResult.get(0).get("INSPECTA");
		Object returnflagp = sqlResult.get(0).get("INSPECTP");
		Object returnflagv = sqlResult.get(0).get("INSPECTV");
		if(returnflaga != null &&returnflagp != null&&returnflagv != null){
			if(returnflaga.equals("01")&&returnflagp.equals("X")&&returnflagv.equals("X")){
				return true;
			}else{
				return false;
			}
						
		}else{
			return false;
		}
	}
	
	public List<Map<String,Object>> getDestination(String shipRequestName)
	{
		String sql="SELECT ERPFACTORYNAME,ERPRECEIVEFACTORY,ERPRECEIVELOCATION FROM MATERIALSHIPREQUEST WHERE SHIPREQUESTNAME=:SHIPREQUESTNAME";
		Map<String,String> bindmap=new HashMap<String, String>();
		bindmap.put("SHIPREQUESTNAME", shipRequestName);
				
		List<Map<String,Object>> queryResult=IDMFrameServiceProxy
				.getSqlTemplate()
				.queryForList(sql, bindmap);
		 return  queryResult;
	}

	public boolean checkTime(String time) throws ParseException {

		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String date = df.format(new Date());
		Date date1 = df.parse(date);
		String receivedate = time.indexOf("/") > -1 ? time.replace("/", "-")
				: time;
		Date date2 = df.parse(receivedate);
		if (date1.compareTo(date2) >= 0) {

			return true;
		} else {
			return false;
		}

	}

	public String getMaterialSpecState(String sitename, String materialspec) {
		String sql = "select t.expirationdateflag from materialspec t where t.sitename=:sitename and t.materialspecname=:materialspec";
		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("sitename", sitename);
		bindMap.put("materialspec", materialspec);
		Map<String, Object> flag = IDMFrameServiceProxy.getSqlTemplate()
				.queryForMap(sql, bindMap);
		Object returnflag = flag.get("expirationdateflag");
		if (returnflag != null) {
			if (!returnflag.equals("")) {
				return "Y";
			} else {
				return "N";
			}
		} else {
			return "N";
		}
	}
	
  public String getMaterialSpecCharge(String erpFactoryName,String materialspec){
		
		String sql = "SELECT ERPCHARGEFLAG FROM BS_MATERIALSPECCHARGEFLAG WHERE ERPFACTORYNAME=:ERPFACTORYNAME AND MATERIALSPECNAME=:MATERIALSPECNAME ";
		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("ERPFACTORYNAME", erpFactoryName);
		bindMap.put("MATERIALSPECNAME",materialspec);
		List<Map<String, Object>> sqlResult= IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, bindMap);
		if(sqlResult.size()==0){
			return "N";
		}
		Object returnflag = sqlResult.get(0).get("ERPCHARGEFLAG");
		if(returnflag != null){
			if(returnflag.equals("X")){
				return "Y";
			}else{
				return "N";
			}
						
		}else{
			return "N";
		}
	}
	
  public String getMaterialSpecUnit(String erpFactoryName,String materialspec){
		
		String sql = "SELECT MATERIALUNIT FROM MATERIALSPEC WHERE ERPFACTORYNAME=:ERPFACTORYNAME AND MATERIALSPECNAME=:MATERIALSPECNAME ";
		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("ERPFACTORYNAME", erpFactoryName);
		bindMap.put("MATERIALSPECNAME",materialspec);
		List<Map<String, Object>> sqlResult= IDMFrameServiceProxy.getSqlTemplate().queryForList(sql, bindMap);
		if(sqlResult.size()==0){
			return "";
		}
		return sqlResult.get(0).get("MATERIALUNIT").toString();
	}


	public String getGradeByErplocation(String erpfactory, String erplocation) {
		String sql = "select locationgroup from bs_erplocation where erpfactoryname=:erpfactory and erplocationname=:erplocation";
		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("erpfactory", erpfactory);
		bindMap.put("erplocation", erplocation);
		log.info("M2发送ERP后处理返回消息 bindMap ==========> " + JSON.toJSONString(bindMap));
		Map<String, Object> flag = IDMFrameServiceProxy.getSqlTemplate()
				.queryForMap(sql, bindMap);
		log.info("M2发送ERP后处理返回消息 flag ==========> " + JSON.toJSONString(flag));
		Object returnflag = flag.get("locationgroup") == null ? "" : flag.get("locationgroup");
		return returnflag.toString();
		
//		String returnflag = "";
//		Map<String, String> queryMap = new HashMap<String, String>();
//		String querySqlString="select locationgroup from bs_erplocation where erpfactoryname=:erpfactory and erplocationname=:erplocation";
//		queryMap.put("erpfactory", erpfactory);
//		queryMap.put("erplocation", erplocation);
//		log.info("M2发送ERP后处理返回消息 bindMap ==========> " + JSON.toJSONString(queryMap));
//		List<Map<String, Object>> returnListStorge = IDMFrameServiceProxy.getSqlTemplate().queryForList(querySqlString, queryMap);
//		if(returnListStorge != null && returnListStorge.size() > 0) {
//			Map<String, Object> returnStorge = returnListStorge.get(0);
//			log.info("M2发送ERP后处理返回消息 returnStorge ==========> " + JSON.toJSONString(returnStorge));
//			returnflag = returnStorge.get("LOCATIONGROUP").toString();
//		}
//		return returnflag;
	}

	public static void setReturnDoc(String nodeValue, String nodeName,
			Document doc) {
		SMessageUtil.setBodyItemValue(doc, nodeName, nodeValue);
	}

	public String getSpecialDate(String time) throws ParseException {
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
		if (time == "" || time.equals(null)) {						
			//SimpleDateFormat sdf = new SimpleDateFormat("HH");
			Date now = new Date();
			SimpleDateFormat sf=new SimpleDateFormat("HH");
				if(Integer.parseInt(sf.format(now))<6)				
				{	
					Calendar c=Calendar.getInstance();
					c.setTime(now);
					c.add(c.DAY_OF_MONTH, -1);
					return sd.format(c.getTime());
				}
			else
			{
			return sd.format(now);
			}
		} else {
//			time=sd.parse(time)
			return sd.format(sd.parse(time)); 
		}
	}
	
	//物料冲销
	public String specialGetDate(String time) throws ParseException {
		SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd");
		if (time == "" || time.equals(null)) {						
			//SimpleDateFormat sdf = new SimpleDateFormat("HH");
			Date now = new Date();
			SimpleDateFormat sf=new SimpleDateFormat("HH");
				if(Integer.parseInt(sf.format(now))<6)				
				{	
					Calendar c=Calendar.getInstance();
					c.setTime(now);
					c.add(c.DAY_OF_MONTH, -1);
					return sd.format(c.getTime());
				}
			else
			{
			return sd.format(now);
			}
		} else {
//			time=sd.parse(time)
			return sd.format(sd.parse(time)); 
		}
	}
	
	public String getDate(String time) throws ParseException {
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
		if (time == "" || time.equals(null)) {						
			//SimpleDateFormat sdf = new SimpleDateFormat("HH");
			Date now = new Date();
			SimpleDateFormat sf=new SimpleDateFormat("HH");
				if(Integer.parseInt(sf.format(now))<6)				
				{	
					Calendar c=Calendar.getInstance();
					c.setTime(now);
					c.add(c.DAY_OF_MONTH, -1);
					return sd.format(c.getTime());
				}
			else
			{
			return sd.format(now);
			}
		} else {
//			time=sd.parse(time)
			return sd.format(sd.parse(time)); 
		}
	}
	
	public String getDateSpecial(String time,Boolean minusFlag) throws ParseException {
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
		if (time == "" || time.equals(null)) {
			Date now = new Date();
			SimpleDateFormat sf=new SimpleDateFormat("HH");
			if(minusFlag)//只有Delivery的单子过账需要这么操作，其他的过账不需要
			{
				if(Integer.parseInt(sf.format(now))<6)				
				{	
					Calendar c=Calendar.getInstance();
					c.setTime(now);
					c.add(c.DAY_OF_MONTH, -1);
					return sd.format(c.getTime());
				}
			}
			return sd.format(now);
			
		} else {
//			time=sd.parse(time)
			return sd.format(sd.parse(time));
		}
	}
	
	public String GetMessageID(String sitename){
		String messageid = "";		
		List<String> args = new ArrayList<String>();
		args.add("MID");
		if(sitename.equals("B10"))
			sitename ="BA";
		else if(sitename.equals("B11"))
			sitename ="BB";
		else if(sitename.equals("BMDT"))
			sitename ="BM";
		else if (sitename.equals("BMOT"))
			sitename="BO";
		else if(sitename.equals("B17"))
			sitename ="BH";
		else if(sitename.equals("B20"))
			sitename ="BJ";
		args.add(sitename);
		messageid = NameServiceProxy.getNameRuleDefService()
				.generateName("MessageID", args, 1).get(0);
		
		return messageid;
	}
	
	public String GetMessageID_PH(String sitename){
		String messageid = "";		
		List<String> args = new ArrayList<String>();
		SimpleDateFormat samDate = new SimpleDateFormat("yyyy");
		Date d = new Date();
		String year=samDate.format(d);
		args.add(year);
		messageid = NameServiceProxy.getNameRuleDefService().generateName("SEQ", args, 1).get(0);
		// M1 M2 都要发送数据给ERP，为防止SEQ重复，所以这里做下区分
		messageid = "M2WMS" + messageid.substring(0, 4) + messageid.substring(15);
		log.info("M2发送ERP前准备数据 messageid => " + messageid);
		return messageid;
	}
	
	public void RefreshEventTimeKey(EventInfo eventInfo){
		
		eventInfo.setEventTimeKey(TimeStampUtil.getCurrentEventTimeKey());
	}
	
	public List<MaterialReceiveRequestDetail> getReceiveRequestListByJson (String jsStr) throws Exception
	{
		List<MaterialReceiveRequestDetailKey> entitiesList=new ArrayList<MaterialReceiveRequestDetailKey>();
		if(jsStr!=""){
			try{
				ObjectMapper mapper=new ObjectMapper();
				mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY , true);
				entitiesList=mapper.readValue(jsStr, new TypeReference<List<MaterialReceiveRequestDetailKey>>(){});					
			}catch(Exception e)
			{
				e.getMessage();
				throw e;
			}			
		}
		List<MaterialReceiveRequestDetail> mdList=new ArrayList<MaterialReceiveRequestDetail>();
		for (MaterialReceiveRequestDetailKey key : entitiesList) {
			MaterialReceiveRequestDetail md=new MaterialReceiveRequestDetail();
			md.setKey(key);
			mdList.add(md);
		}
		return mdList;
	}
	public List<MaterialShipRequestDetail> getShipRequestListByJson (String jsStr) throws Exception
	{
		List<MaterialShipRequestDetailKey> entitiesList=new ArrayList<MaterialShipRequestDetailKey>();
		if(jsStr!=""){
			try{
				ObjectMapper mapper=new ObjectMapper();
				mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY , true);
				entitiesList=mapper.readValue(jsStr, new TypeReference<List<MaterialShipRequestDetailKey>>(){});					
			}catch(Exception e)
			{
				e.getMessage();
				throw e;
			}			
		}
		List<MaterialShipRequestDetail> mdList=new ArrayList<MaterialShipRequestDetail>();
		for (MaterialShipRequestDetailKey key : entitiesList) {
			MaterialShipRequestDetail md=new MaterialShipRequestDetail();
			md.setKey(key);
			mdList.add(md);
		}
		return mdList;
	}
	public List<UserInfo> getUserListByJson (String jsStr) throws Exception
	{
		List<UserInfo> entitiesList=new ArrayList<UserInfo>();
		if(jsStr!=""){
			try{
				ObjectMapper mapper=new ObjectMapper();
				mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY , true);
				entitiesList=mapper.readValue(jsStr, new TypeReference<List<UserInfo>>(){});	
			}catch(Exception e)
			{
				e.getMessage();
				throw e;
			}			
		}
		return entitiesList;
	}
	public String GetEventTime(){		
		Calendar calendar=Calendar.getInstance();		
		int hour=calendar.get(Calendar.HOUR_OF_DAY);
		if(hour<6)
			calendar.add(Calendar.DAY_OF_MONTH, -1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(calendar.getTime());			
	}
	
	public void checkMaterialActNo(String materialActNo, String siteName) throws CustomException {
		String sql = "SELECT RECEIVEACTNO FROM MATERIALRECEIVEACT WHERE RECEIVEACTNO = :RECEIVEACTNO AND SITENAME = :SITENAME";

		Map<String, String> bindMap = new HashMap<String, String>();
		bindMap.put("RECEIVEACTNO", materialActNo);
		bindMap.put("SITENAME", siteName);
		List<Map<String, Object>> queryResult = IDMFrameServiceProxy
				.getSqlTemplate()
				.queryForList(sql, bindMap);
		if(queryResult == null || queryResult.isEmpty())
		{
			throw new CustomException("ACTNO-0001", materialActNo);
		}
	}
	/*
	* Name : checkInvoiceHoldState
	* Desc : This function is checkInvoiceHoldState
	* Author : BOE CIM 
	* Date : 2015.01.14
	*/
	public static void checkInvoiceHoldState (String invoiceNo,String siteName) throws Exception
	{
		
		List<ProductPacking> result = CommonUtil.getPackingGroupInfoByInoviceNo(invoiceNo,siteName);
		
		for(ProductPacking packingGroup : result)
		{
			if(StringUtils.equals(packingGroup.getHoldState(), com.cim.idm.wmspackage.generic.GenericServiceProxy.getConstantMap().PackingGroup_OnHold))
			{
				if(StringUtils.equals(packingGroup.getPackingType(), GenericServiceProxy.getConstantMap().PackingGroupType_Pallet))
					throw new CustomException("PALLET-0101", packingGroup.getKey().getProductPackingName());
				else if(StringUtils.equals(packingGroup.getPackingType(),GenericServiceProxy.getConstantMap().PackingGroupType_Box)){
					throw new CustomException("BOX-0101", packingGroup.getKey().getProductPackingName());
				}else {
					throw new CustomException("PACKINGGROUP-0101", packingGroup.getKey().getProductPackingName());
				}
				
			}
		}
		
	}
}