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

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.swt.SWT;
import org.eclipse.swt.core.ImageResolver;
import org.eclipse.swt.core.MessageDialog;
import org.eclipse.swt.custom.CLabel;
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.components.core.I18NEnum;
import com.gx.obe.common.icons.IconsActivator;
import com.gx.obe.message.Messages;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.util.utils.NumberFormatUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.util.utils.SortUtils;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.SupplierEvaluationResult;
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.SupplierEvaluationResultService;
import com.gx.obe.web.service.evaluation.EvaluationFactorService;
import com.gx.obe.web.service.expert.ExpertEvaluationResultService;
import com.gx.obe.web.service.expert.ExpertEvaluationStepService;
import com.swtdesigner.ResourceManager;
import com.swtdesigner.SWTResourceManager;

import de.kupzog.ktable.KTable;
import de.kupzog.ktable.SWTX;
import de.kupzog.ktable.editors.KTableCellEditorText;
import de.kupzog.ktable.model.CommonKtableCModel;
import de.kupzog.ktable.renderers.CellAlignmentRender;
import de.kupzog.ktable.renderers.CellContentRender;
import de.kupzog.ktable.renderers.CellEditContentRender;
import de.kupzog.ktable.renderers.CellEditorRender;
import de.kupzog.ktable.renderers.CellRender;
import de.kupzog.ktable.renderers.FixedWrapCellRenderer;
import de.kupzog.ktable.renderers.TextWrapCellRenderer;

/**
 * @Description: 信用评审面板
 * @author chenxw
 */
public class CreditEvaluationTableComposite extends Composite {

	private ImageResolver imageResolver = new ImageResolver();
	private Composite evaluationTableComposite;
	private List<Supplier> supplierList;
	private TenderProjectEntity tenderProjectEntity;
	private EvaluationStep evaluationStep;
	private Expert CURRENT_EXPERT;
	private ExpertEvaluationStepService expertEvaluationStepService ;;
	private ExpertEvaluationResultService expertEvaluationResultService;
	private SupplierEvaluationResultService supplierEvaluationResultService ;
	private EvaluationFactorService evaluationFactorService = new EvaluationFactorService();
	private Map<String, ExpertEvaluationResult> expertEvaluationResultMap;
	private String supplierName;
	private KTable resultKTable;
	private CLabel cleanTenderStepName;
	private int scoreRound = 2;
	private BigDecimal creditRate;
	private boolean hasCreditRate = false;
	private EvaluationFactor creditEvaluationFactor;
	private String creditSourceName;

	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 */
	public CreditEvaluationTableComposite(Composite parent, int style) {
		super(parent, style);
		GridLayout gridLayout = new GridLayout(1, false);
		gridLayout.marginHeight = 0;
		gridLayout.marginWidth = 0;
		setLayout(gridLayout);
		setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		Composite evaluationComposite = new Composite(this, SWT.NONE);
		evaluationComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		evaluationComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		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);

		Composite headComposite = new Composite(evaluationComposite, SWT.NONE);
		headComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		GridData gd_composite_5 = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_composite_5.widthHint = 500;
		headComposite.setLayoutData(gd_composite_5);
		GridLayout gl_composite_5 = new GridLayout(1, false);
		headComposite.setLayout(gl_composite_5);
		headComposite.setBackgroundMode(SWT.INHERIT_FORCE);
		
		cleanTenderStepName = new CLabel(headComposite, SWT.NONE);
		cleanTenderStepName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, true, 1, 1));
		cleanTenderStepName.setFont(SWTResourceManager.getFont("微软雅黑", 10, SWT.NORMAL));
		cleanTenderStepName.setImage(ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/tips_blue.png"));
		
		Composite bodyComposite = new Composite(evaluationComposite, SWT.NONE);
		bodyComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		GridLayout gl_composite_1 = new GridLayout(1, false);
		gl_composite_1.marginHeight = 1;
		gl_composite_1.marginWidth = 1;
		bodyComposite.setLayout(gl_composite_1);
		bodyComposite.setBackground(ColorConstants.BORDER_LINE_COLOR);

		evaluationTableComposite = new Composite(bodyComposite, SWT.NONE);
		evaluationTableComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		GridLayout gl_evaluationTableComposite = new GridLayout(1, false);
		gl_evaluationTableComposite.marginHeight = 0;
		gl_evaluationTableComposite.marginWidth = 0;
		evaluationTableComposite.setLayout(gl_evaluationTableComposite);
		GridData gd_evaluationTableComposite = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_evaluationTableComposite.minimumHeight = 200;
		evaluationTableComposite.setLayoutData(gd_evaluationTableComposite);
		supplierEvaluationResultService = new SupplierEvaluationResultService();
		expertEvaluationStepService = new ExpertEvaluationStepService();
		expertEvaluationResultService = new ExpertEvaluationResultService();
	}

	/**
	 * @Description: 初始化
	 * @author chenxw
	 * @param evaluationStep
	 * @param tenderProjectEntity
	 */
	public void refresh(TenderProjectEntity tenderProjectEntity, TenderProjectRuleEntity tenderProjectRuleEntity, EvaluationStep evaluationStep, Expert curExpert, List<Supplier> supplierList) {
		this.tenderProjectEntity = tenderProjectEntity;
		this.evaluationStep = evaluationStep;
		this.CURRENT_EXPERT = curExpert;
		this.supplierList = supplierList;
		scoreRound = tenderProjectRuleEntity.getScoreRoundIntVal();
		creditRate = evaluationStep.getEvaluationParamByKey(com.gx.obe.components.core.enumeration.EvaluationStepEnum.PARAM_CREDIT_RATE, BigDecimal.class);
		creditSourceName = evaluationStep.getEvaluationParamByKey(com.gx.obe.components.core.enumeration.EvaluationStepEnum.PARAM_CREDIT_SOURCE_NAME);
		if(null == creditSourceName || creditSourceName.length() == 0){
			creditSourceName = "信息网查询得分";
		}
		if (null != creditRate && creditRate.compareTo(BigDecimal.ZERO) != 0) {
			hasCreditRate = true;
		}else {
			hasCreditRate = false;
		}
		expertEvaluationResultMap = new HashMap<String, ExpertEvaluationResult>();
		
		initEvaluationStepFactor();
		initEvaluationResult();
		drawEvaluationTable();
	}

	/**
	 * @Description: 初始化当前评标步骤的评审指标
	 * @author guoyr
	 */
	private void initEvaluationStepFactor(){
		List<EvaluationFactor> evaluationTopFactorList = evaluationFactorService.getEvaluationStepFactorTreeList(tenderProjectEntity.getId(), evaluationStep);
		if(null != evaluationTopFactorList && evaluationTopFactorList.size() > 0){
			creditEvaluationFactor = evaluationTopFactorList.get(0);
		}
	}
	
	private void initEvaluationResult() {
		supplierName = com.gx.obe.components.core.I18N.getString(I18NEnum.SUPPLIERNAME, tenderProjectEntity.getTenderType());
		cleanTenderStepName.setText("直接录入" + supplierName + "的综合信用得分！");
		List<ExpertEvaluationResult> queryExpertEvaluationResultList = expertEvaluationResultService.getExpertStepAllSupplierEvaluationResultList(tenderProjectEntity.getId(), evaluationStep.getId(), CURRENT_EXPERT.getUserId());
		List<SupplierEvaluationResult> supplierEvaluationResultList = supplierEvaluationResultService.getSupplierEvaluationResultListByTenderId(tenderProjectEntity.getId());
		for (Supplier supplier : supplierList) {
			SupplierEvaluationResult supplierEvaluationResult = null;
			if(null != supplierEvaluationResultList && supplierEvaluationResultList.size() > 0){
				for(SupplierEvaluationResult evalResult : supplierEvaluationResultList){
					if(ObjectUtils.equals(evalResult.getSupplierId(), supplier.getId())){
						supplierEvaluationResult = evalResult;
						break;
					}
				}
			}
			if (null == supplierEvaluationResult) {
				supplierEvaluationResult = new SupplierEvaluationResult();
				supplierEvaluationResult.setTenderId(tenderProjectEntity.getId());
				supplierEvaluationResult.setSupplierId(supplier.getId());
			}
			supplier.setSupplierEvaluationResult(supplierEvaluationResult);
			// 获取评标专家对投标人的评审记录
			ExpertEvaluationResult expertEvaluationResult = null;
			if (null != queryExpertEvaluationResultList && queryExpertEvaluationResultList.size() > 0) {
				for (ExpertEvaluationResult queryExpertEvaluationResult : queryExpertEvaluationResultList) {
					if (ObjectUtils.equals(queryExpertEvaluationResult.getSupplierId(), supplier.getId())) {
						expertEvaluationResult = queryExpertEvaluationResult;
						break;
					}
				}
			}
			if (null == expertEvaluationResult) {
				expertEvaluationResult = new ExpertEvaluationResult();
				expertEvaluationResult.setTenderId(tenderProjectEntity.getId());
				expertEvaluationResult.setStepId(evaluationStep.getId());
				expertEvaluationResult.setUserId(CURRENT_EXPERT.getUserId());
				expertEvaluationResult.setSupplierId(supplier.getId());
				expertEvaluationResult.setAccessment(com.gx.obe.components.core.enumeration.EvaluationStepEnum.QUALIFIED);
			}
			expertEvaluationResultMap.put(supplier.getId(), expertEvaluationResult);
		}
	}

	/**
	 * @Description: 供应商表格
	 * @author chenxw
	 */
	private void drawEvaluationTable() {
		if(null != resultKTable && !resultKTable.isDisposed()){
			resultKTable.dispose();
		}
		
		resultKTable = new KTable(evaluationTableComposite, SWTX.AUTO_SCROLL | SWT.FULL_SELECTION | SWTX.EDIT_ON_KEY);
		resultKTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		final int creditSourceScoreCol = hasCreditRate ? 1 : -1;
		final int evaluationScoreCol = hasCreditRate ? 2 : 1;
		final int sortCol = hasCreditRate ? 3 : 2;
		final CommonKtableCModel commKTableModel = new CommonKtableCModel(resultKTable, 1, 1, supplierList.size() , hasCreditRate ? 3 : 2);
		commKTableModel.setColumnMinWidth(1, 200);
		commKTableModel.setColumnMaxWidth(commKTableModel.getColCount() -1, 100);
		
		final String[] tableTitles = new String[commKTableModel.getColCount()];
		tableTitles[0] = supplierName;
		if(creditSourceScoreCol > 0){
			tableTitles[creditSourceScoreCol] = creditSourceName;
		}
		tableTitles[evaluationScoreCol] = null != creditEvaluationFactor ? creditEvaluationFactor.getFactorName() : "信用得分";
		tableTitles[sortCol] = Messages.SortNo;
		
		// 设置单元格内容
		CellContentRender contentRender = new CellContentRender(){
			public Object receiveContent(int row, int col) {
				if (row < commKTableModel.getFixedRowCount()) {
					return tableTitles[col];
				} else {
					int supplierIndex = row - commKTableModel.getFixedRowCount();
					Supplier supplier = supplierList.get(supplierIndex);
					if (col == 0) {
						return supplier.getSupplierName();
					} else {
						ExpertEvaluationResult expertEvaluationResult = expertEvaluationResultMap.get(supplier.getId());
						if (null != expertEvaluationResult) {
							if (col == creditSourceScoreCol) {
								if(null != expertEvaluationResult.getEvaluationScore() && null != creditRate && null != creditEvaluationFactor && null != creditEvaluationFactor.getFactorScore()){
									return BigDecimalUtils.round(BigDecimalUtils.mul(expertEvaluationResult.getEvaluationScore().divide(creditEvaluationFactor.getFactorScore()), creditRate), scoreRound);
								}
							} else if (col == evaluationScoreCol) {
								if(null != expertEvaluationResult.getEvaluationScore()){
									return NumberFormatUtils.format(expertEvaluationResult.getEvaluationScore(), scoreRound);
								}
							} else if (col == sortCol && expertEvaluationResult.getSortNoIntValue() > 0) {
								return expertEvaluationResult.getSortNoIntValue()+"";
							}
						}
					}
				}
				return "";
			}
		};
		commKTableModel.setCellContentRender(contentRender);
		
		// 设置单元格编辑器
        final KTableCellEditorText text = new KTableCellEditorText();
		text.setSingleClickEdit(true);
		CellEditorRender cellEditorRender = new CellEditorRender(){
			public Object receiveCellEditor(int row, int col) {
				if(null != creditEvaluationFactor && row >= commKTableModel.getFixedRowCount()){
					if(hasCreditRate){
						if(col == creditSourceScoreCol){
							return text;
						}
					}else {
						if(col == evaluationScoreCol){
							return text;
						}
					}
				}
				return null;
			}
		};
		commKTableModel.setCellEditorRender(cellEditorRender);
		
		// 编辑单元格内容
		CellEditContentRender editContentRender = new CellEditContentRender(){
			private boolean isShowError;

			public void receiveContent(int row, int col, Object content) {
				if(null == content)return;
				if(row >= commKTableModel.getFixedRowCount()){
					int supplierIndex = row - commKTableModel.getFixedRowCount();
					Supplier supplier = supplierList.get(supplierIndex);
					ExpertEvaluationResult expertEvaluationResult = expertEvaluationResultMap.get(supplier.getId());
					BigDecimal score = ObjectUtils.getObjBigDecimal(content);
					if (null != expertEvaluationResult && null != creditEvaluationFactor) {
						BigDecimal evaluationScore = score;
						if(null != evaluationScore){
							if(hasCreditRate){
								if(col == creditSourceScoreCol){
									if(evaluationScore.compareTo(creditRate) > 0 || evaluationScore.compareTo(creditEvaluationFactor.getFactorMinScore()) < 0){
										if(!isShowError){
											isShowError = true;
											MessageDialog.openError(getShell(), MessageFormat.format(Messages.Tips_entryScroeRange, creditEvaluationFactor.getFactorMinScore(), creditRate));
											isShowError = false;
										}
										return;
									}
									evaluationScore = BigDecimalUtils.div(score.multiply(BigDecimal.valueOf(100)), creditRate, scoreRound);
								}
							}else {
								if(col == evaluationScoreCol){
									if(evaluationScore.compareTo(creditEvaluationFactor.getFactorMaxScore()) > 0 || evaluationScore.compareTo(creditEvaluationFactor.getFactorMinScore()) < 0){
										if(!isShowError){
											isShowError = true;
											MessageDialog.openError(getShell(), MessageFormat.format(Messages.Tips_entryScroeRange,creditEvaluationFactor.getFactorMinScore(), creditEvaluationFactor.getFactorMaxScore()));
											isShowError = false;
										}
										return;
									}
								}
							}
						}
						BigDecimal evaluationFinalScore = getEvaluationFinalScore(evaluationScore);
						expertEvaluationResult.setEvaluationScore(evaluationScore);
						expertEvaluationResult.setEvaluationFinalScore(evaluationFinalScore);
						reSetSortNo();
						resultKTable.redraw();
					}
				}
			}
		};
		commKTableModel.setCellEditContentRender(editContentRender);
		
		// 编辑单元格对齐方式
		CellAlignmentRender cellAlignmentRender = new CellAlignmentRender(){
			public int receiveCellAlignment(int row, int col) {
				if(row >= commKTableModel.getFixedRowCount() && col == 0){
					return SWTX.ALIGN_VERTICAL_CENTER | SWTX.ALIGN_HORIZONTAL_LEFT;
				}
				return SWTX.ALIGN_VERTICAL_CENTER | SWTX.ALIGN_HORIZONTAL_CENTER;
			}
		};
		commKTableModel.setCellAlignmentRender(cellAlignmentRender);
		
		// 设置单元格渲染器
		CellRender cellRender = new CellRender() {
			public Object receiveCellRender(int row, int col) {
				if (commKTableModel.isFixedCell(col, row)) {
					return new FixedWrapCellRenderer();
				} else {
					return new TextWrapCellRenderer();
				}
			}
		};
		commKTableModel.setCellRender(cellRender);
		resultKTable.setModel(commKTableModel);
		evaluationTableComposite.layout();
	}

	/**
	 * @Description: 得到最终得分
	 * @author guoyr
	 * @param evaluationFactor
	 * @param evaluationScore
	 * @return 
	 */
	private BigDecimal getEvaluationFinalScore(BigDecimal evaluationScore){
		BigDecimal evaluationFinalScore = evaluationScore;
		BigDecimal weight = null != creditEvaluationFactor ? creditEvaluationFactor.getFactorFinalWeight() : null;
		if(null != evaluationScore && null != weight && weight.compareTo(BigDecimal.ZERO) > 0){
			evaluationFinalScore = BigDecimalUtils.div(BigDecimalUtils.mul(weight, evaluationScore), new BigDecimal(100));
		}
		return BigDecimalUtils.round(evaluationFinalScore, scoreRound);
	}
	
	/**
	 * @Description: 设置排名
	 * @author guoyr 
	 */
	private void reSetSortNo(){
		List<Double> sortList = new ArrayList<Double>();
		
		// 每次进入评审界面都采用公式重新计算的
		for(Supplier supplier : supplierList){
			ExpertEvaluationResult expertEvaluationResult = expertEvaluationResultMap.get(supplier.getId());
			if(null != expertEvaluationResult && null != expertEvaluationResult.getEvaluationFinalScore()){
				sortList.add(expertEvaluationResult.getEvaluationFinalScore().doubleValue());
			}
		}
		SortUtils sortUtil = new SortUtils(sortList);
		for(Entry<String, ExpertEvaluationResult> expertEvaluationResultEntry : expertEvaluationResultMap.entrySet()){
			ExpertEvaluationResult expertEvaluationResult = expertEvaluationResultEntry.getValue();
			if(null != expertEvaluationResult.getEvaluationFinalScore()){
				expertEvaluationResultEntry.getValue().setSortNo(sortUtil.getSortNo(expertEvaluationResult.getEvaluationFinalScore().doubleValue()));
			}else {
				expertEvaluationResultEntry.getValue().setSortNo(0);
			}
		}
	}
	
	/**
	 * @Description: 保存评审结果
	 * @author chenxw
	 * @return
	 */
	public boolean saveVetoBidEvaluationResult() {
		return expertEvaluationStepService.saveVetoBidEvaluationResult(tenderProjectEntity.getId(), CURRENT_EXPERT.getUserId(), evaluationStep, expertEvaluationResultMap);
	}

	/**
	 * @Description: 提交评审结果
	 * @author chenxw
	 * @return
	 */
	public boolean submitCreditEvaluationResult() {
		return expertEvaluationStepService.submitCreditEvaluationResult(tenderProjectEntity.getId(), CURRENT_EXPERT.getUserId(), evaluationStep, supplierList, expertEvaluationResultMap);
	}

	/**
	 * @Description: 释放资源
	 * @author chenxw
	 */
	public void dispose() {
		imageResolver.disposite();
		super.dispose();
	}

	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}
}
