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

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

import com.gx.obe.components.core.enumeration.TenderProjectEnum;
import com.gx.obe.formula.AvgFloatRangeItem;
import com.gx.obe.formula.BenchmarkPriceParam;
import com.gx.obe.web.entity.tender.TenderProjectRuleEntity;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.util.utils.StringUtils;

/** 
 * @Description: 
 * @author guoyr
 */
public class BenchmarkPriceCalculator {
	
	private PriceScoreCalculator calculator;
	private BigDecimal basePrice;
	private TenderProjectRuleEntity tenderProjectRuleEntity;

	/** 
	 * @Description:  计算基准价
	 * @author guoyr 
	 * @param calculator  
	 */
	public BigDecimal start(PriceScoreCalculator calculator, TenderProjectRuleEntity tenderProjectRuleEntity){
		this.calculator = calculator;
		this.tenderProjectRuleEntity = tenderProjectRuleEntity;
		// 按算术平均法计算基准价
		if(StringUtils.equals(BenchmarkPriceParam.BASE_PRICE_TYPE_AVG, calculator.getBasePriceParam().getBasePriceType())){
			
			getBasePriceByAvg();
		}else if(StringUtils.equals(BenchmarkPriceParam.BASE_PRICE_TYPE_WEIGHT_AVG, calculator.getBasePriceParam().getBasePriceType())){
			
			// 按加权平均法计算基准价
			getBasePriceByWeightAvg();
		}else if(StringUtils.equals(BenchmarkPriceParam.BASE_PRICE_TYPE_AVG_FLOAT_RANGE, calculator.getBasePriceParam().getBasePriceType())){
			// 按算数平均值范围浮动
			getBaseByAvgFloat();
		}else {
			// 以评标价的最高、平均或最低价作为基准价
			getBasePriceByEvalPrice();
		}
		return basePrice;
	}
	
	/**
	 * @Description: 根据算术平均值取基准价
	 * @author guoyr
	 */
	private void getBasePriceByAvg(){
		
		// 如果设置最低价条件，并且投标人家数满足最低价要求
		if(calculator.getBasePriceParam().isUseMinPriceCondition() && calculator.getEffectiveSupplierCount() <= calculator.getBasePriceParam().getSupplierNum()){
			basePrice = calculator.getMinEvalPrice();
		}else {
			// 获得最低价
			BigDecimal minEvalPrice =  calculator.getMinEvalPrice();
			// 否则基准价为平均价
			BigDecimal avgPrice = calculator.getAvgEvalPrice();
			basePrice = avgPrice;
			// 如果设置了K值，则基准价＝平均值*K
			if(null != calculator.getBasePriceParam().getBasePriceFloat()){
				BigDecimal rate = BigDecimalUtils.div(calculator.getBasePriceParam().getBasePriceFloat(), new BigDecimal(100));
				if(calculator.getBasePriceParam().isDownFloat()){
					// 下浮时必须为正数
					if(rate.compareTo(BigDecimal.ZERO) < 0){
						rate = BigDecimalUtils.mul(rate, new BigDecimal(-1));
					}
				}else {
					// 上浮
					if(rate.compareTo(BigDecimal.ZERO) > 0){
						rate = BigDecimalUtils.mul(rate, new BigDecimal(-1));
					}
				}
				basePrice = BigDecimalUtils.mul(avgPrice, BigDecimalUtils.sub(new BigDecimal(1), rate));
			}
			if (calculator.getBasePriceParam().isBasePriceUnderMinPrice() && BigDecimalUtils.compareTo(basePrice, minEvalPrice) < 0) {
				basePrice = minEvalPrice;
			}
		}
	}
	
	/**
	 * @Description: 根据加权平均值取基准价
	 * @author guoyr
	 */
	private void getBasePriceByWeightAvg(){
		// 评标基准价=所有有效投标报价的算术平均值×R+有效报价的最低报价×（1-R）
		basePrice = BigDecimal.ZERO;
		// 第一个固定值默认为平均价
		BigDecimal firstPrice = calculator.getAvgEvalPrice();
		if(ObjectUtils.equals(calculator.getBasePriceParam().getPriceFixedA(), BenchmarkPriceParam.EVAL_PPRICE_FIXED)){
			
			if(null != calculator.getBasePriceParam().getFixedPrice()){
				firstPrice = calculator.getBasePriceParam().getFixedPrice();
			}else if(null != tenderProjectRuleEntity.getControlPrice()){
				firstPrice = tenderProjectRuleEntity.getControlPrice();
			}
		}else if(ObjectUtils.equals(calculator.getBasePriceParam().getPriceFixedA(), BenchmarkPriceParam.EVAL_PPRICE_MIN)){
			firstPrice = calculator.getMinEvalPrice();
		}
		
		if(calculator.getBasePriceParam().isHasK()){
			BigDecimal kValue = getKorRValue(calculator.getBasePriceParam().getKValue());
			if(null != kValue){
				firstPrice = BigDecimalUtils.mul(firstPrice, kValue);
			}
		}
		
		BigDecimal secondPrice = BigDecimal.ZERO;
		
		// 如果存在R值
		if(calculator.getBasePriceParam().isHasR()){
			BigDecimal rValue = getKorRValue(calculator.getBasePriceParam().getRValue());
			firstPrice = BigDecimalUtils.mul(firstPrice, rValue);
			
			// 第二个固定值，默认为最小值
			secondPrice = calculator.getMinEvalPrice();
			if(ObjectUtils.equals(calculator.getBasePriceParam().getPriceFixedB(), BenchmarkPriceParam.EVAL_PPRICE_FIXED)){
				if(null != calculator.getBasePriceParam().getFixedPrice()){
					secondPrice = calculator.getBasePriceParam().getFixedPrice();
				}else if(null != tenderProjectRuleEntity.getControlPrice()){
					secondPrice = tenderProjectRuleEntity.getControlPrice();
				}
			}else if(ObjectUtils.equals(calculator.getBasePriceParam().getPriceFixedB(), BenchmarkPriceParam.EVAL_PPRICE_AVG)){
				secondPrice = calculator.getAvgEvalPrice();
			}
			
			// 固定值* （1-R）
			secondPrice = BigDecimalUtils.mul(secondPrice, BigDecimalUtils.sub(new BigDecimal(1), rValue));
		}else {// 如果没有R，则不加后面的一个值
			secondPrice = BigDecimal.ZERO;
		}
		basePrice = BigDecimalUtils.add(firstPrice, secondPrice);
		
	}
	
	/**
	 * @Description: 按算数平均值范围
	 * @author wangx
	 */
	private void getBaseByAvgFloat(){
		List<AvgFloatRangeItem> avgFloatRangeItemList = calculator.getBasePriceParam().getAvgFloatRangeItemList();
		BigDecimal outRangeFolat = calculator.getBasePriceParam().getOutRangeFolat();
		boolean isOutRangeFolatDownFloat =  calculator.getBasePriceParam().isOutRangeFolatDownFloat();
		//获得有效报价的平均价
		BigDecimal avgPrice = calculator.getAvgEvalPrice();
		
		if(null != avgFloatRangeItemList && avgFloatRangeItemList.size() > 0 ){
			for(AvgFloatRangeItem avgFloatRangeItem : avgFloatRangeItemList){
				boolean  isDownFloat = avgFloatRangeItem.isDownFloat();
				BigDecimal  avgFloat = avgFloatRangeItem.getAvgFloat();
				BigDecimal  floatRangeMin = avgFloatRangeItem.getFloatRangeMin();
				boolean isIncludeFloatRangeMin = avgFloatRangeItem.isIncludeFloatRangeMin();
				BigDecimal  floatRangeMax = avgFloatRangeItem.getFloatRangeMax();
				boolean isIncludeFloatRangeMax = avgFloatRangeItem.isIncludeFloatRangeMax();
				
				//有效评标价
				List<BigDecimal> effectiveEvalPriceList = calculator.getEffectiveEvalPriceList();
				boolean allEffect = true;
				if(null != effectiveEvalPriceList && effectiveEvalPriceList.size() > 0){
					BigDecimal minPrice = BigDecimalUtils.mul(avgPrice, BigDecimalUtils.div(floatRangeMin, new BigDecimal(100)));
					BigDecimal maxPrice = BigDecimalUtils.mul(avgPrice, BigDecimalUtils.div(BigDecimalUtils.add(floatRangeMax, new BigDecimal(1)), new BigDecimal(100)));
					for(int i = 0; i < effectiveEvalPriceList.size(); i++){
						BigDecimal effectPrice = effectiveEvalPriceList.get(i);
						if(isIncludeFloatRangeMin){
							if(isIncludeFloatRangeMax){
								if(effectPrice.compareTo(minPrice) < 0 || effectPrice.compareTo(maxPrice) > 0){
									allEffect = false;
									effectiveEvalPriceList.remove(i--);
								}
							}else{
								if(effectPrice.compareTo(minPrice) < 0 || effectPrice.compareTo(maxPrice) >= 0){
									allEffect = false;
									effectiveEvalPriceList.remove(i--);
								}
							}
						}else{
							if(effectPrice.compareTo(minPrice) <= 0 || effectPrice.compareTo(maxPrice) >= 0){
								allEffect = false;
								effectiveEvalPriceList.remove(i--);
							}
						}
					}
					
					
					if(allEffect){
						if(!isDownFloat){
							basePrice = BigDecimalUtils.mul(BigDecimalUtils.add(BigDecimalUtils.div(avgFloat,new BigDecimal(100)), new BigDecimal(1)), avgPrice);
						}else{
							basePrice = BigDecimalUtils.mul(BigDecimalUtils.sub(new BigDecimal(1),BigDecimalUtils.div(avgFloat,new BigDecimal(100))), avgPrice);
						}
					}else{
						if(effectiveEvalPriceList.size() >= 2){
							//计算剩余有效评标价的算数平均值
							avgPrice = getAvgEvalPrice(effectiveEvalPriceList);
							//上浮
							if(!isOutRangeFolatDownFloat){
								basePrice = BigDecimalUtils.mul(BigDecimalUtils.add(BigDecimalUtils.div(outRangeFolat,new BigDecimal(100)), new BigDecimal(1)), avgPrice);
							}else{
								basePrice = BigDecimalUtils.mul(BigDecimalUtils.sub(new BigDecimal(1),BigDecimalUtils.div(outRangeFolat,new BigDecimal(100))), avgPrice);
							}
						}else{
							basePrice = calculator.getMinEvalPrice();
						}
					}
				}
			}
		}
	}
	
	/**
	 * @Description: 根据评标价获取基准价
	 * @author guoyr
	 */
	private void getBasePriceByEvalPrice(){
		if(ObjectUtils.equals(calculator.getBasePriceParam().getEvaluationPriceType(), BenchmarkPriceParam.EVAL_PPRICE_AVG)){
			basePrice = calculator.getAvgEvalPrice();
		}else if(ObjectUtils.equals(calculator.getBasePriceParam().getEvaluationPriceType(), BenchmarkPriceParam.EVAL_PPRICE_MAX)){
			basePrice = calculator.getMaxEvalPrice();
		}else {
			basePrice = calculator.getMinEvalPrice();
		}
	}
	
	/**
	 * @Description: 获得K或R的系数值
	 * @author guoyr
	 * @param modulus
	 * @return
	 */
	public static BigDecimal getKorRValue(String modulus){
		if(null == modulus || modulus.equals("")){
			return null;
		}
		BigDecimal kValue = BigDecimal.ZERO;
		if(modulus.indexOf(TenderProjectEnum.MODULUS_SEP) > 0){
			String[] modulusArray = modulus.split(TenderProjectEnum.MODULUS_SEP);
			int index = 0;
			for(String modul : modulusArray){
				if(!"".equals(modul)){
					kValue = BigDecimalUtils.add(kValue, new BigDecimal(modul));
					index ++;
				}
			}
			if(index > 1){
				kValue = BigDecimalUtils.div(kValue, new BigDecimal(index));
			}
		}else {
			kValue = new BigDecimal(modulus);
		}
		return BigDecimalUtils.round(kValue, 2);
	}
	
	/**
	 * @Description: 获得有效报价的平均值 
	 * @author wangx
	 * @return
	 */
	public BigDecimal getAvgEvalPrice(List<BigDecimal> effectiveEvalPriceList){
		BigDecimal total = BigDecimal.ZERO;
		for(BigDecimal evaluationPrice : effectiveEvalPriceList){
			total = BigDecimalUtils.add(total, evaluationPrice);
		}
		return BigDecimalUtils.div(total, BigDecimal.valueOf(effectiveEvalPriceList.size()));
	}
}
