package nc.bs.bd.psn.psndoc.validator;

import java.util.Collection;
import java.util.List;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.logging.Logger;
import nc.bs.uif2.BusinessExceptionAdapter;
import nc.bs.uif2.validation.UniqueValidationFailure;
import nc.bs.uif2.validation.ValidationFailure;
import nc.itf.bd.config.uniquerule.UniqueRuleConst;
import nc.jdbc.framework.SQLParameter;
import nc.md.MDBaseQueryFacade;
import nc.md.data.access.NCObject;
import nc.md.model.IBean;
import nc.md.model.MetaDataException;
import nc.vo.bd.config.BDUniqueruleItemVO;
import nc.vo.bd.config.BDUniqueruleVO;
import nc.vo.bd.psn.IPsnConst;
import nc.vo.bd.psn.PsndocVO;
import nc.vo.bd.psn.PsnjobVO;
import nc.vo.bd.psn.util.GetBusiDateUtil;
import nc.vo.bd.pub.IPubEnumConst;
import nc.vo.org.OrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.SuperVO;
import nc.vo.pub.lang.UFLiteralDate;
import nc.vo.util.BDUniqueRuleValidate;

import nccloud.commons.lang.StringUtils;

/**
 * 人员唯一性校验
 * 
 * @author jiangjuna
 * @since NC6.0
 * 
 */
@SuppressWarnings("serial")
public class PsndocUniqueValidator extends BDUniqueRuleValidate {

	private BaseDAO baseDAO = null;

	private IBean bean = null;
	
	public static final String ISCHECKREPEAT = "isCheckRepeat";

	/**
	 * 是否校验提示字段（名称或证件类型+证件号）
	 */
	private boolean isCheckRepeat = false;
	
	private UFLiteralDate nowDate=getNowDate();
	
	public PsndocUniqueValidator() {
	}

	@Override
	public ValidationFailure validate(Object objects) {
		PsndocVO vo = (PsndocVO) objects;
		if ((Boolean) vo.getAttributeValue(ISCHECKREPEAT) !=null) {
			this.isCheckRepeat = (Boolean) vo.getAttributeValue(ISCHECKREPEAT);
		}
		try {
			this.bean = MDBaseQueryFacade.getInstance().getBeanByFullClassName(vo.getClass().getName());
		} catch (MetaDataException e1) {
			throw new BusinessExceptionAdapter(e1);
		}
		ValidationFailure failure = super.validate(vo);
		// 如果为姓名或证件类型+证件号重复，则先不抛出，继续检查姓名+证件类型+证件号是否重复
		if (failure != null
				&& !(failure.getErrorcode().equalsIgnoreCase(
						IPsnConst.UNIQUERULE_NAME_ERRORCODE) || failure
						.getErrorcode().equalsIgnoreCase(
								IPsnConst.UNIQUERULE_IDTYPE_ID_ERRORCODE))) {
			return failure;

		}
		ValidationFailure vf;
		try {
			// 校验“姓名+证件类型+证件号”是否重复，系统默认的唯一性规则
			vf = validatorPsnDefaultUniqueRule(vo);
		} catch (BusinessException e) {
			Logger.error(e.getMessage(), e);
			throw new BusinessExceptionAdapter(e);
		}
		if (vf == null && failure != null) {
			//modify by wangchge 20210302,人员姓名重复不再抛出异常
			if(failure.getErrorcode().equalsIgnoreCase(
					IPsnConst.UNIQUERULE_NAME_ERRORCODE)) {
				return null;
			}else {
				return failure;
			}
		}
		return vf;
	}
	

	/**
	 * 重新组织人员的唯一性规则
	 */
	@Override
	protected Collection<BDUniqueruleVO> getUniqueRules(IBean bean,
			SuperVO[] vos) throws BusinessException {
		Collection<BDUniqueruleVO> col = super.getUniqueRules(bean, vos);
		BDUniqueruleVO defaultRule = null;
		boolean isNameExist = false;
		boolean isIdtypeAndIdExist = false;
		for (BDUniqueruleVO rule : col) {
			if (getUniqueRuleType(rule) == IPsnConst.UNIQUERULE_NAME_IDTYPE_ID) {
				defaultRule = rule;
			} else if (getUniqueRuleType(rule) == IPsnConst.UNIQUERULE_NAME) {
				isNameExist = true;
			} else if (getUniqueRuleType(rule) == IPsnConst.UNIQUERULE_IDTYPE_ID) {
				isIdtypeAndIdExist = true;
			}
		}
		// 当定义的唯一性规则包含姓名+证件类型+证件号时，去掉该规则
		if (defaultRule != null) {
			col.remove(defaultRule);
		}

		// 设置校验提示字段时
		if (this.isCheckRepeat) {
			// 当“姓名”规则不存在时，增加一条
			if (!isNameExist) {
				BDUniqueruleVO rule = new BDUniqueruleVO();
				rule.setPk_rule(IPsnConst.UNIQUERULE_NAME);
				BDUniqueruleItemVO item = new BDUniqueruleItemVO();
				item.setMdcolumnid(bean.getAttributeByName(PsndocVO.NAME)
						.getID());
				rule.setRuleitems(new BDUniqueruleItemVO[] { item });
				col.add(rule);
			}
			// 当"证件类型+证件"规则不存在时，增加一条
			if (!isIdtypeAndIdExist) {
				BDUniqueruleVO rule = new BDUniqueruleVO();
				rule.setPk_rule(IPsnConst.UNIQUERULE_IDTYPE_ID);
				BDUniqueruleItemVO[] items = new BDUniqueruleItemVO[2];
				items[0] = new BDUniqueruleItemVO();
				items[0].setMdcolumnid(bean.getAttributeByName(PsndocVO.IDTYPE)
						.getID());
				items[1] = new BDUniqueruleItemVO();
				items[1].setMdcolumnid(bean.getAttributeByName(PsndocVO.ID)
						.getID());
				rule.setRuleitems(items);
				col.add(rule);
			}
		}
		return col;
	}

	/**
	 * 获得异常码时，判断提示性规则
	 */
	@Override
	protected String getErrorCode(List<BDUniqueruleVO> ruleList) {
		String errorCode = super.getErrorCode(ruleList);
		if (UniqueRuleConst.CODEBREAKUNIQUE.equals(errorCode)) {
			return errorCode;
		}
		if (ruleList != null && ruleList.size() > 0) {
			for (BDUniqueruleVO uniqueruleVO : ruleList) {
				if (uniqueruleVO.getPk_rule() == IPsnConst.UNIQUERULE_NAME) {
					errorCode = IPsnConst.UNIQUERULE_NAME_ERRORCODE;
				} else if (uniqueruleVO.getPk_rule() == IPsnConst.UNIQUERULE_IDTYPE_ID) {
					errorCode = IPsnConst.UNIQUERULE_IDTYPE_ID_ERRORCODE;
				}
			}
		}

		return errorCode;
	}

	/**
	 * 判断唯一性规则的内容
	 * 
	 * @param rule
	 * @return
	 */
	private String getUniqueRuleType(BDUniqueruleVO rule) {
		BDUniqueruleItemVO[] ruleitems = rule.getRuleitems();
		if (ruleitems == null || ruleitems.length > 3) {
			return null;
		}
		boolean name = false;
		boolean idtype = false;
		boolean id = false;
		for (BDUniqueruleItemVO item : ruleitems) {
			if (item.getMdcolumnid().equals(
					this.bean.getAttributeByName(PsndocVO.NAME).getID())) {
				// 包含名称时
				name = true;
			} else if (item.getMdcolumnid().equals(
					this.bean.getAttributeByName(PsndocVO.IDTYPE).getID())) {
				// 包含证件类型时
				idtype = true;
			} else if (item.getMdcolumnid().equals(
					this.bean.getAttributeByName(PsndocVO.ID).getID())) {
				// 包含证件号时
				id = true;
			}
		}

		if (ruleitems.length == 1 && name) {
			// 姓名唯一
			return IPsnConst.UNIQUERULE_NAME;
		} else if (ruleitems.length == 2 && idtype && id) {
			// 证件类型+证件号唯一
			return IPsnConst.UNIQUERULE_IDTYPE_ID;
		} else if (ruleitems.length == 3 && name && idtype && id) {
			// 姓名+证件类型+证件号唯一
			return IPsnConst.UNIQUERULE_NAME_IDTYPE_ID;
		}
		return null;
	}

	/**
	 * 校验人员默认唯一性规则（姓名+证件类型+证件号，重复表示为同一人）
	 * 
	 * @param vo
	 * @throws BusinessException
	 */
	private ValidationFailure validatorPsnDefaultUniqueRule(PsndocVO vo)
			throws BusinessException {

		PsndocVO repeatVO = getRepeatVO(vo);
		if (repeatVO == null) {
			return null;
		}
		String name = vo.getName();
		OrgVO orgVO = (OrgVO) new BaseDAO().retrieveByPK(OrgVO.class,
				repeatVO.getPk_org(), new String[] { OrgVO.NAME, OrgVO.NAME2,
						OrgVO.NAME3, OrgVO.NAME4, OrgVO.NAME5, OrgVO.NAME6 });
		String buName = NCObject.newInstance(orgVO).getAttributeValue(OrgVO.NAME).toString();
		if (IPubEnumConst.ENABLESTATE_DISABLE == repeatVO.getEnablestate()) {
			// 已停用的数据
			UniqueValidationFailure vf = null;
			vf = new UniqueValidationFailure();
			vf.setErrorcode(IPsnConst.UNIQUERULE_NAME_IDTYPE_ID_ERRORCODE);
			vf.setDetailMsg(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes()
					.getStrByID("10140psn", "010140psn0079")/*
															 * @res"业务单元"
															 */
					+ buName
					+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
							"10140psn", "010140psn0108")/*
														 * @res"下已存在已停用"
														 */
					+ name
					+ ","
					+ vo.getId()
					+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
							"10140psn", "010140psn0095")/*
														 * @res"人员"
														 */);
			return vf;
		}else{
			PsnjobVO[] jobvos=getRepeatPsnjobVOs(repeatVO);
			int jobRecords=0;	
			if(jobvos!=null&& jobvos.length>0){
				for(PsnjobVO jobvo:jobvos){
					if(jobvo.getEnddutydate()!=null && jobvo.getEnddutydate().compareTo(nowDate)<0){
						jobRecords++;
					}
				}
			}
			if(jobRecords==jobvos.length){
				UniqueValidationFailure vf = null;
				vf = new UniqueValidationFailure();
				vf.setErrorcode(IPsnConst.UNIQUERULE_NAME_IDTYPE_ID_ERRORCODE);
				vf.setDetailMsg(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes()
						.getStrByID("10140psn", "010140psn0079")/*
																 * @res"业务单元"
																 */
						+ buName
						+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
								"10140psn", "110140psn0036")/*
															 * @res"下已存在离职"
															 */
						+ name
						+ ","
						+ vo.getId()
						+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
								"10140psn", "010140psn0095")/*
															 * @res"人员"
															 */);
				return vf;
			}
		}
		String msg = nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
				"10140psn", "010140psn0078"/*
											 * @res [姓名+证件类型+证件号] 不允许重复，请修改：
											 */)
				+ "["
				+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
						"10140psn", "010140psn0081"/* @res 姓名 */)
				+ ":"
				+ name
				+ ","
				+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
						"10140psn", "010140psn0068"/* @res 证件号 */)
				+ ":"
				+ vo.getId()
				+ ","
				+ nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
						"10140psn", "010140psn0079"/* @res 业务单元 */)
				+ ":"
				+ buName + "]";
		BusinessException ex = new BusinessException(msg);
		throw ex;
	}

	private PsnjobVO[] getRepeatPsnjobVOs(PsndocVO vo) throws DAOException{
		String condition=PsndocVO.PK_PSNDOC + " = ?";
		SQLParameter param = new SQLParameter();
		param.addParam(vo.getPk_psndoc());
		@SuppressWarnings("unchecked")
		Collection<PsnjobVO> col = getBaseDAO().retrieveByClause(PsnjobVO.class,condition,param);
		if (col != null && col.size() > 0) {
			return col.toArray(new PsnjobVO[0]);
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	private PsndocVO getRepeatVO(PsndocVO vo) throws DAOException {
		String condition = PsndocVO.NAME + " = ? and " + PsndocVO.IDTYPE
				+ " = ? and " + PsndocVO.ID + " = ?";
		SQLParameter param = new SQLParameter();
		param.addParam(vo.getName());
		param.addParam(vo.getIdtype());
		param.addParam(vo.getId());
		if (!StringUtils.isBlank(vo.getPrimaryKey())) {
			condition += " and " + PsndocVO.PK_PSNDOC + " <> ?";
			param.addParam(vo.getPrimaryKey());
		}
		Collection<PsndocVO> col = getBaseDAO().retrieveByClause(
				PsndocVO.class,
				condition,
				new String[] { PsndocVO.PK_ORG, PsndocVO.CODE, PsndocVO.NAME,
						PsndocVO.NAME2, PsndocVO.NAME3, PsndocVO.NAME4,
						PsndocVO.NAME5, PsndocVO.NAME6, PsndocVO.ENABLESTATE },
				param);
		if (col != null && col.size() > 0) {
			return col.iterator().next();
		}
		return null;
	}

	private BaseDAO getBaseDAO() {
		if (this.baseDAO == null) {
			this.baseDAO = new BaseDAO();
		}
		return this.baseDAO;
	}
	
	private UFLiteralDate getNowDate(){
		if(nowDate==null){
			nowDate=new GetBusiDateUtil().getNowDate();
		}
		return nowDate;
	}
}
