package nc.impl.om.eventlistener;

import java.io.ByteArrayInputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;

import nc.bs.arap.util.NCToMyXmlUtil;
import nc.bs.businessevent.IBusinessEvent;
import nc.bs.businessevent.IBusinessListener;
import nc.bs.businessevent.bd.BDCommonEvent;
import nc.bs.framework.common.NCLocator;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.BeanProcessor;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.vo.esb.EsbInfoAnnotatioVO;
import nc.vo.esb.QueryInfoVO;
import nc.vo.esb.RequestDeptInfoVO;
import nc.vo.esb.RequestDeptToEsbVO;
import nc.vo.esb.ResultFinanceDeptFramMyToNcVO;
import nc.vo.org.DeptVO;
import nc.vo.pub.BusinessException;
import nccloud.commons.lang.ArrayUtils;
import nccloud.commons.lang.StringUtils;



/**
 * @author libx3/李炳雄
 * @date 2019-3-29 下午19:30:47
 * @Description:NC部门增删改保存时同步到明源
 *
 */
public class SynNCFinanceDeptManagerListener implements IBusinessListener {
	
	public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
	
	private final  String EVENT_ADD = "1002"; //新增
	private final  String EVENT_EDIT = "1004"; //修改
	private final  String EVENT_DELETE = "1006"; //删除
	//add by zhengfyao3@郑瑶 增加插件类型 2019年4月4日12:01:17
	private final  String EVENT_DELETEBEFORE = "1005"; //删除
	private final  String EVENT_FIRSTENABLE = "1067"; //未启用变成启用
	private final  String EVENT_DISTENABLE = "1069"; //启用变停用
	private final  String EVENT_ENABLE = "1071"; //停用变启用
	
	@Override
	public void doAction(IBusinessEvent event) throws BusinessException {
		BDCommonEvent.BDCommonUserObj userObj = (BDCommonEvent.BDCommonUserObj) event.getUserObject();
		Object newObj = userObj.getNewObjects();
		Object oldObj = userObj.getOldObjects();
		if(newObj.getClass().isArray()) {
			Object[] newVOs = (Object[])newObj;
			Object[] oldVOs = (Object[])oldObj;
			if(ArrayUtils.isEmpty(newVOs)) {
				return;
			}
			String oldPrincipal = "";
			if(!ArrayUtils.isEmpty(oldVOs)) {
				oldPrincipal = ((DeptVO)oldVOs[0]).getPrincipal();
			}
			String newPrincipal = ((DeptVO)newVOs[0]).getPrincipal();
			if((!StringUtils.isEmpty(newPrincipal)) && (!StringUtils.isEmpty(oldPrincipal)) && newPrincipal.equalsIgnoreCase(oldPrincipal)) {
				return;
			}
			String eventType = event.getEventType();
			String MsgType = "1";//更新,新增,删除都传1
			//add by zhengfyao3@郑瑶 删除前调用明源 2019年4月4日12:01:17
			//update by zhengyao3@郑瑶 2019年4月4日17:14:16 删除部门时传递给明源停用标识 begin
			//update by zhengyao3@郑瑶  2019年4月8日16:25:54 增加字段 begin
			for(Object deptVO: newVOs){
				DeptVO newDeptVO = (DeptVO)deptVO;
				String pk_dept = newDeptVO.getPk_dept();
				//add by 黄冠华 40331 【联测】无法新增保存部门节点 ,添加新字段部门属性以及部门属性编码和  begin
				//update by zhengyao3@郑瑶 2019年4月23日17:36:11 修正原有sql，不需要去联查财务组织表，只需要联查org_orgs表 begin
				String sql = "select d1.pk_dept NC_PK_Dept,d1.code DepartmentCode,d1.name DepartmentName,d2.pk_dept FatherDepartmentPK," +
						" d2.code FatherDepartmentCode,d2.name FatherDepartmentName,o1.code FinanceCode,o1.name FinanceName," +
						" def.code BUGUID,def.name Area,d1.enablestate Enabledstate,d1.modifiedtime UpdateDate,d1.modifier modifier," +
						" o2.code ParentFinanceCode,o2.name ParentFinanceName,d1.creationtime CreateDate,'' HtTypeDepartmentName,doc2.code DepartmentPropertyCode,doc2.name DepartmentPropertyName from org_dept d1 " +
						" left join org_dept d2 on d1.pk_fatherorg=d2.pk_dept " +
						" left join org_orgs o1 on d1.pk_org=o1.pk_org " +
						" left join org_orgs o2 on o1.pk_fatherorg=o2.pk_org " +
						" left join bd_defdoc def on o1.def11=def.pk_defdoc " +
						" left join bd_defdoc doc2 on  d1.def20=doc2.pk_defdoc "+
						" where d1.pk_dept='" + pk_dept+"'";
				//update by zhengyao3@郑瑶 2019年4月23日17:36:11 修正原有sql，不需要去联查财务组织表，只需要联查org_orgs表 end
				//add by 黄冠华 40331 【联测】无法新增保存部门节点 end
				IUAPQueryBS bs = NCLocator.getInstance().lookup(IUAPQueryBS.class);
				RequestDeptInfoVO requestDeptInfoVO = (RequestDeptInfoVO) bs.executeQuery(sql, new BeanProcessor(RequestDeptInfoVO.class));
				if(requestDeptInfoVO == null){
					throw new BusinessException("新增修改删除部门传递明源报错,查询不到对应部门!");
				}
				
				//add by 陈志威 2019-12-11 限制组织为物业板块下的组织 begin
				//update by zhengyao3@郑瑶 部门传递按照自定义档案下面的版块进行传递 2020年6月28日17:16:46 begin
		        //String queryorgsql = "select pk_org from org_orgs where isbusinessunit = 'Y' and code = '" + requestDeptInfoVO.getFinanceCode() + "' start with pk_org = '0001H21000000000G2RL' connect by prior pk_org = pk_fatherorg";
				String queryorgsql = new StringBuilder("SELECT PK_ORG")
				.append("  FROM ORG_ORGS")
				.append(" WHERE ISBUSINESSUNIT = 'Y'")
				.append("   AND CODE = '" + requestDeptInfoVO.getFinanceCode() + "'")
				.append("  START WITH PK_ORG IN (SELECT T3.PK_ORG ")
				.append("                         FROM BD_DEFDOC T1 ")
				.append("                         LEFT JOIN BD_DEFDOCLIST T2 ")
				.append("                           ON T1.PK_DEFDOCLIST = T2.PK_DEFDOCLIST ")
				.append("                         LEFT JOIN ORG_ORGS T3 ")
				.append("                           ON T3.CODE = T1.CODE ")
				.append("                          AND T3.ISBUSINESSUNIT = 'Y' ")
				.append("                        WHERE T2.CODE = 'BGY-MY01') ")
				.append(" CONNECT BY PRIOR PK_ORG = PK_FATHERORG ").toString();
				//update by zhengyao3@郑瑶 部门传递按照自定义档案下面的版块进行传递 2020年6月28日17:16:46 end
				String pk_org = (String) bs.executeQuery(queryorgsql, new ColumnProcessor());
		        if(pk_org == null) {
		        	return;
		        }
				//add by 陈志威 2019-12-11 限制组织为物业板块下的组织 end
				//update by zhengyao3@郑瑶 2019年4月8日16:25:54 增加字段 end
				if(EVENT_DELETE.equals(eventType) || EVENT_DELETEBEFORE.equals(eventType)){
					requestDeptInfoVO.setEnabledstate(3);//删除时传递停用标识
				}
				//update by zhengyao3@郑瑶 2019年4月4日17:14:16 删除部门时传递给明源停用标识 end
				requestDeptInfoVO.setMsgType(MsgType);
				RequestDeptToEsbVO ruquestVO = getEsbVO(requestDeptInfoVO);
				String xml = EsbVOToXML(ruquestVO);
				String resultXML = NCToMyXmlUtil.sendXMLToMy(xml, "NC-MY-FY-001", ruquestVO.getRequestDeptInfo().getNC_PK_Dept());
				ResultFinanceDeptFramMyToNcVO resultEsbXmlToNcVo = getResultEsbXmlToNcVo(resultXML);
				if(resultEsbXmlToNcVo != null){
					EsbInfoAnnotatioVO esbInfo = resultEsbXmlToNcVo.getEsbInfo();
					if(!"S".equals(esbInfo.getReturnStatus())) {
						throw new BusinessException("同步明源错误，错误为: " + esbInfo.getReturnMsg());
					}
				}
			}
		}
	}
	
	/**
	 * 传到明源的VO转XML
	 * @param ruquestVO
	 * @return
	 */
	private String EsbVOToXML(RequestDeptToEsbVO ruquestVO){
		XStream x = new XStream(new DomDriver("utf-8", new XmlFriendlyNameCoder("_-", "_")));
		x.autodetectAnnotations(true);
		x.processAnnotations(RequestDeptToEsbVO.class);
		x.aliasAttribute("NC_PK_Dept", "NC_PK_Dept");
		return x.toXML(ruquestVO);
	}
	
	/**
	 * 获取调用明源的VO，后续转XML
	 * @param requestDeptInfoVO
	 * @return
	 */
	private RequestDeptToEsbVO getEsbVO(RequestDeptInfoVO requestDeptInfoVO){
		RequestDeptToEsbVO RequestDeptToEsbVO = new RequestDeptToEsbVO();
		EsbInfoAnnotatioVO esbInfo = new EsbInfoAnnotatioVO();
		QueryInfoVO queryInfo = new QueryInfoVO();
		Date date = Calendar.getInstance().getTime();// 获取当前时间
		// 设置请求时间
		esbInfo.setRequestTime(dateFormat.format(date));
		esbInfo.setInstId(UUID.randomUUID().toString());// 使用UUID作为流水号
		RequestDeptToEsbVO.setEsbInfo(esbInfo);
		RequestDeptToEsbVO.setQueryInfo(queryInfo);
		RequestDeptToEsbVO.setRequestDeptInfo(requestDeptInfoVO);
		return RequestDeptToEsbVO;
	}
	
	/**
	 * 解析明源返回的XML数据，转成NC的VO
	 * @param resultXML
	 * @return
	 * @throws BusinessException
	 */
	private ResultFinanceDeptFramMyToNcVO getResultEsbXmlToNcVo(String resultXML) throws BusinessException {
		SAXReader reader = new SAXReader();
		Document document = null;
		Element resultElement = null;
		try {
			document = reader.read(new ByteArrayInputStream(resultXML.getBytes("UTF-8")));
			Element rootElement = document.getRootElement();
			if(rootElement == null) {
				throw new BusinessException("调用明源接口信息异常,请联系用友顾问查看日志!!日志表名 sap_po_log");
			}
			resultElement = rootElement.element("Body").
					element("FinanceDepartmentFramNCResponse").
					element("FinanceDepartmentFramNCResult");
		} catch (Exception e) {
			throw new BusinessException("调用明源接口信息异常,请联系用友顾问查看日志!!日志表名 sap_po_log");
		}
		if(resultElement == null) {
			throw new BusinessException("调用明源接口信息异常,请联系用友顾问查看日志!!日志表名 sap_po_log");
		}
		XStream xStream = new XStream();
		xStream.alias("FinanceDepartmentFramNCResult", ResultFinanceDeptFramMyToNcVO.class);
		xStream.alias("esbInfo", EsbInfoAnnotatioVO.class);
		ResultFinanceDeptFramMyToNcVO NcVo = (ResultFinanceDeptFramMyToNcVO) xStream.fromXML(resultElement.asXML());
		return NcVo;
	}
	
}
