package nc.bs.ic.general.rule.before;

import nc.bs.framework.common.NCLocator;
import nc.bs.ic.pub.base.ICRule;
import nc.bs.ic.pub.util.DebugUtils;
import nc.impl.pubapp.bd.material.assistant.MarAssistantCheckUtils;
import nc.impl.pubapp.bd.material.assistant.MarAssistantSaveRule;
import nc.impl.pubapp.pattern.rule.ICompareRule;
import nc.pubitf.uapbd.IMaterialPubService_C;
import nc.pubitf.uapbd.assistant.IMarAssistantPubService;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.userdefrule.UserdefitemVO;
import nc.vo.ic.general.define.ICBillBodyVO;
import nc.vo.ic.general.define.ICBillVO;
import nc.vo.ic.m45.entity.PurchaseInBodyVO;
import nc.vo.ic.m45.entity.PurchaseInVO;
import nc.vo.ic.pub.define.ICPubMetaNameConst;
import nc.vo.ic.pub.util.CollectionUtils;
import nc.vo.ic.pub.util.NCBaseTypeUtils;
import nc.vo.ic.pub.util.ValueCheckUtil;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.BusinessException;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pubapp.AppContext;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.Constructor;
import nc.vo.pubapp.pattern.pub.MapList;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * 
 * @description
 * 自由辅助属性检查
 * @scene
 * 普通出入库单据保存
 * @param
 * 无
 *
 * @since 6.3
 * @version 2011-4-2 上午10:13:52
 * @author chennn
 */
public class MaterialAssistantCheck<E extends ICBillVO> extends ICRule<E>
implements ICompareRule<E> {

  @SuppressWarnings("unchecked")
  @Override
	public void process(E[] vos) {
		long time1 = System.currentTimeMillis();
		//对于物料辅助属性设置了boolean值且未启用  默认值是N 所以此处先进行清空处理 置为null
		IMarAssistantPubService assistantPubService = NCLocator.getInstance().lookup(IMarAssistantPubService.class);
		try {
			UserdefitemVO[] userdefitemVOs = assistantPubService.queryMarAssistantDefine(AppContext.getInstance().getPkGroup());
			boolean isUseDef = false;
			if(userdefitemVOs!=null) {
				for (UserdefitemVO vo : userdefitemVOs) {
					if(vo.getClassid().equals("BS000010000100001032")) {
						isUseDef = true;
					}
				}
			}
			if (isUseDef) {
				this.processFreeDef(vos);
			}
		} catch (BusinessException e) {
			ExceptionUtils.wrappException(e);
		}
		for (int i = 0; vos != null && i < vos.length; i++) {
			Set<String> set = new HashSet<String>();
			Class<? extends ISuperVO> clazz = null;
			if(vos[0] instanceof PurchaseInVO){
				clazz = PurchaseInBodyVO.class;
			}else {
				clazz = (Class<? extends ISuperVO>) vos[0].getClass();
			}
			ICBillVO outvo = (ICBillVO)vos[i];
			MapList<String, String> checkvalue=check(ICPubMetaNameConst.CMATERIALVID,vos[i].getChildren(clazz));
			for(ICBillBodyVO bodyvo:outvo.getBodys()) {
				if(checkvalue==null) {
					for(int k=1; k<=10;k++) {
						String index="vfree"+k;
						Object vfree=bodyvo.getAttributeValue(index);
						if((vfree!=null)&&bodyvo.getStatus()!=VOStatus.DELETED) {
							ExceptionUtils.wrappBusinessException(NCLangRes4VoTransl.getNCLangRes()
						              .getStrByID("4008001_0", "04008001-0933", null, new String[] {
						            		  bodyvo.getCrowno()
						              })+ "-----" + vfree.toString());/*第{0}行物料自由辅助属性有问题*/
						}
					}
				}else {
					Map<String, List<String>> maplist = checkvalue.toMap();
					List<String> materialList=maplist.get(bodyvo.getCmaterialvid());
					if(materialList!=null) {
						for (String code : materialList) {
							set.add(code);
						}
					}
					for(int k=1; k<=10;k++) {
						String index="vfree"+k;
						Object vfree=bodyvo.getAttributeValue(index);
						if((vfree!=null)&&!set.contains(index)&&bodyvo.getStatus()!=VOStatus.DELETED) {
							ExceptionUtils.wrappBusinessException(NCLangRes4VoTransl.getNCLangRes()
						              .getStrByID("4008001_0", "04008001-0933", null, new String[] {
						            		  bodyvo.getCrowno()
						              }));/*第{0}行物料自由辅助属性有问题*/
						}
					}
				}
			}
		}
		this.checkItemNotNull(vos);
		long time2 = System.currentTimeMillis();
		DebugUtils.debug(" before rule: MaterialAssistantCheck", time2-time1);
	}
  
	@SuppressWarnings("unchecked")
	private void processFreeDef(E[] billvos) {
		for (ICBillVO billvo : billvos) {
			Class<? extends ISuperVO> clazz = null;
			if(billvo instanceof PurchaseInVO){
				clazz = PurchaseInBodyVO.class;
			}else {
				clazz = (Class<? extends ISuperVO>) billvo.getClass();
			}
			MapList<String, String> checkvalue = check(ICPubMetaNameConst.CMATERIALVID, billvo.getChildren(clazz));
			for (ICBillBodyVO bodyvo : billvo.getBodys()) {
				if (checkvalue == null) {
					for (int k = 1; k <= 10; k++) {
						String index = "vfree" + k;
						Object vfree = bodyvo.getAttributeValue(index);
						if ((vfree != null && (vfree.equals("N") || vfree.equals("false"))) ) {
							bodyvo.setAttributeValue(index, null);
						}
					}
				} else {
					Map<String, List<String>> maplist = checkvalue.toMap();
					List<String> list = maplist.get(bodyvo.getAttributeValue(ICPubMetaNameConst.CMATERIALVID));
					for (int k = 1; k <= 10; k++) {
						String index = "vfree" + k;
						Object vfree = bodyvo.getAttributeValue(index);
						if ((vfree != null && (vfree.equals("N") || vfree.equals("false")))) {
							if(list==null || !list.contains(index)) {
								bodyvo.setAttributeValue(index, null);
							}
						}
					}
				}
			}
		}
		
	}
  
  
  @Override
  public void process(E[] vos, E[] originVOs) {
    
	  this.process(vos);
	  this.checkItemNotNull(vos);
  }

  private void checkItemNotNull(E[] vos) {
    if (ValueCheckUtil.isNullORZeroLength(vos)) {
      return;
    }  
    MarAssistantSaveRule<E> ruleProc = new MarAssistantSaveRule<E>();
    ruleProc.setNotNullValidate(ICPubMetaNameConst.CMATERIALVID);
    ruleProc.process(getBillWithNum(vos));
  }
  
  
  
  public MapList<String, String> check(String materialField,ISuperVO[] valueObjects) {
	  MapList<String, String> materialMapList = new MapList<String, String>();
	  Map<String, MaterialVO> materialMap = this.getMaterialMap(materialField, valueObjects);
	  if (materialMap == null || materialMap.size() == 0) {
		  return null;
	  }
	  Map<String, List<Integer>> marFrameMap = this.getMarFrameMap(materialMap);
	  if (marFrameMap == null || marFrameMap.size() == 0) {
		  return null;
	  }
	  
	  for (ISuperVO value : valueObjects) {
		  Object pk_material = value.getAttributeValue(materialField);
		  String pk_marasstframe = materialMap.get(pk_material).getPk_marasstframe();
		  List<Integer> list = marFrameMap.get(pk_marasstframe);
		  if(list==null) {
			  continue;
		  }
		  for(Integer listvlaue:list) {
			  if (pk_marasstframe != null) {
					materialMapList.put(pk_material.toString(), "vfree"+(listvlaue-5));
				} 
		  }
	  }
	  return  materialMapList;
  }
  private Map<String, List<Integer>> getMarFrameMap(Map<String, MaterialVO> materialMap) {
	    Map<String, List<Integer>> marFrameMap = null;
	    try {
	      Set<String> marFramePkSet = new HashSet<String>();
	      for (Entry<String, MaterialVO> entry : materialMap.entrySet()) {
	        String pk_marasstframe = entry.getValue().getPk_marasstframe();
	        if (pk_marasstframe != null) {
	          marFramePkSet.add(pk_marasstframe);
	        }
	      }
	      marFrameMap =
	          MarAssistantCheckUtils.queryMarAsstFrameIncludeDefPropIndex(marFramePkSet
	              .toArray(new String[0]));
	    } catch (BusinessException e) {
	      ExceptionUtils.wrappException(e);
	    }
	    return marFrameMap;
	  }
  private Map<String, MaterialVO> getMaterialMap(String materialField, ISuperVO[] valueObjects) {
	    Map<String, MaterialVO> materialMap = null;
	    try {
	      Set<String> marPkSet = new HashSet<String>();
	      for (int i = 0; i < valueObjects.length; i++) {
	        String pk_material = (String) valueObjects[i].getAttributeValue(materialField);
	        marPkSet.add(pk_material);
	      }

	      IMaterialPubService_C marService =
	          NCLocator.getInstance().lookup(IMaterialPubService_C.class);
	      materialMap =
	          marService.queryMaterialBaseInfoByPks(marPkSet.toArray(new String[0]), new String[] {
	              MaterialVO.PK_MARASSTFRAME, MaterialVO.NAME, MaterialVO.NAME2, MaterialVO.NAME3,
	              MaterialVO.NAME4, MaterialVO.NAME5, MaterialVO.NAME6});
	    } catch (BusinessException e) {
	      ExceptionUtils.wrappException(e);
	    }
	    return materialMap;
	  }
  

  private E[] getBillWithNum(E[] vos){
    List<E> retList= new ArrayList<E>();
    Class<? extends ICBillVO> clazz= vos[0].getClass();
    for(E vo:vos){   
      @SuppressWarnings("unchecked")
      E bill=  (E) Constructor.construct(clazz);
      bill.setParentVO(vo.getHead());
      List<ICBillBodyVO> bodys= new ArrayList<ICBillBodyVO>();
      for(ICBillBodyVO body:vo.getBodys()){
        if(NCBaseTypeUtils.isNull(body.getNnum())){
          continue;
        }
        bodys.add(body);
      }
      if(ValueCheckUtil.isNullORZeroLength(bodys)){
        continue;
      }
      bill.setChildrenVO(CollectionUtils.listToArray(bodys));
      retList.add(bill);
    }
    return CollectionUtils.listToArray(retList);
    
  }

}
