package nc.bs.mmpac.pmo.pac0002.bp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nc.bs.mmpac.pmo.pac0002.bp.service.PMOBPService;
import nc.bs.mmpac.pmo.pac0002.bp.util.PMOBPUtil;
import nc.bs.mmpac.pmo.pac0002.pluginpoint.PMOPluginPoint;
import nc.bs.mmpac.pmo.pac0002.rule.PMOFilterBillStatusRule;
import nc.bs.mmpac.pmo.pac0002.rule.PMOFilterRowStatusRule;
import nc.bs.mmpac.pmo.pac0002.rule.PMOPutAutoAuditPickmRule;
import nc.bs.mmpac.pmo.pac0002.rule.check.PMOCheckDeptNotNullRule;
import nc.bs.mmpac.pmo.pac0002.rule.fill.PMOFillBatchCodeRule;
import nc.bs.mmpac.pmo.pac0002.rule.fill.PMOFillPutValueRule;
import nc.bs.mmpac.pmo.pac0002.bp.rule.putBeforeCheckRule;
import nc.bs.mmpub.rule.MMVOSagaFrozenValidateRule;
import nc.impl.pubapp.pattern.data.vo.tool.VOConcurrentTool;
import nc.impl.pubapp.pattern.rule.processer.CompareAroundProcesser;
import nc.util.mmf.framework.gc.GCBillConcurrentTool;
import nc.util.mmf.framework.gc.GCBillTransferTool;
import nc.util.mmf.framework.gc.GCBillUpdate;
import nc.util.mmf.framework.gc.GCUpdateBPTemplate;
import nc.vo.mmpac.pmo.pac0002.constant.PMOConstLang;
import nc.vo.mmpac.pmo.pac0002.entity.PMOAggVO;
import nc.vo.mmpac.pmo.pac0002.entity.PMOItemVO;
import nc.vo.mmpac.pmo.pac0002.enumeration.PMOFBillstatusEnum;
import nc.vo.mmpac.pmo.pac0002.enumeration.PMOFItemStatusEnum;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;

public class PMORowPutBP {
	public PMOAggVO[] rowput(PMOAggVO[] vos) {
		try {
			GCBillConcurrentTool lockTool = new GCBillConcurrentTool();
			lockTool.lockBill(vos);

			(new VOConcurrentTool()).checkTSWithDB(vos[0].getChildrenVO());

			GCUpdateBPTemplate<PMOAggVO> bp = new GCUpdateBPTemplate<PMOAggVO>(PMOPluginPoint.ROWPUT);
			CompareAroundProcesser<PMOAggVO> processer = bp.getAroundProcesser();

			addRowPutBeforeRule(processer);

			addRowPutAfterRule(processer);

			PMOAggVO[] returnvos = (PMOAggVO[]) processer.before(vos, vos);

			List<PMOItemVO> upditemList = new ArrayList<PMOItemVO>();
			Map<String, PMOItemVO> upditemMap = new HashMap<String, PMOItemVO>();
			for (PMOAggVO aggvo : returnvos) {
				PMOItemVO[] items = aggvo.getChildrenVO();
				for (PMOItemVO item : items) {
					upditemList.add(item);
					upditemMap.put(item.getCmoid(), item);
				}
			}
			PMOAggVO aggvo = PMOBPService.getIPMOQueryService().queryByPk(vos[0].getParentVO().getCpmohid());

			PMOItemVO[] olditems = aggvo.getChildrenVO();
			List<PMOItemVO> tempitems = new ArrayList<PMOItemVO>();
			for (PMOItemVO item : olditems) {
				if (!upditemMap.containsKey(item.getCmoid())) {
					tempitems.add(item);
				} else {

					((PMOItemVO) upditemMap.get(item.getCmoid())).setStatus(1);
					PMOBPUtil.setGrandVOStatusUpdate((PMOItemVO) upditemMap.get(item.getCmoid()));
					tempitems.add((PMOItemVO) upditemMap.get(item.getCmoid()));
				}
			}
			aggvo.setChildrenVO((CircularlyAccessibleValueObject[]) tempitems.toArray(new PMOItemVO[tempitems.size()]));

			PMOAggVO[] aggvos = { aggvo };

			GCBillTransferTool<PMOAggVO> transferTool = new GCBillTransferTool<PMOAggVO>(aggvos);
			PMOAggVO[] originBills = (PMOAggVO[]) transferTool.getOriginBills();
			GCBillUpdate<PMOAggVO> billupdate = new GCBillUpdate<PMOAggVO>();
			PMOAggVO[] newaggvos = (PMOAggVO[]) billupdate.update(aggvos, originBills);

			PMOItemVO[] totalitems = newaggvos[0].getChildrenVO();
			Map<String, PMOItemVO> newitemMap = new HashMap<String, PMOItemVO>();
			for (PMOItemVO item : totalitems) {
				if (upditemMap.containsKey(item.getCmoid())) {
					newitemMap.put(item.getCmoid(), item);
				}
			}
			returnvos[0]
					.setChildrenVO((CircularlyAccessibleValueObject[]) newitemMap.values().toArray(new PMOItemVO[0]));

			processer.after(returnvos, returnvos);

			PMOAggVO newaggvo = PMOBPService.getIPMOQueryService().queryByPk(vos[0].getParentVO().getCpmohid());

			return new PMOAggVO[] { newaggvo };

		} catch (Exception e) {
			ExceptionUtils.wrappException(e);

			return null;
		}
	}

	private void addRowPutBeforeRule(CompareAroundProcesser<PMOAggVO> processer) {
		MMVOSagaFrozenValidateRule mMVOSagaFrozenValidateRule = new MMVOSagaFrozenValidateRule(true);
		processer.addBeforeRule(mMVOSagaFrozenValidateRule);
		processer.addBeforeRule(
				new PMOFilterBillStatusRule(PMOConstLang.getMSG_ACTION_NO_AUDIT(), PMOFBillstatusEnum.AUDIT));

		processer.addBeforeRule(
				new PMOFilterRowStatusRule(PMOConstLang.getMSG_RULE_NO_ROWDATA(), PMOFItemStatusEnum.AUDIT));

		processer.addBeforeRule(new PMOCheckDeptNotNullRule());
		processer.addBeforeRule(new PMOPutAutoAuditPickmRule());
		processer.addBeforeRule(new PMOFillPutValueRule(false));
		processer.addBeforeRule(new PMOFillBatchCodeRule());
		processer.addBeforeRule(new putBeforeCheckRule());
	}

	private void addRowPutAfterRule(CompareAroundProcesser<PMOAggVO> processer) {
	}
}
