package com.gx.obe.evaluation.step.calculator.calculate;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.List;

import com.gx.obe.components.core.util.MoneyUtils;
import com.gx.obe.evaluation.step.calculator.PriceScoreCalculator;
import com.gx.obe.evaluation.step.entity.CalculationResult;
import com.gx.obe.formula.DeviateRateItem;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.web.entity.evaluation.EvaluationFactor;
import com.gx.obe.web.entity.tender.TenderProjectRuleEntity;

/** 
 * @Description: 直线插值法
 * @author guoyr
 */
public class LinearStageDeviateCalculateImpl implements ICalculate {

	public CalculationResult start(PriceScoreCalculator tool, BigDecimal evaluationPrice, EvaluationFactor evaluationFactor, TenderProjectRuleEntity tenderProjectRuleEntity){

//		// 高于偏差率投标人得分
//		BigDecimal highDeviateDefaultScore = (null == tool.getCalculationParam().getHighDeviateDefaultScore() || tool.getCalculationParam().getHighDeviateDefaultScore().compareTo(BigDecimal.ZERO) < 0)? BigDecimal.ZERO : tool.getCalculationParam().getHighDeviateDefaultScore();
//		// 低于偏差率投标人得分
//		BigDecimal lowDeviateDefaultScore = (null == tool.getCalculationParam().getLowDeviateDefaultScore() || tool.getCalculationParam().getLowDeviateDefaultScore().compareTo(evaluationFactor.getFactorScore()) > 0)? evaluationFactor.getFactorScore() : tool.getCalculationParam().getLowDeviateDefaultScore();
		// 偏差率范围内投标人得分
		BigDecimal inDeviateRangeScore = (null == tool.getCalculationParam().getInDeviateRangeScore() || tool.getCalculationParam().getInDeviateRangeScore().compareTo(evaluationFactor.getFactorScore()) > 0)? evaluationFactor.getFactorScore() : tool.getCalculationParam().getInDeviateRangeScore();
		
		BigDecimal priceScore = null;
		BigDecimal basePrice = tool.getBasePrice();
		CalculationResult calculationResult = new CalculationResult();
		// 计算偏差率
		BigDecimal deviationRate = tool.getDeviationRate(evaluationPrice);
		calculationResult.setDeviationRate(deviationRate);
		
		// 如果在取样时设定了价格得分，则不再计算
		StringBuilder formual = new StringBuilder();
		
		if(null != basePrice){
			formual.append("基准价为");
			formual.append(MoneyUtils.getMoneyFormatByUnit(basePrice, tenderProjectRuleEntity.getEvalPriceUnit()));
		}
		formual.append("；偏差率为 ").append(deviationRate).append("%");
		if(null != tool.getDefaultScore(evaluationPrice)){
			priceScore = tool.getDefaultScore(evaluationPrice);
			priceScore = tool.getPriceScoreRound(priceScore);
			formual.append("，得默值").append(priceScore).append("分");
		
		}else {
			priceScore = tool.getPriceScoreRound(inDeviateRangeScore);
			
			// 如果设置了偏差率范围，且在偏差范围以内，则直接设置为预订分值
			if(deviationRate.compareTo(tool.getCalculationParam().getDeviateRangeMin()) >= 0 && deviationRate.compareTo(tool.getCalculationParam().getDeviateRangeMax()) <= 0 ){
				formual.append("，得").append(priceScore).append("分");
			}else {
				
				BigDecimal otherDeviateRangeBaseScore = tool.getCalculationParam().getOtherDeviateRangeBaseScore();
				if(null != otherDeviateRangeBaseScore && otherDeviateRangeBaseScore.compareTo(BigDecimal.ZERO) > 0){
					priceScore = otherDeviateRangeBaseScore;
				}
//				BigDecimal heightDeviateStart = tool.getCalculationParam().getDeviateRangeMax();
//				BigDecimal lowDeviateStart = tool.getCalculationParam().getDeviateRangeMin();
//				// 偏差率大于0,扣分
//				if(deviationRate.compareTo(heightDeviateStart) > 0){
//					
//					
//				}else if(deviationRate.compareTo(lowDeviateStart) < 0){}
				
				
				List<DeviateRateItem> hightDeviateItemList = tool.getCalculationParam().getHigherDeviateRateList();
				if(null != hightDeviateItemList && hightDeviateItemList.size() > 0){
					for(int i = 0; i < hightDeviateItemList.size(); i++){
						DeviateRateItem deviateItem = hightDeviateItemList.get(i);
						// 如果偏差率超过当前阶段偏差范围
						if(null != deviateItem.getDeviateRateStart() && deviationRate.compareTo(deviateItem.getDeviateRateStart()) > 0){
							
							formual.append("；高于基准价 "+ NumberFormat.getInstance().format(deviateItem.getDeviateRateStart())).append("%以上");
							
							// 计算出与当前阶段偏差的总偏差率
							BigDecimal moreDeviateRate = BigDecimalUtils.sub(deviationRate, deviateItem.getDeviateRateStart());
							if(i+1 < hightDeviateItemList.size()){
								DeviateRateItem nextDeviateItem = hightDeviateItemList.get(i+1);
								if(deviationRate.compareTo(nextDeviateItem.getDeviateRateStart()) > 0){
									moreDeviateRate = BigDecimalUtils.sub(nextDeviateItem.getDeviateRateStart(), deviateItem.getDeviateRateStart());
								}
							}
							BigDecimal addOrReduceScore = getDeviateAddOrReduceScore(moreDeviateRate, deviateItem.getDeviatePercentUnit(), deviateItem.getDeviatePercentValue());
							// 如果是扣分
							formual.append("，每高 ").append(NumberFormat.getInstance().format(deviateItem.getDeviatePercentUnit())).append("%");
							if(deviateItem.isReduceScore()){
								formual.append("扣 ").append(NumberFormat.getInstance().format(deviateItem.getDeviatePercentValue())).append("分");
								formual.append("，共扣 ").append(addOrReduceScore.doubleValue()).append("分");
								priceScore = BigDecimalUtils.sub(priceScore, addOrReduceScore);
								// 如果存在最小分值，则判断扣分后是否小于最低分
								if(null == deviateItem.getDefaultScore()){
									deviateItem.setDefaultScore(BigDecimal.ZERO);
								}
								if(priceScore.compareTo(deviateItem.getDefaultScore()) < 0){
									priceScore = tool.getPriceScoreRound(deviateItem.getDefaultScore());
									formual.append("， 最低得").append(priceScore).append("分");
								}
								
							}else {
								formual.append("加 ").append(NumberFormat.getInstance().format(deviateItem.getDeviatePercentValue())).append("分");
								formual.append("，共加 ").append(addOrReduceScore.doubleValue()).append("分");
								priceScore = BigDecimalUtils.add(priceScore, addOrReduceScore);
								// 如果存在最高分值，则判断加分后是否高于最高分
								if(null != deviateItem.getDefaultScore() && priceScore.compareTo(deviateItem.getDefaultScore()) > 0){
									priceScore = tool.getPriceScoreRound(deviateItem.getDefaultScore());
									formual.append("， 最高得").append(priceScore).append("分");
								}
							}
						}
					}
				}


				List<DeviateRateItem> lowDeviateItemList = tool.getCalculationParam().getLowerDeviateRateList();
				if(null != lowDeviateItemList && lowDeviateItemList.size() > 0){
					for(int i = 0; i < lowDeviateItemList.size(); i++){
						DeviateRateItem deviateItem = lowDeviateItemList.get(i);
						// 如果偏差率超过当前阶段偏差范围
						if(null != deviateItem.getDeviateRateStart() && deviationRate.compareTo(deviateItem.getDeviateRateStart()) < 0){
							formual.append("；低于基准价 "+ NumberFormat.getInstance().format(deviateItem.getDeviateRateStart())).append("%以上 ");
							
							// 计算出与当前阶段偏差的总偏差率
							BigDecimal moreDeviateRate = BigDecimalUtils.sub(deviationRate, deviateItem.getDeviateRateStart());
							if(i+1 < lowDeviateItemList.size()){
								DeviateRateItem nextDeviateItem = lowDeviateItemList.get(i+1);
								if(deviationRate.compareTo(nextDeviateItem.getDeviateRateStart()) < 0){
									moreDeviateRate = BigDecimalUtils.sub(nextDeviateItem.getDeviateRateStart(), deviateItem.getDeviateRateStart());
								}
							}
							
							BigDecimal addOrReduceScore = getDeviateAddOrReduceScore(moreDeviateRate, deviateItem.getDeviatePercentUnit(), deviateItem.getDeviatePercentValue());
							// 如果是扣分
							formual.append("，每低 ").append(NumberFormat.getInstance().format(deviateItem.getDeviatePercentUnit())).append("%");
							if(deviateItem.isReduceScore()){
								formual.append("扣 ").append(NumberFormat.getInstance().format(deviateItem.getDeviatePercentValue())).append("分");
								formual.append("，共扣 ").append(addOrReduceScore.doubleValue()).append("分");
								priceScore = BigDecimalUtils.sub(priceScore, addOrReduceScore);
								// 如果存在最小分值，则判断扣分后是否小于最低分
								if(null != deviateItem.getDefaultScore() && priceScore.compareTo(deviateItem.getDefaultScore()) < 0){
									priceScore = tool.getPriceScoreRound(deviateItem.getDefaultScore());
									formual.append("， 最低得").append(priceScore).append("分");
								}
								
							}else {
								formual.append("加 ").append(NumberFormat.getInstance().format(deviateItem.getDeviatePercentValue())).append("分");
								formual.append("，共加 ").append(addOrReduceScore.doubleValue()).append("分");
								priceScore = BigDecimalUtils.add(priceScore, addOrReduceScore);
								// 如果存在最高分值，则判断加分后是否高于最高分
								if(null != deviateItem.getDefaultScore() && priceScore.compareTo(deviateItem.getDefaultScore()) > 0){
									priceScore = tool.getPriceScoreRound(deviateItem.getDefaultScore());
									formual.append("， 最高得").append(priceScore).append("分");
								}
							}
						}
					}
				}
			
			}
		}
		priceScore = tool.getPriceScoreRound(priceScore);
		formual.append("；最终得").append(priceScore);
		calculationResult.setPriceScore(priceScore);
		calculationResult.setPriceFinalScore(tool.getScoreByWeight(priceScore));
//		if(null != evaluationFactor.getFactorFinalWeight()){
		if(priceScore.compareTo(BigDecimal.ZERO) != 0 && null != evaluationFactor.getFactorWeight() && evaluationFactor.getFactorFinalWeight().compareTo(BigDecimal.ZERO) != 0){
			formual.append("；权重为");
			formual.append(NumberFormat.getInstance().format(evaluationFactor.getFactorFinalWeight()));
			formual.append("%，权重后得");
			formual.append(calculationResult.getPriceFinalScore());
		}
		formual.append("分。");
		// 价格分保留小数位
		calculationResult.setFormual(formual.toString());
		return calculationResult;
	}
	
	/**
	 * @Description: 计算出当前偏差率所扣或所加分值
	 * @author guoyr
	 * @param deviationRate 扣分或加分偏差
	 * @param deviatePercentUnit 偏差扣分或加分单位
	 * @param deviatePercentValue 偏差扣分或加分值
	 * @return 
	 */
	private BigDecimal getDeviateAddOrReduceScore(BigDecimal deviationRate, BigDecimal deviatePercentUnit, BigDecimal deviatePercentValue){
		// 计算高出几个单位的偏差
		BigDecimal deviationUnit = BigDecimalUtils.div(deviationRate, deviatePercentUnit);
		
		// 计算出高出单位所扣分值
		BigDecimal deviationValue = BigDecimalUtils.mul(deviationUnit, deviatePercentValue);
		
		if(deviationValue.compareTo(BigDecimal.ZERO) < 0){
			deviationValue = BigDecimalUtils.sub(BigDecimal.ZERO, deviationValue);
		}
		return deviationValue;
	}
}
