package com.yeejoin.equipmanage.common.utils;

import java.math.BigDecimal;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;

/** 
* <pre>
*  库存单据编码 管理器
* </pre>
*
* @author as-chennan E-mail: chennan@yeejoin.com
* @version BillCodeManagerUtil.java v0.1 
* @time 2017年2月19日 下午8:36:15 
* 
* 缓存上一个使用的库存单据号，每次新生成单据号时，需要在管理器中检查是否有人占用，被占用则改变单号，并记录单号
* ，若未被占用，则记录单号并返回原单号。
*/
public class BillCodeManagerUtil {

	
	public static final String INBOUND = "RK";
	public static final String OUTBOUND = "CK";
	public static final String ALLOT = "DB";
	public static final String RETIRED = "TY";
	public static final String SCRAP = "BF";
	public static final String RETIRMENT = "TYBF";
	public static final String MAINTAIN = "BY";
	public static final String OTHER = "DF";
	public static final String BORROW = "JY";
	public static final String CHECK = "JC";
	public static final String INVENTORY = "PD";
	public static final String TRANSFER = "HWZY";
	public static final String LOSS = "SH";
	
	
	public static final String[] prefixs = {"RK", "CK", "DF", "TY", "BF","TYBF", "BY", "JY", "JC", "PD", "DB", "HWZY", "SH"};
	
	private static ConcurrentHashMap<String, String> codes = new ConcurrentHashMap<String, String>();
	
	public static String checkTransferCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(TRANSFER, code)) {
				code_copy = changeCode(getRecoedCode(TRANSFER));
				recoredCode(TRANSFER, code_copy);
			} else {
				recoredCode(TRANSFER, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkWastageCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(LOSS, code)) {
				code_copy = changeCode(getRecoedCode(LOSS));
				recoredCode(LOSS, code_copy);
			} else {
				recoredCode(LOSS, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkOutboundCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(OUTBOUND, code)) {
				code_copy = changeCode(getRecoedCode(OUTBOUND));
				recoredCode(OUTBOUND, code_copy);
			} else {
				recoredCode(OUTBOUND, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkInventoryCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(INVENTORY, code)) {
				code_copy = changeCode(getRecoedCode(INVENTORY));
				recoredCode(INVENTORY, code_copy);
			} else {
				recoredCode(INVENTORY, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkInspectCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(CHECK, code)) {
				code_copy = changeCode(getRecoedCode(CHECK));
				recoredCode(CHECK, code_copy);
			} else {
				recoredCode(CHECK, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkMaintianCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(MAINTAIN, code)) {
				code_copy = changeCode(getRecoedCode(MAINTAIN));
				recoredCode(MAINTAIN, code_copy);
			} else {
				recoredCode(MAINTAIN, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkRetiredCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(RETIRED, code)) {
				code_copy = changeCode(getRecoedCode(RETIRED));
				recoredCode(RETIRED, code_copy);
			} else {
				recoredCode(RETIRED, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkScrapCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(SCRAP, code)) {
				code_copy = changeCode(getRecoedCode(SCRAP));
				recoredCode(SCRAP, code_copy);
			} else {
				recoredCode(SCRAP, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkBorrowCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(BORROW, code)) {
				code_copy = changeCode(getRecoedCode(BORROW));
				recoredCode(BORROW, code_copy);
			} else {
				recoredCode(BORROW, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkAllotCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(ALLOT, code)) {
				code_copy = changeCode(getRecoedCode(ALLOT));
				recoredCode(ALLOT, code_copy);
			} else {
				recoredCode(ALLOT, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkRetiementCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(RETIRMENT, code)) {
				code_copy = changeCode(getRecoedCode(RETIRMENT));
				recoredCode(RETIRMENT, code_copy);
			} else {
				recoredCode(RETIRMENT, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkInboundCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(INBOUND, code)) {
				code_copy = changeCode(getRecoedCode(INBOUND));
				recoredCode(INBOUND, code_copy);
			} else {
				recoredCode(INBOUND, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkOtherCode(String code) {
		synchronized(BillCodeManagerUtil.class) {
			String code_copy = code;
			if (hasCode(OTHER, code)) {
				code_copy = changeCode(getRecoedCode(OTHER));
				recoredCode(OTHER, code_copy);
			} else {
				recoredCode(OTHER, code_copy);
			}
			
			return code_copy;
		}
	}
	
	public static String checkCoding(String prefix, String code) {
		if (null == prefix || null == code) {
			throw new IllegalArgumentException("未输入正确参数，编码前缀（prefix），编码（code）！");
		}

		String tmp_prefix = prefix.toUpperCase(Locale.ENGLISH);
		switch (tmp_prefix) {
			case INBOUND:
				return checkInboundCode(code);
			case OUTBOUND:
				return checkOutboundCode(code);
			case ALLOT:
				return checkAllotCode(code);
			case RETIRMENT:
				return checkRetiementCode(code);
			case RETIRED:
				return checkRetiredCode(code);
			case SCRAP:
				return checkScrapCode(code);
			case MAINTAIN:
				return checkMaintianCode(code);
			case BORROW:
				return checkBorrowCode(code);
			case CHECK:
				return checkInspectCode(code);
			case INVENTORY:
				return checkInventoryCode(code);
			case TRANSFER:
				return checkInventoryCode(code);
			case LOSS:
				return checkWastageCode(code);
			default:
				return checkOtherCode(code);
		}
	}
	
	private static boolean hasCode(String key, String code) {
		if (codes.containsKey(key) && code.equals(codes.get(key))) {
			return true;
		} else if (codes.containsKey(key) && code.compareTo(codes.get(key)) < 0) {
			return true;
		} else {
			return false;
		}
		
	}
	
	private static String changeCode(String code) {
		String tmp_code = code;
		String prefix = "DF";
		boolean hasdefind = false;
		
		for(int i = 0; i < prefixs.length; i++) {
			if (code.indexOf(prefixs[i]) != -1) {
				prefix = prefixs[i];
				tmp_code = tmp_code.replace(prefix, "");
				hasdefind = true;
				break;
			}
		}
		
		if (!hasdefind) {
			tmp_code = tmp_code.replaceAll("[a-zA-Z]+", "");
		}
		
		BigDecimal decimal = new BigDecimal(tmp_code);
		String appDecimal = decimal.toString().substring(6);//去掉decimal的前6位
		String preDecimal = decimal.toString().substring(0,6);
		int len = appDecimal.replace("9", "").length();
		if(len==0){
			return prefix + preDecimal + (Integer.parseInt(appDecimal)+1);
		}
		tmp_code = prefix + (decimal.longValue() + 1) ;
		
		return tmp_code;
	}
	
	private static void recoredCode(String key, String code) {
		codes.put(key, code);
	}
	
	private static String getRecoedCode(String key) {
		return codes.get(key);
	}

	private BillCodeManagerUtil() {
	}
}
