package com.yonyou.hrcloud.pm.ps.impl;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yonyou.hrcloud.adder.context.AppContext;
import com.yonyou.hrcloud.adder.exception.AdderBusinessException;
import com.yonyou.hrcloud.adder.model.query.Condition;
import com.yonyou.hrcloud.adder.model.query.Operator;
import com.yonyou.hrcloud.pm.base.model.Grade;
import com.yonyou.hrcloud.pm.base.model.GradeItem;
import com.yonyou.hrcloud.pm.base.model.Period;
import com.yonyou.hrcloud.pm.base.model.ScoreRule;
import com.yonyou.hrcloud.pm.base.service.IGradeService;
import com.yonyou.hrcloud.pm.base.service.IPeriodService;
import com.yonyou.hrcloud.pm.base.service.IScoreRuleService;
import com.yonyou.hrcloud.pm.common.model.CommonValue;
import com.yonyou.hrcloud.pm.ps.dao.IOperationDao;
import com.yonyou.hrcloud.pm.ps.model.EvaAppraiser;
import com.yonyou.hrcloud.pm.ps.model.EvaGroup;
import com.yonyou.hrcloud.pm.ps.model.EvaObject;
import com.yonyou.hrcloud.pm.ps.model.Scheme;
import com.yonyou.hrcloud.pm.ps.service.IEvaGroupService;
import com.yonyou.hrcloud.pm.ps.service.IOperationGaugeService;

/**
 * 公共量表操作流程实现层
 * 
 * @author Flysea
 *
 */
@Service
@Transactional
public class OperationGaugeServiceImpl implements IOperationGaugeService {

	@Resource
	public com.yonyou.hrcloud.adder.service.IGenericService daoex;

	@Resource
	public IOperationDao dao;

	@Resource
	public IEvaGroupService daoGroup;

	@Resource
	public IPeriodService periodSrv;

	@Resource
	public IScoreRuleService scoreRuleSrv;

	@Resource
	public IGradeService gradeSrv;

	protected static final Logger logger = LoggerFactory.getLogger(OperationGaugeServiceImpl.class);
	
	/**
	 * 启动检查方案数据正确性
	 *
	 * @param scheme
	 */
	@Override
	public void checkScheme(Scheme scheme) {
		if ("".equals(scheme.getId()))
			throw new AdderBusinessException("方案id不正确", "pm.i18n_core.ps.013");
		if (scheme.getSchemename().length() > 40)
			throw new AdderBusinessException("方案名称不能超过{0}个字符", "pm.i18n_core.ps.014", "40");
		Period p = periodSrv.queryPeriodByID(scheme.getPeriodid());
		if (p == null)
			throw new AdderBusinessException("方案中周期不存在", "pm.i18n_core.ps.015");
		if (StringUtils.isEmpty(scheme.getOrgid()))
			throw new AdderBusinessException("方案所属组织不正确", "pm.i18n_core.ps.016");
		if (!scheme.getPeriodcode().equals(p.getPeriodcode()))
			throw new AdderBusinessException("方案中周期不存在", "pm.i18n_core.ps.015");
		ScoreRule sr = scoreRuleSrv.queryScoreRuleByID(scheme.getScoreruleid());
		if (sr == null)
			throw new AdderBusinessException("方案中评分规则不存在", "pm.i18n_core.ps.017");
		if (sr.getOrgid().length() > 0 && !sr.getOrgid().equals(CommonValue.EnumDataBaseSpecial.Empty.getSymbol())
				&& !sr.getOrgid().equals(scheme.getOrgid()))
			throw new AdderBusinessException("方案与评分规则所属组织不一致", "pm.i18n_core.ps.018");
		Grade grade = gradeSrv.queryGradeByID(scheme.getGradeid(), true);
		if (grade == null)
			throw new AdderBusinessException("方案中考核结果等级不存在", "pm.i18n_core.ps.019");
		if (grade.getOrgid().length() > 0 && !grade.getOrgid().equals(CommonValue.EnumDataBaseSpecial.Empty.getSymbol())
				&& !grade.getOrgid().equals(scheme.getOrgid())) {
			logger.error("pm:" + grade.getOrgid() + "," + scheme.getOrgid());
			throw new AdderBusinessException("方案与考核等级所属组织不一致。", "pm.i18n_core.ps.0200");
		}
		boolean ok = true;
		if ((scheme.getSchememode() > CommonValue.EnumSchemeMode.pm_values.getIndex() &&
				scheme.getSchememode() != CommonValue.EnumSchemeMode.pm_mtr.getIndex()) || scheme.getSchememode() < 0)
			ok = false;
		else if (scheme.getAbstentionmode() < 0 || scheme.getAbstentionmode() > 2)
			ok = false;
		else if (scheme.getApplyobj() > 2 || scheme.getApplyobj() < 1)
			ok = false;
		else if (scheme.getScoreway() < 1 || scheme.getScoreway() > 3)
			ok = false;
		if (!ok)
			throw new AdderBusinessException("方案数据不正确", "pm.i18n_core.ps.021");
		if (scheme.getOEvaAppraiser() != null) {
			BigDecimal bignum1 = new BigDecimal("100");
			BigDecimal bignum2 = BigDecimal.ZERO;
			for (EvaAppraiser item : scheme.getOEvaAppraiser()) {
				// 循环每一个轮次
				if (item.getTurn() < 0 && item.getTurn() > scheme.getOEvaAppraiser().size())
					throw new AdderBusinessException("方案流程轮次不正确", "pm.i18n_core.ps.022");
				else if ("".equals(item.getStaffid()))
					item.setStaffid(null);
				if (item.getWeight() != null)
					bignum2 = bignum2.add(item.getWeight());
			}
			if (bignum1.compareTo(bignum2) < 0)
				throw new AdderBusinessException("方案数据不正确", "pm.i18n_core.ps.021");
		}
		// 检查考核等级是否涵盖了评分方式
		BigDecimal upper = grade.getOGradeItem().get(0).getUpperlimit();
		BigDecimal lower = grade.getOGradeItem().get(grade.getOGradeItem().size() - 1).getLowerlimit();
		BigDecimal srupper = sr.getUpperlimit();
		BigDecimal srlower = sr.getLowerlimit();
		if (sr.getRuletype() == CommonValue.EnumScoreRuleType.Grade.getIndex()) {
			// 等级式判断标准分范围
			Collections.sort(sr.getOGradeItem(), new Comparator<GradeItem>() {
				@Override
				public int compare(GradeItem o1, GradeItem o2) {
					int i = o1.getStandardscore().compareTo(o2.getStandardscore());
					return i;
				}
			});
			srlower = sr.getOGradeItem().get(0).getStandardscore();
			srupper = sr.getOGradeItem().get(sr.getOGradeItem().size() - 1).getStandardscore();
		}
		if (upper != null && upper.compareTo(srupper) < 0 || lower != null && lower.compareTo(srlower) > 0)
			throw new AdderBusinessException("考核等级范围要覆盖评分方式，请修改", "pm.i18n_core.ps.023");
		// 检查考核等级是否为空
		for (GradeItem item : grade.getOGradeItem()) {
			if (item.getArchiveid() == null)
				throw new AdderBusinessException("考核等级规则中缺少等级设置", "pm.i18n_core.ps.066");
		}
		// 提交专用校验
		if (StringUtils.isEmpty(scheme.getOrgid()))
			throw new AdderBusinessException("方案所属组织不正确", "pm.i18n_core.ps.016");
		if(!scheme.isIsimportresult()) {
			if (CollectionUtils.isEmpty(scheme.getOGroups()) || CollectionUtils.isEmpty(scheme.getOEvaAppraiser()))
				throw new AdderBusinessException("考核流程设置不完整", "pm.i18n_pbc.ps.023");
			if (CollectionUtils.isEmpty(scheme.getOGroups()))
				throw new AdderBusinessException("考核对象组设置不完整", "pm.i18n_pbc.ps.024");
		}
		// scheme.getOGroups().forEach(evaGroup -> {
		for (EvaGroup evaGroup : scheme.getOGroups()) {
			if (CollectionUtils.isEmpty(evaGroup.getOEvaObjects())) {
				evaGroup = daoGroup.queryEvaGroupByID(evaGroup.getId(), false);
				if (CollectionUtils.isEmpty(evaGroup.getOEvaObjects()))
					throw new AdderBusinessException("考核对象异常，请检查", "pm.i18n_pbc.ps.009");
			}
			if (!scheme.isIsallowfillup() && scheme.getIndisource() == CommonValue.EnumIndiSource.hrfill.getIndex()) {
				for (EvaObject item : evaGroup.getOEvaObjects()) {
					if(!scheme.isIsimportresult()) {
						if (item.getGaugeid() == null)
							throw new AdderBusinessException("未设置考核对象的量表，请检查", "pm.i18n_pbc.ps.021");
					}
				}
			}
		} // );
			// 允许员工填报校验
		Condition condObj = new Condition();
		condObj.addExpression("schemeid", scheme.getId());
		condObj.addExpression("gaugeid", "", Operator.GREATER);
		condObj.addExpression("tenantid", AppContext.getContext().getScope());
		if (!scheme.isIsallowfillup() && scheme.getIndisource() == CommonValue.EnumIndiSource.hrfill.getIndex()) {
			// 检查每个考核对象都设置了公共量表
			int count = dao.getGaugeUncheckedCount(condObj);
			if (count > 0)
				throw new AdderBusinessException("方案选择了不允许员工填报，公共量表需要满足指标权重合计为100%", "pm.i18n_pbc.ps.017");
		}
		// 双权重公共量表和方案一致
		int count = dao.getGaugecheckDoubleWeightCount(!scheme.isIsdoubleweight(), condObj);
		if (count > 0)
			throw new AdderBusinessException("方案中按指标分类、指标两级设置权重与公共量表不相符", "pm.i18n_pbc.ps.020");
	}
}
