package com.dev.swms.server.service.sequence.pojo;

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

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.transaction.annotation.Transactional;

import com.dev.sequence.service.sequence.SequenceGenerater;
import com.dev.swms.server.model.base.BillType;
import com.dev.swms.server.model.receiving.ReceivedDoc;
import com.dev.swms.server.service.sequence.BussinessCodeManager;
import com.dev.swms.server.service.sequence.SwmsSequenceDao;
import com.dev.energy.server.config.UniConfig;
import com.dev.energy.server.config.globalparam.GlobalParam;
import com.dev.energy.server.service.pojo.DefaultBaseManager;

/**
 * @author  dev
 */
public class DefaultBussinessCodeManager extends DefaultBaseManager implements BussinessCodeManager,ApplicationContextAware{
	private static ApplicationContext ac;
	private final  SequenceGenerater sequenceGenerater;
	private final SwmsSequenceDao sequenceDao;
	
	public DefaultBussinessCodeManager(SequenceGenerater sequenceGenerater, SwmsSequenceDao sequenceDao){
		this.sequenceGenerater = sequenceGenerater;
		this.sequenceDao = sequenceDao;
	}

	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		ac = arg0;
	}
	
	public Map generateASNReceiveGroupCode(String code){
		//同一张ASN单在同一天只生成一个GroupCode
		//先用收货单CODE和RGYYYYMMDD在入库单中查找记录数，如无记录存在，则生成一个GroupCode，否则用找到的GroupCode
		Map a = new HashMap();
		if(ac.containsBean("uniConfig")){
			UniConfig uniConfig = (UniConfig) ac.getBean("uniConfig");
//			String key = this.getKey(uniConfig, "generateASNReceiveGroupDefault", "asnReceiveGroupGodePrefix");
 			String key=getCodeForYm("AG", 4);
			ReceivedDoc receivedDoc = getReceivedDocByCode(code, "%"+key+"%");
 			if (receivedDoc != null) {
 				a.put("receivedDocId", receivedDoc.getId());
 				a.put("groupCode", receivedDoc.getCode());
 			} else {
 				a.put("receivedDocId", 0L);
 				a.put("groupCode", key);//generateBussinessBillCode("generateASNReceiveGroup","asnReceiveGroupCodeNumber","generateASNReceiveGroupDefault","asnReceiveGroupGodePrefix"));
 			}
		}
		return a;
	}
	
	private ReceivedDoc getReceivedDocByCode(String code, String receivedCode) {
		List result = commonDao.findByNamedQuery("getReceivedDocByASNCode",
					new String[] { "ASNCode", "receivedCode" }, new String[] { code, receivedCode });
		if (result.size() >= 1) {
			return (ReceivedDoc) result.get(0);
		}
		return null;
	}
	
	/**
	 * 创建流水号
	 * 格式=前缀+key+自增数
	 * @param type 创建流水号的单据类型全局参数Y表示创建N表示不创建
	 * @param patten 自增数位数的全局参数
	 * @param defaultKey 是否采用缺省key的全局参数，缺省为日期
	 * @param prefix 流水号前缀的全局参数
	 */
	public String generateBussinessBillCode(String type,String patten,String defaultKey,String prefix) {
		if(ac.containsBean("uniConfig")){
			 UniConfig uniConfig = (UniConfig) ac.getBean("uniConfig");
	         GlobalParam gloabalType = uniConfig.getGlobalParam(type);
	         if(gloabalType!=null && gloabalType.getString()!=null && "Y".equals(gloabalType.getString())){
	        	int number = this.getPattenNumber(uniConfig,patten);
	        	String key = this.getKey(uniConfig,defaultKey,prefix);
	        	return generateSequence(key,number);
	         }else{
	            return "";
	         }
		}else{
			return "";
		}
	}
	
	private int getPattenNumber(UniConfig uniConfig, String patten) {
		int number = 1;
		GlobalParam gloabalPatten = uniConfig.getGlobalParam(patten);
		if(gloabalPatten!=null && gloabalPatten.getString()!=null && !"".equals(gloabalPatten.getString())){
   		   number = gloabalPatten.getInt();
   	    }
		return number;
	}
	
	private String getKey(UniConfig uniConfig, String defaultKey, String prefix) {
		String key = "";
		String prefixString = this.getPrefixString(uniConfig,prefix);
		GlobalParam gloabalDefault = uniConfig.getGlobalParam(defaultKey);
		if(gloabalDefault!=null && gloabalDefault.getString()!=null && "Y".equals(gloabalDefault.getString())){
	   		 DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
	   		 key = prefixString + dateFormat.format(new Date());
	   	 }else{
	   		 key = prefixString + getBussinessCodeFormatKey();
	   	 }
		return key;
	}

	private String getPrefixString(UniConfig uniConfig, String prefix) {
		String prefixString = "";
		GlobalParam gloabalPrifix = uniConfig.getGlobalParam(prefix);
  		 if(gloabalPrifix!=null && gloabalPrifix.getString()!=null){
  			 prefixString = gloabalPrifix.getString();
  		 }
		return prefixString;
	}

	protected String getBussinessCodeFormatKey() {
		return "";
	}
	

	public String getCodeBySP(String key,int number) {
		String code = sequenceDao.getSequenceBySP(key).toString();
		if (code.length() < number) {
			code = StringUtils.repeat("0", number-code.length()) + code;
		}
		return key+code;
	}

	private String generateSequence(String key,int number) {
		UniConfig uniConfig = (UniConfig) ac.getBean("uniConfig");
        GlobalParam sequenceType = uniConfig.getGlobalParam("generateSequenceBySP");
        if (sequenceType!=null && sequenceType.getString()!=null && "Y".equals(sequenceType.getString())){
        	return getCodeBySP(key, number);
        } else {
        	return sequenceGenerater.generateSequence(key, number);
        }
	}
	@Transactional
	public String generateDayCode(String code,int len) {
		String time = new SimpleDateFormat("yyMMdd").format(Calendar.getInstance().getTime());
		String lotCode = sequenceGenerater.generateSequence(code+time,len);
		return lotCode.substring(0, lotCode.length());

	}

	public String generateCountPlanCode(Map params) {
		return generateBussinessBillCode("generateCountPlan","countPlanCodeNumber","generateCountPlanDefault","countPlanCodePrefix");
	}
	
	public String generateReceivingDocCode(Map params) {
		return generateBussinessBillCode("generateRevDoc","revDocCodeNumber","generateRevDocDefault","revDocCodePrefix");
	}
	
	public String generateLP(String warehouseCode) {
		String prefix = warehouseCode+"LP";
		String lp = generateSequence(prefix, 10);
		return lp.substring(prefix.length()-2, lp.length());
	}
	
	public String generateCageInfoCode(String warehouseCode) {
		String prefix = warehouseCode+"CG";
		String lp = generateSequence(prefix, 10);
		return lp.substring(prefix.length()-2, lp.length());
	}
	
	public String generateBOLCode(Map params) {
		return generateBussinessBillCode("generateBOL","BOLNumber","generateBOLDefault","BOLPrefix");
	}
	
	public String generateMasterBOLCode(Map params) {
		return generateBussinessBillCode("generateMasterBOL","masterBOLCodeNumber","generateMasterBOLDefault","masterBOLCodePrefix");
	}
	
	public String generateInventoryApplyCode(Map params){
		return generateBussinessBillCode("generateInventoryApplyCode","inventoryApplyCodeNumber","generateInventoryApplyCodeDefault","inventoryApplyCodePrefix");
	}

	public String generateLot(){
		String lotCode = generateSequence("CreateLotTypeDefault",10);
		return lotCode.substring(20,lotCode.length());
	}

	public String generateTask() {
		String lotCode = generateSequence("generateTask",10);
		return lotCode.substring(12,lotCode.length());
	}
	
	public String generatePackage() {
		String lotCode = generateSequence("generatePackage",10);
		return lotCode.substring(15, lotCode.length());
	}
	
	public String generatePackage(String prefix) {
		String lotCode = generateSequence("generatePackage",10);
		return lotCode.substring(15, lotCode.length());
	}

	public String getCodeByBillType(BillType billType, Long warehouseId) {
		String key = "";	
		String prefix = "";
		String cutString = "";
		String warehouse = warehouseId.toString();
		if(null != billType.getPrefix()){
			prefix = billType.getPrefix();
		}
		if(null != billType.getCutString()){
			cutString = billType.getCutString();
		}
		if(billType.isBeUseDate()){
			SimpleDateFormat sd = new SimpleDateFormat(billType.getDateFormatString());
			key = warehouse + prefix + cutString + sd.format(new Date()) + cutString;
		}else{
			key = warehouse + prefix + cutString;
		}		
		int number = billType.getNumberCount() - key.length() + warehouse.length();
		String code = generateSequence(key, number);
		return code.substring(warehouse.length(),code.length());
	}
	
	
	public String getCodeForYm(String code, int len) {
		String time = new SimpleDateFormat("yyMMdd").format(Calendar.getInstance().getTime());
		return sequenceGenerater.generateSequence(code+time,len);
	}

	public String getCodeYm(String code, int len) {
		String time = new SimpleDateFormat("yyMM").format(Calendar.getInstance().getTime());
		return sequenceGenerater.generateSequence(code+time,len);
	}
	
}
