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

import java.math.BigDecimal;

import org.apache.log4j.Logger;

import com.gx.obe.DictValueEnum;
import com.gx.obe.components.core.Constants;
import com.gx.obe.evaluation.step.inter.BillCheckerCache;
import com.gx.obe.evaluation.step.inter.IChecker;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.util.utils.UuidUtils;
import com.gx.obe.web.entity.CheckResult;
import com.gx.obe.web.entity.DictionaryValue;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.boq.ConstructProject;
import com.gx.obe.web.entity.evaluation.EvaluationStep;
import com.gx.obe.web.entity.tender.TenderProjectEntity;

public class BaseChecker {
	
	DictionaryValue dictionaryValue;
	EvaluationStep evaluationStep;
	Supplier supplier;
	TenderProjectEntity tenderProject;
	ConstructProject constructProject;
	CheckResult checkResult;
	BillCheckerCache cacheListener;
	Logger LOG = Logger.getLogger(BaseChecker.class);
	
	private boolean isStop = false;
	
	public CheckResult getCheckResult() {
		return checkResult;
	}
	
	public void setCheckResult(CheckResult checkResult) {
		this.checkResult = checkResult;
	}
	
	public ConstructProject getConstructProject() {
		return constructProject;
	}
	
	public void setConstructProject(ConstructProject constructProject) {
		this.constructProject = constructProject;
	}
	
	public DictionaryValue getDictionaryValue() {
		return dictionaryValue;
	}
	
	public void setDictionaryValue(DictionaryValue dictionaryValue) {
		this.dictionaryValue = dictionaryValue;
	}
	
	public EvaluationStep getEvaluationStep() {
		return evaluationStep;
	}
	
	public void setEvaluationStep(EvaluationStep evaluationStep) {
		this.evaluationStep = evaluationStep;
	}
	
	public Supplier getSupplier() {
		return supplier;
	}
	
	public void setSupplier(Supplier supplier) {
		this.supplier = supplier;
	}
	
	public TenderProjectEntity getTenderProject() {
		return tenderProject;
	}
	
	public void setTenderProject(TenderProjectEntity tenderProject) {
		this.tenderProject = tenderProject;
	}
	
	public BillCheckerCache getCacheListener() {
		return cacheListener;
	}
	
	public void setCacheListener(BillCheckerCache cacheListener) {
		this.cacheListener = cacheListener;
	}
	
	public void init(TenderProjectEntity tenderProject, Supplier supplier, EvaluationStep evaluationStep, DictionaryValue dictionaryValue, CheckResult checkResult, ConstructProject constructProject) {
		this.tenderProject = tenderProject;
		this.evaluationStep = evaluationStep;
		this.supplier = supplier;
		this.dictionaryValue = dictionaryValue;
		this.constructProject = constructProject;
		this.checkResult = checkResult;
		isStop = false;
	}
	
	public void check(TenderProjectEntity tenderProject, Supplier supplier, EvaluationStep evaluationStep, DictionaryValue dictionaryValue) {
		this.tenderProject = tenderProject;
		this.evaluationStep = evaluationStep;
		this.supplier = supplier;
		this.dictionaryValue = dictionaryValue;
	}
	
	public CheckResult initCheckResult(CheckResult checkResult) {
		if (null == checkResult) {
			checkResult = new CheckResult();
		}
		checkResult.setId(UuidUtils.getUUID());
		checkResult.setCheckItemId(this.getDictionaryValue().getId());
		checkResult.setTenderId(tenderProject.getId());
		checkResult.setStepId(evaluationStep.getId());
		checkResult.setSupplierId(supplier.getId());
		checkResult.setUserId(Constants.USER.getId());
		return checkResult;
	}
	
	/**
	 * Description: 获得清标结果
	 * Create Date: Jul 14, 20144:09:34 PM<br/>
	 * Author : guoyr <br/>
	 * Modify Date: <br/>
	 * Modify By : <br/>
	 * 
	 * @param tenderProject
	 * @param evaluationStep
	 * @param dictionaryValue
	 * @param supplier
	 * @return
	 */
	public static IChecker getCleanTenderChecker(TenderProjectEntity tenderProject, Supplier supplier, EvaluationStep evaluationStep, DictionaryValue dictionaryValue, CheckResult checkResult, ConstructProject constructProject, BillCheckerCache cacheListener) {
		IChecker checker = null;
		// 算术性错误检查
		if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.ARITHMETIC_ERROR)) {
			checker = new ArithmeticErrorChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.ERROR_LEAK)) {
			// 错漏项检查
			checker = new ErrorLeakItemChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.GUIFEI_RATE_CHECK)) {
			// 规费费率检查
			checker = new RatesCompeteItemChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.AQWMSGF_RATE_CHECK)) {
			// 安全文明施工费费率检查
			checker = new RatesCompeteItemChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.TAX_RATE_CHECK)) {
			// 税金费率检查
			if (null != dictionaryValue.getDictValueDesc() && dictionaryValue.getDictValueDesc().equals("unit")) {
				checker = new TaxFeesChecker();
			} else {
				checker = new SingleConstructionTaxFeesChecker();
			}
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.INVENTORY_PRICE)) {
			// 清单报价检查
			checker = new InventoryPriceChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.MATERIAL_PRICE)) {
			// 材料报价检查
			checker = new MaterialPriceItemChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.UNCOMPETE_CHECK)) {
			// 不可竞争费检查
//			checker = new UnCompeteItemChecker();
		}
		if (checker == null) {
			return null;
		}
		checker.addBillItemCacheListener(cacheListener);
		checker.init(tenderProject, supplier, evaluationStep, dictionaryValue, checkResult, constructProject);
//		if(null != checker){
//			try {
//				checker.check(tenderProject, supplier, evaluationStep, dictionaryValue,constructProject ,cacheDataClass,checkResult);
//			} catch (Exception e) {
//			}
//		}
		
		return checker;
	}
	
	/**
	 * Description: 获得清标结果
	 * Create Date: Jul 14, 20144:09:34 PM<br/>
	 * Author : guoyr <br/>
	 * Modify Date: <br/>
	 * Modify By : <br/>
	 * 
	 * @param tenderProject
	 * @param evaluationStep
	 * @param dictionaryValue
	 * @param supplier
	 * @return
	 */
	public static IChecker getCleanTenderChecker(TenderProjectEntity tenderProject, EvaluationStep evaluationStep, DictionaryValue dictionaryValue, Supplier supplier) {
		//mazhichao_在次之前无需优化
		IChecker checker = null;
		// 算术性错误检查
		if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.ARITHMETIC_ERROR)) {
			checker = new ArithmeticErrorChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.ERROR_LEAK)) {
			// 错漏项检查
			checker = new ErrorLeakItemChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.INVENTORY_PRICE)) {
			// 清单报价检查
			checker = new InventoryPriceChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.MATERIAL_PRICE)) {
			// 材料报价检查
			checker = new MaterialPriceItemChecker();
		} else if (ObjectUtils.equals(dictionaryValue.getDictValueCode(), DictValueEnum.CleanTender.UNCOMPETE_CHECK)) {
			// 不可竞争费检查
//			checker = new UnCompeteItemChecker();
			
		}
		if (null != checker) {
			checker.check(tenderProject, supplier, evaluationStep, dictionaryValue);
		}
		
		return checker;
	}
	
	public boolean isReasonable(BigDecimal srouceValue, BigDecimal calculateValue, BigDecimal baseRate) {
		String calculationError = evaluationStep.getEvaluationParamByKey(EvaluationStep.CALCULATION_ERROR);
		// 如果是根据差额率来计算
		if (ObjectUtils.equals(calculationError, EvaluationStep.CALCULATION_ERROR_RATE)) {
			BigDecimal rate = evaluationStep.getEvaluationParamByKey(EvaluationStep.CALCULATION_ERROR_RATE, BigDecimal.class);
			if (null == rate || rate.compareTo(BigDecimal.ZERO) == 0) {
				rate = BigDecimal.valueOf(5);
			}
			
			BigDecimal differenceRate = getDifferenceRate(srouceValue, calculateValue);
			if (differenceRate.compareTo(rate) > 0) {
				return true;
			} else {
				return false;
			}
		} else {
			
			BigDecimal value = evaluationStep.getEvaluationParamByKey(EvaluationStep.CALCULATION_ERROR_VALUE, BigDecimal.class);
			if (null == value || value.compareTo(BigDecimal.ZERO) == 0) {
				value = BigDecimal.valueOf(20);
			}
			BigDecimal _difference = getDifference(srouceValue, calculateValue);
			if (_difference.compareTo(value) > 0) {
				return true;
			} else {
				return false;
			}
		}
	}
	
	public BigDecimal getDifference(BigDecimal srouceValue, BigDecimal calculateValue) {
		if (null == srouceValue || calculateValue == null) return BigDecimal.ZERO;
		
		BigDecimal difference = srouceValue.subtract(calculateValue);
		if (null == difference) {
			difference = BigDecimal.ZERO;
		}
		if (difference.compareTo(BigDecimal.ZERO) > 0) {
			return difference;
		} else {
			return BigDecimal.ZERO.subtract(difference);
		}
	}
	
	public BigDecimal getDifferenceRate(BigDecimal srouceValue, BigDecimal calculateValue) {
		BigDecimal differenceRate = BigDecimalUtils.mul(BigDecimalUtils.div(getDifference(srouceValue, calculateValue), srouceValue), BigDecimal.valueOf(100));
		return differenceRate;
	}
	
	public boolean isSame(BigDecimal cmp1, BigDecimal cmp2) {
		if (null == cmp1) {
			cmp1 = BigDecimal.ZERO;
		}
		if (null == cmp2) {
			cmp2 = BigDecimal.ZERO;
		}
		return cmp1.compareTo(cmp2) == 0;
		
	}
	
	public boolean isStop() {
		return isStop;
	}
	
	public void stopCheck() {
		isStop = true;
	}
	
	public void addBillItemCacheListener(BillCheckerCache cacheListener) {
		this.cacheListener = cacheListener;
	}
}
