package com.gx.obe.evaluation.step.composite.business;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.core.MessageDialog;
import org.eclipse.swt.core.utils.StyledTextUtils;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;

import com.gx.obe.ColorConstants;
import com.gx.obe.business.entity.SupplierEvaluationStep;
import com.gx.obe.components.core.enumeration.EvaluationFactorEnum;
import com.gx.obe.components.core.enumeration.ExpertEnum;
import com.gx.obe.components.core.enumeration.TenderProjectEnum;
import com.gx.obe.evaluation.step.calculator.BusinessBasePriceCalculator;
import com.gx.obe.evaluation.step.calculator.BusinessScoreCalculator;
import com.gx.obe.evaluation.step.entity.BusinessEvalResult;
import com.gx.obe.evaluation.step.entity.BusinessParam;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.util.utils.ListSortUtils;
import com.gx.obe.web.entity.EvaluationFactorResult;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.SupplierOpeningResult;
import com.gx.obe.web.entity.evaluation.EvaluationFactor;
import com.gx.obe.web.entity.evaluation.EvaluationStep;
import com.gx.obe.web.entity.expert.Expert;
import com.gx.obe.web.entity.expert.ExpertEvaluationResult;
import com.gx.obe.web.entity.tender.TenderProjectEntity;
import com.gx.obe.web.entity.tender.TenderProjectRuleEntity;
import com.gx.obe.web.service.evaluation.EvaluationFactorService;
import com.gx.obe.web.service.expert.ExpertEvaluationStepService;
import com.swtdesigner.SWTResourceManager;

/**
 * @Description: 商务评审表格界面
 * @author chenxw
 */
public class BusinessEvaluationTableComposite extends Composite {
    
    private final EvaluationFactorService evaluationFactorService = new EvaluationFactorService();
    private final ExpertEvaluationStepService expertEvaluationStepService = new ExpertEvaluationStepService();
    
    private StyledText evalFactorMemoText;
//	private StyledText computerDetailText;
    private BusinessEvalResultComposite businessEvalResultComposite;
    
    private TenderProjectEntity tenderProject;
    private Expert CURRENT_EXPERT;
    private EvaluationStep evaluationStep;
    private TenderProjectRuleEntity projectRule;
    private List<Supplier> supplierList;
    
    private List<BusinessEvalResult> businessEvalResultList = new ArrayList<BusinessEvalResult>();
    
    private BigDecimal basePrice;
    private EvaluationFactor businessFactor;
    private BusinessParam businessParam;
    private boolean isError;
    private BusinessEvaluationListener listener;
    
    /**
     * @author chenxw
     * @param parent
     * @param style
     */
    public BusinessEvaluationTableComposite(Composite parent, int style) {
        super(parent, style);
        GridLayout gridLayout = new GridLayout(1, false);
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
        setLayout(gridLayout);
        
        Composite evaluationComposite = new Composite(this, SWT.NONE);
        GridLayout gl_evaluationComposite = new GridLayout(1, false);
        gl_evaluationComposite.verticalSpacing = 0;
        gl_evaluationComposite.horizontalSpacing = 0;
        gl_evaluationComposite.marginHeight = 0;
        gl_evaluationComposite.marginWidth = 0;
        evaluationComposite.setLayout(gl_evaluationComposite);
        evaluationComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        evaluationComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
        
        Composite composite_5 = new Composite(evaluationComposite, SWT.NONE);
        GridData gd_composite_5 = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
        gd_composite_5.widthHint = 500;
        composite_5.setLayoutData(gd_composite_5);
        GridLayout gl_composite_5 = new GridLayout(1, false);
        gl_composite_5.marginHeight = 1;
        gl_composite_5.marginWidth = 1;
        gl_composite_5.verticalSpacing = 0;
        gl_composite_5.horizontalSpacing = 0;
        composite_5.setLayout(gl_composite_5);
        composite_5.setBackgroundMode(SWT.INHERIT_FORCE);
        
        evalFactorMemoText = new StyledText(composite_5, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
        evalFactorMemoText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
        evalFactorMemoText.setFont(SWTResourceManager.getFont("微软雅黑", 10, SWT.NORMAL));
        
//		computerDetailText = new StyledText(composite_5, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
//		computerDetailText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
//		computerDetailText.setFont(SWTResourceManager.getFont("微软雅黑", 10, SWT.NORMAL));
        
        Composite composite_1 = new Composite(evaluationComposite, SWT.NONE);
        GridLayout gl_composite_1 = new GridLayout(1, false);
        gl_composite_1.marginHeight = 1;
        gl_composite_1.marginWidth = 1;
        composite_1.setLayout(gl_composite_1);
        composite_1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        composite_1.setBackground(ColorConstants.BORDER_LINE_COLOR);
        
        businessEvalResultComposite = new BusinessEvalResultComposite(composite_1, SWT.NONE);
        
    }
    
    /**
     * @Description: 刷新
     * @author chenxw
     * @param tenderProject
     * @param projectRule
     * @param evaluationStep
     * @param supplierList
     */
    public void refresh(TenderProjectEntity tenderProject, Expert CURRENT_EXPERT, EvaluationStep evaluationStep, TenderProjectRuleEntity projectRule, List<Supplier> supplierList) {
        this.tenderProject = tenderProject;
        this.CURRENT_EXPERT = CURRENT_EXPERT;
        this.evaluationStep = evaluationStep;
        this.projectRule = projectRule;
        this.supplierList = supplierList;
        refreshEvaluationResult();
    }
    
    /**
     * @Description: 刷新评审结果
     * @author chenxw
     */
    private void refreshEvaluationResult() {
        businessFactor = evaluationFactorService.getBillFactoryByType(tenderProject.getId(), EvaluationFactorEnum.FACTOR_BILL);
        if (null == businessFactor) {
            return;
        }
        businessParam = BusinessParam.setSerialize(businessFactor.getComputerParams());
        if (null == businessParam) {
            return;
        }
        refreshForm();
        refreshTableComposite();
        if (isError) {
            listener.error();
            MessageDialog.openError(getShell(), "商务指标配置有误，无法完成评审！");
        }
    }
    
    /**
     * @Description: 刷新表单
     * @author chenxw
     */
    private void refreshForm() {
        StyledTextUtils styledTextUtils = new StyledTextUtils();
        styledTextUtils.addTitle("分值范围：");
        styledTextUtils.addContent("[");
        styledTextUtils.addContent(NumberFormat.getInstance().format(businessFactor.getFactorMinScore()));
        styledTextUtils.addContent("-");
        styledTextUtils.addContent(NumberFormat.getInstance().format(businessFactor.getFactorMaxScore()));
        styledTextUtils.addContent("]");
        styledTextUtils.addContent("(权重");
        styledTextUtils.addContent(BigDecimalUtils.round(businessFactor.getFactorWeight(), 2));
        styledTextUtils.addContent("%)");
        styledTextUtils.addContent("\r\n");
        styledTextUtils.addTitle("计算规则：");
        styledTextUtils.addContent(businessParam.getFormulaContent());
        evalFactorMemoText.setText(styledTextUtils.getText());
        evalFactorMemoText.setStyleRanges(styledTextUtils.getStyleRanges());
    }
    
    /**
     * @Description: 刷新表格界面
     * @author chenxw
     */
    private void refreshTableComposite() {
        try {
            basePrice = getBasePrice();
        } catch (Exception e) {
            isError = true;
            return;
        }
        businessEvalResultList.clear();
        BusinessScoreCalculator scoreCalculator = getBusinessScoreCalculator();
        scoreCalculator.setBasePrice(basePrice);
        for (Supplier supplier : supplierList) {
            businessEvalResultList.add(getBusinessEvalResult(supplier, scoreCalculator));
        }
        refreshEvalResultSort();
        businessEvalResultComposite.refresh(tenderProject, projectRule, basePrice, businessEvalResultList);
    }
    
    /**
     * @Description: 获取商务得分计算器
     * @author chenxw
     * @return
     */
    private BusinessScoreCalculator getBusinessScoreCalculator() {
        BusinessScoreCalculator scoreCalculator = new BusinessScoreCalculator();
        scoreCalculator.setTotalScore(businessFactor.getFactorScore());
        scoreCalculator.setScoreCalculation(businessParam.getScoreCalculation());
        return scoreCalculator;
    }
    
    /**
     * @Description: 获取基准价
     * @author chenxw
     * @return
     * @throws Exception
     */
    private BigDecimal getBasePrice() throws Exception {
        BusinessBasePriceCalculator basePriceCalculator = new BusinessBasePriceCalculator();
        List<BigDecimal> briceList = new ArrayList<BigDecimal>();
        for (Supplier supplier : supplierList) {
            BigDecimal evaluationPrice = null;
            SupplierOpeningResult supplierOpeningResult = supplier.getSupplierOpeningResult();
            if (null != supplierOpeningResult) {
                evaluationPrice = supplierOpeningResult.getEvaluationPrice();
            }
            if (null != evaluationPrice) {
                briceList.add(evaluationPrice);
            }
        }
        basePriceCalculator.setBriceList(briceList);
        String evalMethodType = projectRule.getEvalMethodType();
        BigDecimal basePrice = null;
        if (TenderProjectEnum.SUB_LOW_PRICE.equals(evalMethodType)) {
            basePrice = basePriceCalculator.calculateSubLow();
        }
        if (TenderProjectEnum.RANDOM_AVERAGE_PRICE.equals(evalMethodType)) {
            basePrice = basePriceCalculator.calculateRandomAverage(businessParam.getBasePriceCalculation());
        }
        if (TenderProjectEnum.RATIONAL_AVERAGE_PRICE.equals(evalMethodType)) {
            basePrice = basePriceCalculator.calculateRationalAverage(businessParam.getBasePriceCalculation(), tenderProject.getBidPriceLimit());
        }
        return basePrice;
    }
    
    /**
     * @Description: 获取得分结果
     * @author chenxw
     * @param supplier
     * @param scoreCalculator
     * @return
     */
    private BusinessEvalResult getBusinessEvalResult(Supplier supplier, BusinessScoreCalculator scoreCalculator) {
        BusinessEvalResult businessEvalResult = new BusinessEvalResult();
        businessEvalResult.setSupplierId(supplier.getId());
        businessEvalResult.setSupplierName(supplier.getSupplierName());
        BigDecimal bidPrice = null;
        BigDecimal evaluationPrice = null;
        SupplierOpeningResult supplierOpeningResult = supplier.getSupplierOpeningResult();
        if (null != supplierOpeningResult) {
            bidPrice = supplierOpeningResult.getBidPrice();
            evaluationPrice = supplierOpeningResult.getEvaluationPrice();
        }
        businessEvalResult.setBidPrice(bidPrice);
        businessEvalResult.setEvaluationPrice(evaluationPrice);
        BigDecimal biasPercentage = scoreCalculator.calculateBiasPercentage(evaluationPrice);
        businessEvalResult.setDeviationRate(biasPercentage);
        businessEvalResult.setScore(scoreCalculator.calculateScore(biasPercentage));
        return businessEvalResult;
    }
    
    /**
     * @Description: 刷新评审结果排序
     * @author chenxw
     */
    private void refreshEvalResultSort() {
        Comparator<BusinessEvalResult> comparator = new Comparator<BusinessEvalResult>() {
            public int compare(BusinessEvalResult result1, BusinessEvalResult result2) {
                BigDecimal score1 = result1.getScore();
                if (null == score1) {
                    score1 = BigDecimal.valueOf(Integer.MAX_VALUE);
                }
                BigDecimal score2 = result2.getScore();
                if (null == score2) {
                    score2 = BigDecimal.valueOf(Integer.MAX_VALUE);
                }
                return score2.compareTo(score1);
            }
        };
        ListSortUtils<BusinessEvalResult> listSortUtils = new ListSortUtils<BusinessEvalResult>(businessEvalResultList, comparator);
        for (BusinessEvalResult businessEvalResult : businessEvalResultList) {
            businessEvalResult.setSortNo(listSortUtils.getSortNo(businessEvalResult));
        }
        Collections.sort(businessEvalResultList, comparator);
    }
    
    /**
     * @Description: 保存评审结果
     * @author chenxw
     * @return
     */
    public boolean saveEvaluationResult() {
        List<EvaluationFactorResult> evaluationFactorResultList = new ArrayList<EvaluationFactorResult>();
        List<ExpertEvaluationResult> expertEvaluationResultList = new ArrayList<ExpertEvaluationResult>();
        for (BusinessEvalResult businessEvalResult : businessEvalResultList) {
            evaluationFactorResultList.add(initEvaluationFactorResult(businessEvalResult));
            expertEvaluationResultList.add(initExpertEvaluationResult(businessEvalResult));
        }
        return expertEvaluationStepService.saveBusinessEvaluationResult(tenderProject.getId(), CURRENT_EXPERT.getUserId(), evaluationStep, evaluationFactorResultList, expertEvaluationResultList);
    }
    
    /**
     * @Description: 初始化评审指标结果
     * @author chenxw
     * @param supplierId
     * @return
     */
    private EvaluationFactorResult initEvaluationFactorResult(BusinessEvalResult businessEvalResult) {
        EvaluationFactorResult evaluationFactorResult = new EvaluationFactorResult();
        evaluationFactorResult.setTenderId(tenderProject.getId());
        evaluationFactorResult.setStepId(evaluationStep.getId());
        evaluationFactorResult.setSupplierId(businessEvalResult.getSupplierId());
        evaluationFactorResult.setUserId(ExpertEnum.COMMON_EXPERT);
        evaluationFactorResult.setFactorId(businessFactor.getId());
        evaluationFactorResult.setFactorName(businessFactor.getFactorName());
        evaluationFactorResult.setBasePrice(basePrice);
        evaluationFactorResult.setDeviationRate(businessEvalResult.getDeviationRate());
        evaluationFactorResult.setEvaluationScore(businessEvalResult.getScore());
        evaluationFactorResult.setEvaluationFinalScore(businessEvalResult.getScore().multiply(BigDecimalUtils.div(businessFactor.getFactorWeight(), BigDecimal.valueOf(100))));
        return evaluationFactorResult;
    }
    
    /**
     * @Description: 初始化专家评审结果
     * @author chenxw
     * @return
     */
    private ExpertEvaluationResult initExpertEvaluationResult(BusinessEvalResult businessEvalResult) {
        ExpertEvaluationResult expertEvaluationResult = new ExpertEvaluationResult();
        expertEvaluationResult.setTenderId(tenderProject.getId());
        expertEvaluationResult.setStepId(evaluationStep.getId());
        expertEvaluationResult.setUserId(ExpertEnum.COMMON_EXPERT);
        expertEvaluationResult.setSupplierId(businessEvalResult.getSupplierId());
        expertEvaluationResult.setEvaluationScore(businessEvalResult.getScore());
        expertEvaluationResult.setEvaluationFinalScore(businessEvalResult.getScore().multiply(BigDecimalUtils.div(businessFactor.getFactorWeight(), BigDecimal.valueOf(100))));
        expertEvaluationResult.setSortNo(businessEvalResult.getSortNo());
        return expertEvaluationResult;
    }
    
    /**
     * @Description: 初始化供应商评审步骤
     * @author chenxw
     * @param businessEvalResult
     * @return
     */
    private SupplierEvaluationStep initSupplierEvaluationStep(BusinessEvalResult businessEvalResult) {
        SupplierEvaluationStep supplierEvaluationStep = new SupplierEvaluationStep();
        supplierEvaluationStep.setTenderId(tenderProject.getId());
        supplierEvaluationStep.setStepId(evaluationStep.getId());
        supplierEvaluationStep.setSupplierId(businessEvalResult.getSupplierId());
        supplierEvaluationStep.setEvaluationScore(businessEvalResult.getScore());
        supplierEvaluationStep.setEvaluationFinalScore(businessEvalResult.getScore().multiply(BigDecimalUtils.div(businessFactor.getFactorWeight(), BigDecimal.valueOf(100))));
        supplierEvaluationStep.setSortNo(businessEvalResult.getSortNo());
        return supplierEvaluationStep;
    }
    
    /**
     * @Description: 提交评审结果
     * @author chenxw
     * @return
     */
    public boolean submitEvaluationResult() {
        List<SupplierEvaluationStep> supplierEvaluationStepList = new ArrayList<SupplierEvaluationStep>();
        for (BusinessEvalResult businessEvalResult : businessEvalResultList) {
            supplierEvaluationStepList.add(initSupplierEvaluationStep(businessEvalResult));
        }
        return expertEvaluationStepService.submitBusinessEvaluationResult(tenderProject.getId(), CURRENT_EXPERT.getUserId(), evaluationStep, supplierEvaluationStepList);
    }
    
    public void addBusinessEvaluationListener(BusinessEvaluationListener listener) {
        this.listener = listener;
    }
    
    public interface BusinessEvaluationListener {
        void error();
    }
    
    protected void checkSubclass() {}
    
}
