package nc.bs.cmp.listener;

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

import nc.bs.businessevent.BdUpdateEvent;
import nc.bs.businessevent.BusinessEvent;
import nc.bs.businessevent.IBusinessEvent;
import nc.bs.businessevent.IBusinessListener;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.vo.arap.basebill.BaseAggVO;
import nc.vo.arap.gathering.AggGatheringBillVO;
import nc.vo.arap.utils.ArrayUtil;
import nc.vo.jzpm.wfm.WfDefBVO;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.uap.rbac.UserRoleVO;
import nc.vo.wfengine.core.activity.Activity;
import nc.vo.wfengine.core.participant.Participant;
import nc.vo.wfengine.core.workflow.BasicWorkflowProcess;
import nc.vo.wfengine.definition.WorkflowDefinitionVO;

public class GXF4NeizhuanCheckListener implements IBusinessListener {
	public void doAction(IBusinessEvent event) throws BusinessException {
		
		String souid = event.getSourceID();
		String type = event.getEventType();
		AggregatedValueObject[] bills = getBills(event);
		String cuserid = InvocationInfoProxy.getInstance().getUserId();
		SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
		BaseDAO dao = new BaseDAO();

		if("53e7cc81-a016-4d64-973b-d61fd647c7a2".equals(souid)){ //收款单
			if("1002".equals(type)){//新增后
				for (AggregatedValueObject aggregatedValueObject : bills) {
					AggGatheringBillVO aggvo = (AggGatheringBillVO) aggregatedValueObject;
					String billType = aggvo.getHeadVO().getPk_tradetype();
					if("F2-Cxx-01".equals(billType)) {
						List<WorkflowDefinitionVO> wfs = (List<WorkflowDefinitionVO>) dao.executeQuery(getQueryWFSQL(billType,cuserid), new BeanListProcessor(WorkflowDefinitionVO.class));
						if(wfs == null || wfs.size() == 0) {
//							throw new BusinessException("收款单（内转）【审批日期】不能大于【签字日期】!");
							return;
						}
						WorkflowDefinitionVO wfvo = wfs.get(0);
						
						List<WfDefBVO> defBVOs = transWF(wfvo);
						if(defBVOs != null && defBVOs.size() > 0) {
							List<String> err = new ArrayList<String>();
							for (WfDefBVO defBVO : defBVOs) {
								if("ROLE".equals(defBVO.getPartUnitType())) {
									String sql ="SELECT a.* "+ //b.USER_CODE,b.ENABLESTATE ,c.ROLE_CODE ,a.ENABLEDATE " + 
											"FROM sm_user_role a " + 
											"LEFT JOIN SM_USER b ON a.CUSERID = b.CUSERID " + 
											"LEFT JOIN SM_ROLE c ON a.PK_ROLE = c.PK_ROLE " + 
											"WHERE c.ROLE_CODE = '"+defBVO.getPartUnitCode()+"' AND nvl(b.dr,0) = 0 AND nvl(c.DR,0) = 0 " + 
											"AND b.ENABLESTATE = 2 AND a.ENABLEDATE > '"+format.format(new Date())+"' ";
									List<UserRoleVO> urvos = (List<UserRoleVO>) dao.executeQuery(sql, new BeanListProcessor(UserRoleVO.class));
									
									if(urvos == null || urvos.size() == 0) {
										err.add("【流程配置角色："+defBVO.getPartUnitCode()+",没有对应的用户！】");
									}
								}else if("RESPONSIBILITY".equals(defBVO.getPartUnitType())) {
									String sql ="SELECT a.* " + 
											"FROM sm_user_role a " + 
											"LEFT JOIN SM_USER b ON a.CUSERID = b.CUSERID " + 
											"LEFT JOIN SM_ROLE c ON a.PK_ROLE = c.PK_ROLE " + 
											"LEFT JOIN sm_perm_func d ON c.PK_ROLE = d.SUBJECTID " + 
											"LEFT JOIN sm_responsibility e ON d.RULEID = e.PK_RESPONSIBILITY " + 
											"WHERE e.CODE = '"+defBVO.getPartUnitCode()+"'  " + //职责编码
											"AND nvl(b.dr,0) = 0 AND nvl(c.DR,0) = 0 " + 
											"AND b.ENABLESTATE = 2 AND a.ENABLEDATE > '"+format.format(new Date())+"' ";
									List<UserRoleVO> urvos = (List<UserRoleVO>) dao.executeQuery(sql, new BeanListProcessor(UserRoleVO.class));
									
									if(urvos == null || urvos.size() == 0) {
										err.add("【流程配置职责："+defBVO.getPartUnitCode()+",没有对应的用户！】");
									}
								}
							}
							if(err.size() > 0) {
								throw new BusinessException(err.toString());
							}
						}
					}
				}
			}
		}
	}
	
	private List<WfDefBVO> transWF(WorkflowDefinitionVO wfvo) {
		BasicWorkflowProcess process = null;
		try {
			process = wfvo.getWorkflowProcess();
		} catch (Exception e) {
			e.printStackTrace();
			wfvo.getPk_wf_def();
		}
		if (process == null) {
			return null;
		}
		List acts = process.getActivities();
		List parts = process.getParticipants();
		if (parts != null && parts.size() > 0 && acts != null && acts.size() > 0) {
			Map<String,Participant> partMap = new HashMap<String,Participant>();
			for (Object part : parts) {
				Participant tmp = (Participant)part;
				partMap.put(tmp.getId(), tmp);
			}
			List<WfDefBVO> bvos = new ArrayList<WfDefBVO>();
			for (Object acttmp : acts) {
				Activity act = (Activity)acttmp;
				Participant part = partMap.get(act.getPerformer());
				if (part == null) {
					continue;
				}
				WfDefBVO bvo = new WfDefBVO();
				
				bvo.setHid("");
				bvo.setActivityId(act.getId());
				bvo.setActivityName(act.getName());
				bvo.setPartId(act.getPerformer());
				bvo.setPartType(part.getParticipantType().toString());
				bvo.setPartUnitId((String) part.getExtendedAttributes().get("OrganizeUnitPK"));
				bvo.setPartUnitType((String) part.getExtendedAttributes().get("OrganizeUnitType"));
				bvo.setPartUnitCode((String) part.getExtendedAttributes().get("OrganizeUnitCode"));
				bvo.setPartUnitOrg((String) part.getExtendedAttributes().get("OrganizeUnitBelongOrg"));
				
				if("ROLE".equals(bvo.getPartUnitType()) || "RESPONSIBILITY".equals(bvo.getPartUnitType())) {
					bvos.add(bvo);
				}
			}
			return bvos;
		}
		return null;
	}
	
	private String getQueryWFSQL(String billType,String cuserid) {
		String sql = "SELECT * FROM pub_wf_def WHERE BILLTYPE = 'F2-Cxx-01' AND workflow_type = 2 AND VALIDITY = 1 "
				+ "AND (BILLMAKER = '"+cuserid+"' OR BILLMAKER = 'ID_ALLBILLMAKER_ROLE') ORDER BY BILLMAKER ,VERSION desc";
		return sql;
	}
	
	private AggregatedValueObject[] getBills(IBusinessEvent event)
	{
	  Object object = null;
	  if ((event instanceof BusinessEvent)) {
	    BusinessEvent e = (BusinessEvent)event;
	    object = e.getObject();
	  } else if ((event instanceof BdUpdateEvent)) {
	    BdUpdateEvent e = (BdUpdateEvent)event;
	    object = e.getNewObject();
	  }
	  
	  AggregatedValueObject[] bills = null;
	  if (null != object) {
	    if (object.getClass().isArray()) {
	      bills = (AggregatedValueObject[])object;
	    } else {
	      bills = new AggregatedValueObject[1];
	      bills[0] = ((AggregatedValueObject)object);
	    }
	  }
	  return bills;
	}
	
	private BaseAggVO[] getBills_skd(IBusinessEvent event) {
		Object value = null;
		if (event instanceof BusinessEvent) {
			value = ((BusinessEvent) event).getObject();
		} else if (event instanceof BdUpdateEvent) {
			value = ((BdUpdateEvent) event).getNewObject();
		}

		BaseAggVO[] bills = null;
		if (null == value) {

		} else if (value.getClass().isArray()) {
			Object[] objs = (Object[]) value;
			bills = (objs instanceof BaseAggVO[]) ? (BaseAggVO[]) objs : ArrayUtil.convertSupers2Subs((AggregatedValueObject[]) objs, BaseAggVO.class);
		} else {
			bills = new BaseAggVO[1];
			bills[0] = (BaseAggVO) value;
		}

		return bills;
	}
}
