package ncc.bs.wy.tools;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import nc.md.data.access.NCObject;
import nc.md.model.IAttribute;
import nc.vo.arap.payable.PayableBillItemVO;
import nc.vo.cmp.bill.RecBillDetailVO;
import nc.vo.cmp.bill.RecBillVO;
import nc.vo.ep.bx.BXVO;
import nc.vo.erm.costshare.CShareDetailVO;
//import nc.vo.gpm.guarantee.prop.AggGuaPropertyVO;
//import nc.vo.gpm.guarantee.prop.GuaPropertyVO;
import nc.vo.ic.m45.entity.PurchaseInBodyVO;
import nc.vo.ic.m45.entity.PurchaseInHeadVO;
import nc.vo.jcom.lang.StringUtil;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.IAttributeMeta;
import nc.vo.pub.SuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nc.vo.pubapp.pattern.model.meta.entity.vo.Attribute;
import uap.json.JSONArray;
import uap.json.JSONObject;

/**
 * @Description: SAP系统传输JSON数据转换成AggVO工具类
 * @author 钟忠 【碧桂园SAP接口专项】
 * @date 2018-4-12
 * @version with NC V6.3
 */
public class WyWGPTJsonTools {
	private Map<String, IAttribute> attrMap=null;
	private WyWGPTJsonTools() {
	}
	
	/**新建的方法，用于转换明源税务系统业务数据
	 * @author 符耀铭
	 * @time 2020-3-3
	 * @param billdata
	 * @param aggVOClass
	 * @param headVOClass
	 * @param headerVO
	 * @param bodyVOClass
	 * @param itemVOs
	 * @param TableVOClass
	 * @param taxOffsetVOs
	 * @return
	 * @throws Exception
	 */
//	public static void jsonToMultiBody(Object billdata,Class<? extends AbstractBill> aggVOClass,Class<? extends CircularlyAccessibleValueObject> headVOClass, SYMYTaxHeaderVO headerVO, Class<? extends CircularlyAccessibleValueObject> bodyVOClass,List<SYMYTaxItemVO> itemVOs,Class<? extends CircularlyAccessibleValueObject> TableVOClass,List<SYMYTaxOffsetVO> taxOffsetVOs) throws Exception{
//		JSONObject data=new JSONObject();
//		if(billdata instanceof String){
//			JSONObject jsonObj = new JSONObject((String)billdata);
//			data = (JSONObject) jsonObj.get("requestInfo");
//		}else if(billdata instanceof JSONObject){
//			data=(JSONObject)billdata;
//		}
//		AggregatedValueObject aggVo = null;
//		try {
//			if(data == null||StringUtil.isEmptyWithTrim(data.toString())) {
//				return;
//			}
//			CircularlyAccessibleValueObject headVO;
//			CircularlyAccessibleValueObject[] bodyVOs;
//			CircularlyAccessibleValueObject bodyVO;
//			JSONObject bodyJsonObj;
//			JSONArray orderPayPlan;
//			JSONObject requestInfo =(JSONObject) data.get("requestInfo");
//			JSONObject head = (JSONObject) requestInfo.get("Header");
//			JSONArray bodyitems;
//			boolean isExistCJBusiData =requestInfo.isNull("CJBusiData");
//			boolean isExistItems = requestInfo.isNull("Items");
//			if (head == null) {
//				return;
//			}
//				setValue(headVOClass,headerVO,head);
//			//表体VO
//			if(!isExistItems){
//				bodyitems = (JSONArray) requestInfo.get("Items");
////				itemVOs =(SYMYTaxItemVO[]) Array.newInstance(bodyVOClass,bodyitems.length());
//				for (int j = 0; j < bodyitems.length(); j++) {
//					bodyJsonObj = (JSONObject) bodyitems.get(j);
//					if (bodyJsonObj == null) {
//						continue;
//					}
//					bodyVO = bodyVOClass.newInstance();
//					//表体设值
//					if(bodyVO instanceof RecBillDetailVO || bodyVO instanceof PurchaseInBodyVO){//modify by 符耀铭 2019-7-15 添加采购入库单
//						setRecValue(bodyVOClass, bodyVO, bodyJsonObj);
//					}else{
//						setValue(bodyVOClass, bodyVO, bodyJsonObj);	
//					}
//
//					itemVOs.add((SYMYTaxItemVO) bodyVO);
//				}
////				aggVo.setChildrenVO(bodyVOs);
//			}
//			//订单付款计划
//			if(!isExistCJBusiData){
//				orderPayPlan = (JSONArray) requestInfo.get("CJBusiData");
//				if(orderPayPlan!=null && orderPayPlan.length()>0){
//					for (int b = 0; b < orderPayPlan.length(); b++) {
//						bodyJsonObj = (JSONObject) orderPayPlan.get(b);
//						if (bodyJsonObj == null) {
//							continue;
//						}
//						bodyVO = TableVOClass.newInstance();
//						//				//表体设值
//						if(bodyVO instanceof RecBillDetailVO){
//							setRecValue(TableVOClass, bodyVO, bodyJsonObj);
//						}else{
//							setValue(TableVOClass, bodyVO, bodyJsonObj);	
//						}
//						
//						taxOffsetVOs.add((SYMYTaxOffsetVO) bodyVO);
//					}
//				}
//			}
//		} catch (Exception e) {
//			throw new Exception("json参数转换AggVO出错 ！"+ e.getMessage());
//		}
//	}
	
	/** 二开新加方法,json格式转换成多页签的AggVO
	 * @author 符耀铭
	 * @time 2019-3-12
	 * @param billdata
	 * @param aggVOClass
	 * @param headVOClass
	 * @param bodyVOClass
	 * @param TableVOClass
	 * @return
	 * @throws Exception
	 */
	public static <T extends AbstractBill> T jsonToOrderVO(Object billdata,Class<? extends AbstractBill> aggVOClass, Class<? extends CircularlyAccessibleValueObject> headVOClass, Class<? extends CircularlyAccessibleValueObject> bodyVOClass,Class<? extends CircularlyAccessibleValueObject> TableVOClass) throws Exception{

		JSONObject data=new JSONObject();
		if(billdata instanceof String){
			JSONObject jsonObj = new JSONObject((String)billdata);
			data = (JSONObject) jsonObj.get("requestInfo");
		}else if(billdata instanceof JSONObject){
			data=(JSONObject)billdata;
		}
		T aggVo = null;
		try {
			if(data == null||StringUtil.isEmptyWithTrim(data.toString())) {
				return null;
			}
			aggVo = (T) aggVOClass.newInstance();
			CircularlyAccessibleValueObject headVO;
			CircularlyAccessibleValueObject[] bodyVOs;
			CircularlyAccessibleValueObject bodyVO;
			JSONObject bodyJsonObj;
			JSONArray orderPayPlan;
			JSONObject requestInfo =(JSONObject) data.get("requestInfo");
			JSONObject head = (JSONObject) requestInfo.get("Header");
			JSONArray bodyitems;
			boolean isExistPayplan =requestInfo.isNull("OrderPayPlan");
			boolean isExistItems = requestInfo.isNull("Items");
			if (head == null) {
				return null;
			}
			headVO = headVOClass.newInstance();
			//表头设值
			if(headVO instanceof RecBillVO || headVO instanceof PurchaseInHeadVO){//modify by 符耀铭 2019-7-15 添加采购入库单
				setRecValue(headVOClass,headVO,head);
			}else{
				setValue(headVOClass,headVO,head);
			}			
			//表体VO
			if(!isExistItems){
				bodyitems = (JSONArray) requestInfo.get("Items");
				bodyVOs =(CircularlyAccessibleValueObject[]) Array.newInstance(bodyVOClass,bodyitems.length());
				for (int j = 0; j < bodyitems.length(); j++) {
					bodyJsonObj = (JSONObject) bodyitems.get(j);
					if (bodyJsonObj == null) {
						continue;
					}
					bodyVO = bodyVOClass.newInstance();
					//表体设值
					if(bodyVO instanceof RecBillDetailVO || bodyVO instanceof PurchaseInBodyVO|| bodyVO instanceof PayableBillItemVO){//modify by 符耀铭 2019-7-15 添加采购入库单//modify by 符耀铭 2019-9-3 添加应付单
						setRecValue(bodyVOClass, bodyVO, bodyJsonObj);
					}else{
						setValue(bodyVOClass, bodyVO, bodyJsonObj);	
					}

					bodyVOs[j] = bodyVO;
				}
				aggVo.setChildrenVO(bodyVOs);
			}
			//订单付款计划
			if(!isExistPayplan){
				orderPayPlan = (JSONArray) requestInfo.get("OrderPayPlan");
				if(orderPayPlan!=null && orderPayPlan.length()>0){
					bodyVOs =(CircularlyAccessibleValueObject[]) Array.newInstance(TableVOClass,orderPayPlan.length());
					
					for (int b = 0; b < orderPayPlan.length(); b++) {
						bodyJsonObj = (JSONObject) orderPayPlan.get(b);
						if (bodyJsonObj == null) {
							continue;
						}
						bodyVO = TableVOClass.newInstance();
						//				//表体设值
						if(bodyVO instanceof RecBillDetailVO){
							setRecValue(TableVOClass, bodyVO, bodyJsonObj);
						}else{
							setValue(TableVOClass, bodyVO, bodyJsonObj);	
						}
						
						bodyVOs[b] = bodyVO;
					}
					//付款计划
					aggVo.setTableVO("po_order_payplan", bodyVOs);
				}
			}
			aggVo.setParentVO(headVO);


		} catch (Exception e) {
			throw new Exception("json参数转换AggVO出错 ！"+ e.getMessage());
		}
		return aggVo;
	}
	/**
	 * JSON转换担保物权aggvo
	 * @param guaPropertys
	 * @param aggVOClass
	 * @param headVOClass
	 * @return
	 * @throws Exception
	 */
//	@SuppressWarnings("unchecked")
//	public static AggGuaPropertyVO jsonToGPAggVO (com.alibaba.fastjson.JSONObject headJsonObj,AggGuaPropertyVO aggVOClass, GuaPropertyVO headVOClass)throws Exception{
//		//获取sap-nc的sap编码和nc的编码
//		HashMap<String,String> tranNCcodeMap=SapUtils.getTranNCcodes(SapConstants.GUAPROPERTY_CODEH,SapConstants.DIRECTION_SAP2NC);				
//		try {				
//			CircularlyAccessibleValueObject headVO;						
//			if (headJsonObj == null) {
//				return null;
//			}			
//			AggGuaPropertyVO aggvo=new AggGuaPropertyVO();;														
//			//将json里的sap编码转换为nc的编码
//			Set<String> sap_code=tranNCcodeMap.keySet();
//			HashMap<String,String> head=new HashMap<String,String>();
//			HashMap<String,String> oldhead=new HashMap<String,String>();
//			if(sap_code!=null&&sap_code.size()>0){
//				String value;
//				for(String sap:sap_code){
//					Object obj=oldhead.get(sap.toLowerCase());
//					if(null==obj){
//						value=null;
//					}else{
//						value=obj.toString();	
//					}
//
//					if(value!=null){
//						if("ztzrq".equalsIgnoreCase(sap.trim())||"zrq".equalsIgnoreCase(sap.trim())||"zqrrq".equalsIgnoreCase(sap.trim())){
//							value=value.substring(0,4)+"-"+value.substring(4,6)+"-"+value.substring(6,8)+" 00:00:00";
//						}
//						head.put(tranNCcodeMap.get(sap),value.trim());													
//					}					
//				}
//			}				
//			uap.json.JSONObject headObj=new uap.json.JSONObject(head); 				
//			headVO =new GuaPropertyVO();				
//			//表头设值				
//			setValue(GuaPropertyVO.class,headVO,headObj);
//			//组装AggVO	
//			aggvo.setParentVO(headVO);						
//			SapUtils.notNullCheckAndExFormula(SapConstants.GUAPROPERTY_CODEH,null,aggvo);//执行公式
//			return aggvo;
//		} catch (Exception e) {
//			throw e;
//		}
//
//	}
	public static <T extends AggregatedValueObject> T jsonToAggVO (
			Object billdata,Class<? extends AggregatedValueObject> aggVOClass, Class<? extends CircularlyAccessibleValueObject> headVOClass, Class<? extends CircularlyAccessibleValueObject> bodyVOClass)throws Exception{		
		JSONObject data=new JSONObject();	
		if(billdata instanceof String){
			JSONObject jsonObj = new JSONObject((String)billdata);
			data = (JSONObject) jsonObj.get("data");
		}else if(billdata instanceof JSONObject){
			data=(JSONObject)billdata;
		}
		T aggVO = null;
		try {
			if(data == null||StringUtil.isEmptyWithTrim(data.toString())) {
				return null;
			}
			aggVO = (T) aggVOClass.newInstance();
			CircularlyAccessibleValueObject headVO;
			CircularlyAccessibleValueObject[] bodyVOs;
			CircularlyAccessibleValueObject bodyVO;
			JSONObject bodyJsonObj;
			JSONObject head = (JSONObject) data.get("headitem");
			JSONArray bodyitems = (JSONArray) data.get("bodyitems");			
			if (head == null || bodyitems == null) {
				return null;
			}
			headVO = headVOClass.newInstance();
			//表头设值
			if(headVO instanceof RecBillVO){
				setRecValue(headVOClass,headVO,head);
			}else{
				setValue(headVOClass,headVO,head);
			}			
			//表体VO
			bodyVOs =(CircularlyAccessibleValueObject[]) Array.newInstance(bodyVOClass,bodyitems.length());
			for (int j = 0; j < bodyitems.length(); j++) {
				bodyJsonObj = (JSONObject) bodyitems.get(j);
				if (bodyJsonObj == null) {
					continue;
				}
				bodyVO = bodyVOClass.newInstance();
				//表体设值
				if(bodyVO instanceof RecBillDetailVO){
					setRecValue(bodyVOClass, bodyVO, bodyJsonObj);
				}else{
					setValue(bodyVOClass, bodyVO, bodyJsonObj);	
				}

				bodyVOs[j] = bodyVO;
			}
			//组装AggVO
			aggVO.setParentVO(headVO);
			if(aggVO instanceof BXVO){
				((nc.vo.ep.bx.BXVO)aggVO).setcShareDetailVo((CShareDetailVO[])bodyVOs);
			}else{
				aggVO.setChildrenVO(bodyVOs);	
			}
		} catch (Exception e) {
			throw new Exception("json参数转换AggVO出错 ！"+ e.getMessage());
		}

		return aggVO;
	}
	/**
	 * VO设值
	 * @param voClass
	 * @param vo
	 * @param jaonObject
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected static void setValue(Class<? extends CircularlyAccessibleValueObject> voClass,CircularlyAccessibleValueObject vo, JSONObject jaonObject) {
		Field[] headFields = voClass.getFields();
		Iterator<String> it;
		String attributeName;
		Object value;
		it = (Iterator<String>) jaonObject.keys();
		while (it.hasNext()) {
			attributeName = it.next();
			if (StringUtil.isEmptyWithTrim(attributeName)) {
				continue;
			}
			value = jaonObject.get(attributeName);
			if (value == null || StringUtil.isEmptyWithTrim(value.toString())) {
				continue;
			}
			if ("bbje".equalsIgnoreCase(attributeName)|| "assume_amount".equalsIgnoreCase(attributeName)) {
				vo.setAttributeValue(attributeName,new UFDouble(value.toString()));
			}else if ("rowno".equalsIgnoreCase(attributeName)) {
				vo.setAttributeValue(attributeName,Integer.parseInt(value.toString()));
			}
			else {
				for (int j = 0; j < headFields.length; j++) {
					Field field = headFields[j];
					if (headFields[j].getName().equalsIgnoreCase(attributeName)) {
						Class type = field.getType();
						if (type == String.class) {
							vo.setAttributeValue(attributeName, value);
						} else if (type == Integer.class) {
							vo.setAttributeValue(attributeName,
									Integer.parseInt(value.toString()));
						} else if (type == UFDouble.class) {
							vo.setAttributeValue(attributeName, new UFDouble(
									value.toString()));
						} else if (type == UFBoolean.class) {
							vo.setAttributeValue(attributeName, new UFBoolean(
									value.toString()));
						} else if (type == UFDate.class) {
							vo.setAttributeValue(attributeName, new UFDate(
									value.toString()));
						} else if (type == UFDateTime.class) {							
							vo.setAttributeValue(attributeName, new UFDateTime(
									value.toString()));															
						} else {
							vo.setAttributeValue(attributeName, value);
						}
						break;
					}
				}
			}
		}
		//VO状态
		vo.setStatus(VOStatus.NEW);
	}
	/**
	 * 内转单VO设值
	 * @param voClass
	 * @param vo
	 * @param jaonObject
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	@SuppressWarnings({ "unchecked"})
	protected static void setRecValue(Class<? extends CircularlyAccessibleValueObject> voClass,CircularlyAccessibleValueObject vo, JSONObject jaonObject) throws InstantiationException, IllegalAccessException {
		CircularlyAccessibleValueObject recvo;
		recvo=voClass.newInstance();				
		nc.vo.pubapp.pattern.model.meta.entity.vo.ModelVOMeta model =
				(nc.vo.pubapp.pattern.model.meta.entity.vo.ModelVOMeta)((SuperVO)recvo).getMetaData();
		IAttributeMeta[] iMeta = model.getAttributes();
		Iterator<String> it;
		String attributeName;
		Object value;
		it = (Iterator<String>) jaonObject.keys();
		while (it.hasNext()) {
			attributeName = it.next();
			if (StringUtil.isEmptyWithTrim(attributeName)) {
				continue;
			}
			value = jaonObject.get(attributeName);
			if (value == null || StringUtil.isEmptyWithTrim(value.toString())) {
				continue;
			}
			for (int j = 0; j < iMeta.length; j++) {										
				Attribute field=(Attribute)iMeta[j];
				String  attriname=field.getName();
				nc.vo.pub.JavaType type=field.getJavaType();												
				if (attributeName.equalsIgnoreCase(attriname.trim())) {			
					if (type.name().equals("String")) {
						vo.setAttributeValue(attributeName, value);
					} else if (type.name().equals("Integer")) {
						vo.setAttributeValue(attributeName,
								Integer.parseInt(value.toString()));
					} else if (type.name().equals("UFDouble")) {
						vo.setAttributeValue(attributeName, new UFDouble(
								value.toString()));
					} else if (type.name().equals("UFBoolean")) {
						vo.setAttributeValue(attributeName, new UFBoolean(
								value.toString()));
					} else if (type.name().equals("UFDate")) {
						vo.setAttributeValue(attributeName, new UFDate(
								value.toString()));
					} else if (type.name().equals("UFDateTime")) {
						vo.setAttributeValue(attributeName, new UFDateTime(
								value.toString()));
					} else {
						vo.setAttributeValue(attributeName, value);
					}
					break;
				}
			}
		}
		//VO状态
		vo.setStatus(VOStatus.NEW);
	}
	
	public Map getAttrMap(AggregatedValueObject vo){
		if(attrMap==null){
			attrMap=new HashMap<String, IAttribute>();
			List<IAttribute> attributes=NCObject.newInstance(vo).getRelatedBean().getAttributesOfModel();
			
		 for (Iterator<IAttribute> iter = attributes.iterator(); iter.hasNext();) {
            IAttribute i = iter.next();
            attrMap.put(i.getName(), i);
        }
		}
		return attrMap;
		
	}

}
