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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import com.gx.obe.evaluation.step.entity.BusinessParam;
import com.gx.obe.util.utils.BigDecimalUtils;

public class BusinessBasePriceCalculator {
    
    private List<BigDecimal> briceList = new ArrayList<BigDecimal>();
    
    public void setBriceList(List<BigDecimal> briceList) {
        this.briceList = briceList;
    }
    
    /**
     * @Description: 计算基准价
     * @author chenxw
     * @param price
     * @return
     * @throws Exception
     */
    public BigDecimal calculateSubLow() {
        if (briceList.isEmpty()) {
            return BigDecimal.ZERO;
        }
        if (briceList.size() == 1) {
            return briceList.get(0);
        }
        List<BigDecimal> list = new ArrayList<BigDecimal>(briceList);
        list.remove(Collections.min(list));
        return Collections.min(list);
    }
    
    /**
     * @Description: 计算基准价
     * @author chenxw
     * @param price
     * @return
     * @throws Exception
     */
    public BigDecimal calculateRandomAverage(BusinessParam.BasePriceCalculation basePriceCalculation) {
        if (null == basePriceCalculation) {
            return null;
        }
        return getArithMean().multiply(BigDecimal.valueOf(basePriceCalculation.getExtractPercentageC() / 100d));
    }
    
    /**
     * @Description: 计算基准价
     * @author chenxw
     * @param price
     * @return
     * @throws Exception
     */
    public BigDecimal calculateRationalAverage(BusinessParam.BasePriceCalculation basePriceCalculation, BigDecimal limitPrice) throws Exception {
        if (null == basePriceCalculation || null == limitPrice) {
            return null;
        }
        BigDecimal extractRateC1 = BigDecimal.valueOf(basePriceCalculation.getExtractPercentageC1() / 100d);
        BigDecimal extractRateC2 = BigDecimal.valueOf(basePriceCalculation.getExtractPercentageC2() / 100d);
        BigDecimal weightRateQ1 = BigDecimalUtils.div(basePriceCalculation.getWeightPercentageQ1(), BigDecimal.valueOf(100));
        BigDecimal weightRateQ2 = BigDecimalUtils.div(basePriceCalculation.getWeightPercentageQ2(), BigDecimal.valueOf(100));
        BigDecimal partArithPrice = getArithMean().multiply(extractRateC1).multiply(weightRateQ1);
        BigDecimal partLimitPrice = limitPrice.multiply(extractRateC2).multiply(weightRateQ2);
        return partArithPrice.add(partLimitPrice);
    }
    
    /**
     * @Description:
     * @author chenxw
     * @return
     */
    private BigDecimal getArithMean() {
        BigDecimal averageValue = null;
        if (briceList.size() < 20) {
            averageValue = getAverageValue(briceList);
        } else {
            averageValue = getAverageValue(removeHighestPriceLowestPrice());
        }
        return BigDecimalUtils.round(averageValue, 2);
    }
    
    /**
     * @Description: 获取平均值
     * @author chenxw
     * @param briceList
     * @return
     */
    private BigDecimal getAverageValue(List<BigDecimal> briceList) {
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (BigDecimal brice : briceList) {
            totalPrice = totalPrice.add(brice);
        }
        return BigDecimalUtils.div(totalPrice, BigDecimal.valueOf(briceList.size()));
    }
    
    private List<BigDecimal> removeHighestPriceLowestPrice() {
        LinkedList<BigDecimal> list = new LinkedList<BigDecimal>(briceList);
        Collections.sort(list);
        for (int i = 0; i < briceList.size() / 5; i++) {
            list.pollFirst();
            list.pollLast();
        }
        return list;
    }
    
}
