package nc.bs.hbbb.contrast.rightandInterest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.itf.corg.IStockInvestRelaQryService;
import nc.itf.hbbb.hbrepstru.HBRepStruUtil;
import nc.jdbc.framework.SQLParameter;
import nc.pub.iufo.exception.UFOSrvException;
import nc.util.hbbb.pub.HBPubItfService;
import nc.vo.corg.StockInvestRelaVO;
import nc.vo.org.CorpVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.vorg.ReportCombineStruMemberVersionVO;

import com.ufida.iufo.pub.tools.AppDebug;


public abstract class RightAndInterestType {

	public abstract boolean needContrast() throws BusinessException;

	private IStockInvestRelaQryService qryservice=null;
	String pk_self;
	String pk_other;
	UFDate endata;
	//报表合并体系版本主键
	String pk_rms;
	//jiaah 增加股权投资方案
	String pk_investscheme;
	

	public RightAndInterestType(String new_pk_self, String new_pk_other,
			 UFDate newendata, String new_pk_rms,String pk_investscheme) {
		this.pk_self = new_pk_self;
		this.pk_other = new_pk_other;
		this.endata = newendata;
		this.pk_rms = new_pk_rms;
		this.pk_investscheme = pk_investscheme;
	}

	//进行虚单位判断
	@SuppressWarnings({ "unchecked"})
	public static boolean checkVoidOrg(String[] orgs, String pk_org, String pk_rms)
			throws BusinessException {
		boolean result = false;
		BaseDAO dao = new BaseDAO();

		ReportCombineStruMemberVersionVO tvo = HBRepStruUtil.getRepManStrMemberVO(pk_org, pk_rms);
		Set<String> orgset = new HashSet<String>();
		for (String org : orgs) {
			orgset.add(org);
		}
		if (null != tvo.getIsmanageorg() && tvo.getIsmanageorg().booleanValue()) {// 判断是否是虚单位
			// 是虚组织需要判断对应的实体组织也在对账单位对里
			if (orgset.contains(tvo.getPk_entityorg())) { // 存在则参与对帐
				return true;
			}
		} else {
			// 是实组织则需要判断是否在对帐单位对里有虚单位对应本实体单位
			StringBuilder scontent = new StringBuilder();
			scontent.append(" pk_svid=?  and pk_entityorg=? and isnull(dr,0)=0 ");
			SQLParameter params1 = new SQLParameter();
			params1.addParam(pk_rms);
			params1.addParam(pk_org);
			Collection<ReportCombineStruMemberVersionVO> list1 = dao.retrieveByClause(ReportCombineStruMemberVersionVO.class, scontent.toString(), params1);
			if (null == list1 || list1.size() == 0) { // 没有虚单位，则参与对帐
				return true;
			} else {
				ReportCombineStruMemberVersionVO tvoidorg = list1.toArray(new ReportCombineStruMemberVersionVO[0])[0];
				if (orgset.contains(tvoidorg.getPk_org())) {// 存在虚单位且还在对帐单位对里则不参与对帐
					return false;
				} else {// 存在虚单位且但不在对帐单位对里则参与对帐
					return true;
				}

			}
		}
		return result;
	}

	public String getPk_other() {
		try {
			// 只有当虚单位对应的实体做为被投资方时，才有虚单位之说
			ReportCombineStruMemberVersionVO rmsvo = HBRepStruUtil.getRepManStrMemberVO(pk_other, this.getPk_rms());
			if (null != rmsvo.getIsmanageorg()&& rmsvo.getIsmanageorg().booleanValue() ) { // 是虚单位
				if(null != rmsvo.getPk_entityorg()){
					UFDouble value = HBPubItfService.getRemoteStockInvestRelaSrv().getInvestdataSum(pk_self, rmsvo.getPk_entityorg(),
							endata.toStdString(),pk_investscheme);
					if (null != value && value.toDouble() > 0) {
						return rmsvo.getPk_entityorg();
					}
				}
			}
			else{
				//实单位，并且有对应的虚单位存在
				if(rmsvo.getPk_entityorg()!= null){
					ReportCombineStruMemberVersionVO xuVO = HBRepStruUtil.getRepManStrMemberVO(rmsvo.getPk_entityorg(), this.getPk_rms());
						if(xuVO != null){
							return null;
						}
				}
			}
		} catch (BusinessException e) {
			AppDebug.debug(e);
			return null;
		} 
		return pk_other;
	}
	

	public String getPk_self() {
		return pk_self;
	}

	// 存在投资关系
	public boolean existInvest() throws BusinessException {
		// 只有当虚单位对应的实体做为被投资方时，才有虚单位之说
		ReportCombineStruMemberVersionVO rmsvo = HBRepStruUtil.getRepManStrMemberVO(pk_other,this.getPk_rms());
		if (null != rmsvo.getIsmanageorg()&& rmsvo.getIsmanageorg().booleanValue()) { // 是虚单位
			if (null == rmsvo.getPk_entityorg()||rmsvo.getPk_entityorg().trim().length() == 0) {
				return false;
			} else {
				UFDouble value = HBPubItfService.getRemoteStockInvestRelaSrv().getInvestdataSum(pk_self, rmsvo.getPk_entityorg(),endata.toString(),pk_investscheme);
				if (null != value && value.toDouble() > 0) {
					return true;
				}
			}
		} else {
			UFDouble value = HBPubItfService.getRemoteStockInvestRelaSrv().getInvestdataSum(pk_self, pk_other, endata.toString(),pk_investscheme);
			if (null != value && value.toDouble() > 0) {
				return true;
			}
		}

		return false;
	}

	/**
	 * 獲得所有股權投之關係，按照本對方進行匯總
	 * @create by zhoushuang at 2014-11-21,下午4:44:32
	 *
	 * @return
	 * @throws UFOSrvException
	 */
	@SuppressWarnings("unchecked")
	private StockInvestRelaVO[] getStockInvestRela() throws UFOSrvException {
		 //根据条件查询数据
		StringBuilder whereSql = new StringBuilder();
		whereSql.append("investee = ? and pk_investscheme = ? and investdate<=? and investor in (select pk_org from org_rcsmember_v where pk_svid = ? )");
		SQLParameter parameter = new SQLParameter();
		parameter.addParam(this.getPk_other());
		parameter.addParam(this.getPk_investscheme());
		parameter.addParam(this.getEndata().toString());
		parameter.addParam(getPk_rms());
	    try {
	    	BaseDAO baseDao = new BaseDAO();
	    	Collection<StockInvestRelaVO> vosList = baseDao.retrieveByClause(StockInvestRelaVO.class, whereSql.toString(), parameter);
			//对vos进行处理,按照投资方＋被投资方相同的分组
		    Map<String, StockInvestRelaVO> map=new HashMap<String, StockInvestRelaVO>();
		    if(vosList!=null && vosList.size()>0){
		      for(StockInvestRelaVO vo : vosList){
		        String key=vo.getInvestor()+vo.getInvestee();
		        StockInvestRelaVO oldVO=map.get(key);
		        if(oldVO==null){
		          StockInvestRelaVO cloneVO=(StockInvestRelaVO)vo.clone();
		          map.put(key, cloneVO);
		        }else{
		          //重新设置字段的值
		          oldVO.setAssessmode(vo.getAssessmode());
		          oldVO.setAutogenervoucher(vo.getAutogenervoucher());
		          oldVO.setInvestproportion(new UFDouble(oldVO.getInvestproportion().doubleValue()+vo.getInvestproportion().doubleValue()));
		          if (vo.getInvestdate().toDate().after(oldVO.getInvestdate().toDate()) && vo.getControlinvest() != null) {
		        	  oldVO.setControlinvest(vo.getControlinvest());
		          }
		          map.put(key, oldVO);
		        }
		      }
		    }
		    List<StockInvestRelaVO> voList=new ArrayList<StockInvestRelaVO>(map.values());
		    if (voList!=null && voList.size()>0) {
				return voList.toArray(new StockInvestRelaVO[0]);
			}
		} catch (BusinessException e) {
			AppDebug.debug(e.getMessage(), e);
			throw new UFOSrvException();
		}
	    return new StockInvestRelaVO[0];
	}

	// 存在控制性的投资关系
	public boolean existControlInvestor() throws BusinessException {
		boolean result = false;
//		StringBuilder content = new StringBuilder();
//		content.append("SELECT    investor, SUM (investproportion) invest ");
//		content.append("    FROM org_stockinvest ");
//		content.append("   WHERE investee = ? and investdate<=? and investor in(select pk_org from org_rcsmember_v where pk_svid = ? )");
//		content.append("GROUP BY  investor ");
//		BaseDAO dao = new BaseDAO();
//		SQLParameter parameter = new SQLParameter();
//		parameter.addParam(this.getPk_other());
//		parameter.addParam(this.getEndata().toStdString());
//		parameter.addParam(getPk_rms());
//		StockInvestRelaVO[] vos = (StockInvestRelaVO[]) dao.executeQuery(
//				content.toString(), parameter, new BaseProcessor() {
//					private static final long serialVersionUID = 1L;
//
//					@Override
//					public Object processResultSet(ResultSet rs)
//							throws SQLException {
//						List<StockInvestRelaVO> list = new ArrayList<StockInvestRelaVO>();
//						while (rs.next()) {
//							StockInvestRelaVO tvo = new StockInvestRelaVO();
//							tvo.setInvestor(rs.getString("investor"));
//							tvo.setInvestproportion(new UFDouble(rs
//									.getDouble("invest")));
//							list.add(tvo);
//						}
//
//						return list.toArray(new StockInvestRelaVO[0]);
//
//					}
//
//				});
		StockInvestRelaVO[] vos = getStockInvestRela();
		if (null == vos || vos.length == 0) {
			return false;
		}
		
		StockInvestRelaVO controlRelaVO = null;
		
		//@edit by zhoushuang at 2014-11-20,下午3:41:05 控制性字段是否全部为空或N，是则走原来的流程，否则直接判断本对方是否为控制性
		boolean flag = true;//全为空或全为否
		for (int i = 0; i < vos.length; i++) {
			if (vos[i].getControlinvest() != null && vos[i].getControlinvest().booleanValue()) {
				flag = false;
				if (controlRelaVO == null) {
					controlRelaVO = vos[i];
				}else if (vos[i].getInvestdate().toDate().after( controlRelaVO.getInvestdate().toDate())){
					//有多个控制型的时候找时间最新的作为控制性。新的在旧的之后
					controlRelaVO =  vos[i];
				}
			}
		}
		if (!flag) {//有控制性的，走此分支
			// @edit by zhoushuang at 2014-11-20,下午3:41:05  控制性字段有值，则判断该对账对是否是控制性
			if (controlRelaVO.getInvestor().equals(this.getPk_self())) {
				return true;
			}else {
				return false;
			}
		} else { 
			// //没有控制性的时候，走此分支，开始判断本方是不是控制投资类
			double selfvalue = 0;
			for (StockInvestRelaVO tvo : vos) {
				if (tvo.getInvestor().equals(this.getPk_self())) {
					selfvalue = tvo.getInvestproportion().getDouble();
					break;
				}
			}

			List<String> list = new ArrayList<String>();
			for (StockInvestRelaVO tvo : vos) {
				if (tvo.getInvestor().equals(this.getPk_self())) {

				} else {
					if (tvo.getInvestproportion().doubleValue() > selfvalue) { // 存在比本方大的
						return false;
					} else if (tvo.getInvestproportion().doubleValue() == selfvalue) { // 存在相等的
						list.add(tvo.getInvestor());
					}
				}
			}
			if (list.size() > 0) {
				list.add(this.getPk_self());
				String[] corps = list.toArray(new String[0]);
				// 若遇到有多个投资方都相同时，取单位编码排第一的
				CorpVO[] corpvos = HBPubItfService.getRemoteCorpQrySrv()
						.queryCorpVOsByCorpIDs(corps);
				Arrays.sort(corpvos, new Comparator<CorpVO>() {
					public int compare(CorpVO o1, CorpVO o2) {
						return o1.getCode().compareTo(o2.getCode());
					}
				});
				if (corpvos[0].getPk_corp().equals(this.getPk_self())) {
					return true;
				}
			} else {
				return true;
			}
		}
		return result;
	}
	

	// 存在非控制性的投资关系
	public boolean existNonControlInvestor() throws BusinessException {
		boolean result = true;
//		StringBuilder content = new StringBuilder();
//		content.append("SELECT    investor, SUM (investproportion) invest ");
//		content.append("    FROM org_stockinvest ");
//		content.append("   WHERE investee = ? and investdate<=? and investor in(select pk_org from org_rcsmember_v where pk_svid = ? )");
//		content.append("GROUP BY  investor ");
//		BaseDAO dao = new BaseDAO();
//		SQLParameter parameter = new SQLParameter();
//		parameter.addParam(this.getPk_other());
//		parameter.addParam(this.getEndata().toStdString());
//		parameter.addParam(getPk_rms());
//		StockInvestRelaVO[] vos = (StockInvestRelaVO[]) dao.executeQuery(
//				content.toString(), parameter, new BaseProcessor() {
//					private static final long serialVersionUID = 1L;
//
//					@Override
//					public Object processResultSet(ResultSet rs)
//							throws SQLException {
//						// TODO Auto-generated method stub
//
//						List<StockInvestRelaVO> list = new ArrayList<StockInvestRelaVO>();
//						while (rs.next()) {
//							StockInvestRelaVO tvo = new StockInvestRelaVO();
//							tvo.setInvestor(rs.getString("investor"));
//							tvo.setInvestproportion(new UFDouble(rs
//									.getDouble("invest")));
//							list.add(tvo);
//						}
//
//						return list.toArray(new StockInvestRelaVO[0]);
//
//					}
//
//				});
						
		StockInvestRelaVO[] vos = getStockInvestRela();		
		if (null == vos || vos.length == 0) {
			return false;
		}
		
		StockInvestRelaVO controlRelaVO = null;
		
		//@edit by zhoushuang at 2014-11-20,下午3:41:05 控制性字段是否全部为空，是则走原来的流程，否则直接判断本对方是否为非控制性
		boolean flag = true;//全为空或全为否
		//有多个控制性
		for (int i = 0; i < vos.length; i++) {
			if (vos[i].getControlinvest() != null && vos[i].getControlinvest().booleanValue()) {
				flag = false;
				if (controlRelaVO == null) {
					controlRelaVO = vos[i];
					continue;
				}else if (vos[i].getInvestdate().toDate().after( controlRelaVO.getInvestdate().toDate())){
					//有多个控制型的时候找时间最新的作为控制性。新的在旧的之后
					controlRelaVO =  vos[i];
				}
			}
		}
		
		if (!flag) {//有控制性的，走此分支
			if (controlRelaVO.getInvestor().equals(this.getPk_self())) {
				return false;
			}else {
				return true;
			}
		} else {//没有控制性的时候，走此分支， 开始判断本方是不是控制投资类
			double selfvalue = 0;
			for (StockInvestRelaVO tvo : vos) {
				if (tvo.getInvestor().equals(this.getPk_self())) {
					selfvalue = tvo.getInvestproportion().getDouble();
					break;
				}
			}

			List<String> list = new ArrayList<String>();
			for (StockInvestRelaVO tvo : vos) {
				if (tvo.getInvestor().equals(this.getPk_self())) {

				} else {
					if (tvo.getInvestproportion().doubleValue() > selfvalue) { // 存在比本方大的
						return true;
					} else if (tvo.getInvestproportion().doubleValue() == selfvalue) { // 存在相等的
						list.add(tvo.getInvestor());
					}
				}
			}
			if (list.size() > 0) {
				list.add(this.getPk_self());
				String[] corps = list.toArray(new String[0]);
				// 若遇到有多个投资方都相同时，取单位编码排第一的
				CorpVO[] corpvos = HBPubItfService.getRemoteCorpQrySrv()
						.queryCorpVOsByCorpIDs(corps);
				Arrays.sort(corpvos, new Comparator<CorpVO>() {
					public int compare(CorpVO o1, CorpVO o2) {
						return o1.getCode().compareTo(o2.getCode());
					}
				});
				if (corpvos[0].getPk_corp().equals(this.getPk_self())) {
					return false;
				}
			} else {
				return false;
			}
		}
		return result;
	}
	
	public void setPk_self(String pk_self) {
		this.pk_self = pk_self;
	}

	public void setPk_other(String pk_other) {
		this.pk_other = pk_other;
	}


	public UFDate getEndata() {
		return endata;
	}

	public void setEndata(UFDate endata) {
		this.endata = endata;
	}

	public String getPk_rms() {
		return pk_rms;
	}

	public void setPk_rms(String pk_rms) {
		this.pk_rms = pk_rms;
	}

	public String getPk_investscheme() {
		return pk_investscheme;
	}

	public void setPk_investscheme(String pk_investscheme) {
		this.pk_investscheme = pk_investscheme;
	}

	public IStockInvestRelaQryService getQryservice() {
		if (qryservice == null) {
			qryservice = NCLocator.getInstance().lookup(IStockInvestRelaQryService.class);
		}
		return qryservice;
	}
	
}