package com.gx.obe.evaluation.step.review.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 org.eclipse.swt.SWT;
import org.eclipse.swt.core.MessageDialog;
import org.eclipse.swt.core.widgets.ELink;
import org.eclipse.swt.core.widgets.ESepator;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
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.EditPriceItem;
import com.gx.obe.business.entity.EditPriceItemResult;
import com.gx.obe.common.icons.IconsActivator;
import com.gx.obe.common.widget.composite.TitleComposite;
import com.gx.obe.common.widget.dialog.SetEditPriceItemDialog;
import com.gx.obe.components.core.Constants;
import com.gx.obe.components.core.I18NEnum;
import com.gx.obe.components.core.enumeration.BidPriceEnum;
import com.gx.obe.components.core.util.MoneyUtils;
import com.gx.obe.evaluation.step.composite.SingleEvaluationComposite;
import com.gx.obe.evaluation.step.dialog.EditPriceResultDialog;
import com.gx.obe.message.Messages;
import com.gx.obe.util.utils.BigDecimalUtils;
import com.gx.obe.util.utils.CollectionUtils;
import com.gx.obe.util.utils.ObjectUtils;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.price.BidPrice;
import com.gx.obe.web.entity.price.BidPriceResult;
import com.gx.obe.web.service.BidPriceResultService;
import com.gx.obe.web.service.BidPriceService;
import com.gx.obe.web.service.EditPriceItemResultService;
import com.gx.obe.web.service.EditPriceItemService;
import com.gx.obe.web.service.SupplierService;
import com.swtdesigner.ResourceManager;

import de.kupzog.ktable.KTable;
import de.kupzog.ktable.SWTX;
import de.kupzog.ktable.editors.KTableCellEditorLink;
import de.kupzog.ktable.model.CommonKtableCModel;
import de.kupzog.ktable.renderers.CellAlignmentRender;
import de.kupzog.ktable.renderers.CellContentRender;
import de.kupzog.ktable.renderers.CellEditorRender;
import de.kupzog.ktable.renderers.CellEventActionRender;
import de.kupzog.ktable.renderers.CellImageRender;
import de.kupzog.ktable.renderers.CellRender;
import de.kupzog.ktable.renderers.FixedWrapCellRenderer;
import de.kupzog.ktable.renderers.LinkCellRenderer;
import de.kupzog.ktable.renderers.TextWrapCellRenderer;

/**
 * @Description: 修正报价界面
 * @author chenxw
 */
public class EditPriceComposite extends SingleEvaluationComposite {
	
	private SupplierService supplierService = new SupplierService();
	private EditPriceItemService editPriceItemService ;
	private EditPriceItemResultService editPriceItemResultService ;
	private BidPriceService bidPriceService;
	private BidPriceResultService bidPriceResultService;
	
	private ELink setEditPriceItemLink;
	private Composite resultTableComposite; 
	private KTable resultTable;
	
	/**
	 * 固定行
	 */
	private int headRow = 2;
	/**
	 * 固定列
	 */
	private int headCol = 1;
	/**
	 * 评标价列
	 */
	private int evaluationPriceCol;
	/**
	 * 操作列
	 */
	private int operateCol;
	
	private List<Supplier> supplierList;
	private List<EditPriceItem> editPriceItemList;
	
	/**
	 * 修正报价结果
	 */
	private Map<String, Map<String, EditPriceItemResult>> editPriceItemResultMapMap = new HashMap<String, Map<String, EditPriceItemResult>>();
	
	/**
	 * 投标报价结果
	 */
	private Map<String, BidPriceResult> bidPriceResultMap = new HashMap<String, BidPriceResult>();
	
	/**
	 * 单元格内容
	 */
	private Map<Point, String> contentMap = new HashMap<Point, String>();
	
	/**
	 * 单元格监听器
	 */
	private Map<Point, CellEventActionRender> eventActionRenderMap = new HashMap<Point, CellEventActionRender>();
	
	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 */
	public EditPriceComposite(Composite parent, int style) {
		super(parent, style);
		
		TitleComposite titleComposite = new TitleComposite(price_evaluation_table, SWT.NONE);
		titleComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		ESepator titleSep = new ESepator(price_evaluation_table, SWT.HORIZONTAL);
		titleSep.setBackground(ColorConstants.SEP_LIGHT_COLOR);
		titleSep.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		
		setEditPriceItemLink = titleComposite.addELink("SET_CHANGE");
		setEditPriceItemLink.addMouseListener(new MouseAdapter() {
			public void mouseUp(MouseEvent e) {
				setEditPriceItemAction();
			}
		});
		setEditPriceItemLink.setText("设置修正报价项");
		
		resultTableComposite = new Composite(price_evaluation_table, SWT.NONE);
		GridLayout gl_resultTableComposite = new GridLayout(1, false);
		gl_resultTableComposite.marginHeight = 0;
		gl_resultTableComposite.marginWidth = 0;
		resultTableComposite.setLayout(gl_resultTableComposite);
		resultTableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
	}
	
	/**
	 * @Description: 刷新项目信息
	 * @author chenxw
	 */
	protected void refreshTenderInfo() {
		super.refreshTenderInfo();
		if(null == bidPriceResultService){
			bidPriceResultService =new BidPriceResultService();
		}
		if(null == editPriceItemService){
			editPriceItemService = new EditPriceItemService();
		}
		if(null == editPriceItemResultService){
			editPriceItemResultService = new EditPriceItemResultService();
		}
		supplierList = supplierService.getEvaluationStepSupplierList(tenderProjectEntity.getId(), evaluationStep);
		if (null == supplierList) supplierList = new ArrayList<Supplier>();
		editPriceItemList = editPriceItemService.getEditPriceItemList(tenderProjectEntity.getId());
		if (null == editPriceItemList) editPriceItemList = new ArrayList<EditPriceItem>();
		
		editPriceItemResultMapMap.clear();
		List<EditPriceItemResult> editPriceItemResultList = editPriceItemResultService.getEditPriceItemResultList(tenderProjectEntity.getId());
		if (CollectionUtils.isNotNull(editPriceItemResultList)) for (EditPriceItemResult editPriceItemResult : editPriceItemResultList) {
			Map<String, EditPriceItemResult> editPriceItemResultMap = editPriceItemResultMapMap.get(editPriceItemResult.getSupplierId());
			if (null == editPriceItemResultMap) {
				editPriceItemResultMap = new HashMap<String, EditPriceItemResult>();
				editPriceItemResultMapMap.put(editPriceItemResult.getSupplierId(), editPriceItemResultMap);
			}
			editPriceItemResultMap.put(editPriceItemResult.getEditPriceItemId(), editPriceItemResult);
		}
		if(null == bidPriceService){
			bidPriceService = new BidPriceService();
		}
		
		BidPrice bidPrice = bidPriceService.getBidPriceByJoinTotal(tenderProjectEntity.getId());
		
		bidPriceResultMap.clear();
		List<BidPriceResult> bidPriceResultList = bidPriceResultService.getBidPriceResultList(tenderProjectEntity.getId(), bidPrice.getId());
		if (CollectionUtils.isNotNull(bidPriceResultList)) for (BidPriceResult bidPriceResult : bidPriceResultList) {
			bidPriceResultMap.put(bidPriceResult.getSupplierId(), bidPriceResult);
		}
		
		refreshTable();
	}
	
	/**
	 * @Description: 刷新表格
	 * @author chenxw
	 */
	private void refreshTable() {
		if (null != resultTable) resultTable.dispose();
		
		resultTable = new KTable(resultTableComposite, SWTX.AUTO_SCROLL | SWT.FULL_SELECTION | SWTX.FILL_WITH_LASTCOL | SWTX.EDIT_ON_KEY);
		resultTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		
		final CommonKtableCModel model = new CommonKtableCModel(resultTable, headRow, headCol, supplierList.size(), editPriceItemList.size() * 2 + 2);
		model.setContentRowHeight(Constants.ROW_HIGHT);
		resultTable.setModel(model);
		
		evaluationPriceCol = editPriceItemList.size() * 2 + headCol;
		operateCol = evaluationPriceCol + 1;
		
		contentMap.clear();
		eventActionRenderMap.clear();
		
		refreshTableTitle(model);
		refreshTableContent();
		
		setCellRender(model);
		
		resultTableComposite.layout();
	}
	
	/**
	 * @Description: 刷新表头
	 * @author chenxw
	 * @param model
	 */
	private void refreshTableTitle(CommonKtableCModel model) {
		String supplierName = com.gx.obe.components.core.I18N.getString(I18NEnum.SUPPLIERNAME, tenderProjectEntity.getTenderType());
		
		contentMap.put(new Point(0, 0), MessageFormat.format(Messages.NameFormat, supplierName));
		model.addRowSpan(0, 0, 2);
		model.setColumnWidth(0, 300);
		
		String editPriceTitle = "修正报价";
		String editReasonTitle = "修正原因";
		for (int i = 0; i < editPriceItemList.size(); i++) {
			contentMap.put(new Point(0, i * 2 + headCol), editPriceItemList.get(i).getItemName());
			model.addColSpan(0, i * 2 + headCol, 2);
			contentMap.put(new Point(1, i * 2 + headCol), editPriceTitle);
			model.setColumnWidth(i * 2 + headCol, 100);
			contentMap.put(new Point(1, i * 2 + headCol + 1), editReasonTitle);
			model.setColumnWidth(i * 2 + headCol + 1, 200);
		}
		
		contentMap.put(new Point(0, evaluationPriceCol), "评标价（" + tenderProjectRuleEntity.getPriceUnitUseDefault() + "）");
		model.addRowSpan(0, evaluationPriceCol, 2);
		model.setColumnWidth(evaluationPriceCol, 100);
		
		contentMap.put(new Point(0, operateCol), "操作");
		model.addRowSpan(0, operateCol, 2);
		model.setColumnWidth(operateCol, 100);
	}
	
	/**
	 * @Description: 刷新表内容
	 * @author chenxw
	 */
	private void refreshTableContent() {
		String operate = "修正";
		for (int i = 0; i < supplierList.size(); i++) {
			Supplier supplier = supplierList.get(i);
			
			BidPriceResult bidPriceResult = bidPriceResultMap.get(supplier.getId());
			if (null == bidPriceResult) continue;
			BigDecimal priceOriginal = bidPriceResult.getEvaluationPriceOriginal();
			if (null == priceOriginal) priceOriginal = bidPriceResult.getBidPrice();
			if (null == priceOriginal) continue;
			if (priceOriginal.compareTo(BigDecimal.ZERO) == 0) continue;
			
			Map<String, EditPriceItemResult> editPriceItemResultMap = editPriceItemResultMapMap.get(supplier.getId());
			if (null == editPriceItemResultMap) {
				editPriceItemResultMap = new HashMap<String, EditPriceItemResult>();
				editPriceItemResultMapMap.put(supplier.getId(), editPriceItemResultMap);
			}
			
			contentMap.put(new Point(i + headRow, 0), supplier.getSupplierName());
			
			refreshSupplierEditPriceResult(i + headRow, supplier.getId(), editPriceItemResultMap, bidPriceResult, priceOriginal);
			
			contentMap.put(new Point(i + headRow, operateCol), operate);
			eventActionRenderMap.put(new Point(i + headRow, operateCol), getCellEventActionRender(supplier, editPriceItemResultMap, bidPriceResult, priceOriginal));
		}
	}
	
	/**
	 * @Description: 获取评标价
	 * @author chenxw
	 * @param priceOriginal
	 * @param editPriceItemResultMap
	 * @return 
	 */
	private BigDecimal getEvaluationPrice(BigDecimal priceOriginal, Map<String, EditPriceItemResult> editPriceItemResultMap) {
		BigDecimal evaluationPrice = priceOriginal;
		for (String editPriceItemId : editPriceItemResultMap.keySet())
			evaluationPrice = BigDecimalUtils.add(evaluationPrice, editPriceItemResultMap.get(editPriceItemId).getEditPrice());
		return evaluationPrice;
	}
	
	/**
	 * @Description: 获取修正报价结果
	 * @author chenxw
	 * @param supplierId
	 * @param editPriceItemId
	 * @param editPriceItemResultMap 
	 * @return
	 */
	private EditPriceItemResult getEditPriceItemResult(String supplierId, String editPriceItemId, Map<String, EditPriceItemResult> editPriceItemResultMap) {
		EditPriceItemResult editPriceItemResult = editPriceItemResultMap.get(editPriceItemId);
		if (null == editPriceItemResult) {
			editPriceItemResult = new EditPriceItemResult();
			editPriceItemResult.setTenderId(tenderProjectEntity.getId());
			editPriceItemResult.setSupplierId(supplierId);
			editPriceItemResult.setEditPriceItemId(editPriceItemId);
			editPriceItemResultMap.put(editPriceItemId, editPriceItemResult);
		}
		return editPriceItemResult;
	}
	
	/**
	 * @Description: 获取单元格编辑器
	 * @author chenxw
	 * @param supplier 
	 * @param editPriceItemResultMap 
	 * @param bidPriceResult 
	 * @param priceOriginal 
	 * @param editPriceItemResult
	 * @param editPriceItem
	 * @param priceOriginal
	 * @return
	 */
	private CellEventActionRender getCellEventActionRender(final Supplier supplier, final Map<String, EditPriceItemResult> editPriceItemResultMap, final BidPriceResult bidPriceResult, final BigDecimal priceOriginal) {
		return new CellEventActionRender() {
			public void receiveAction(int row, int col) {
				EditPriceResultDialog dialog = new EditPriceResultDialog(getShell(), editPriceItemList, editPriceItemResultMap, tenderProjectRuleEntity, priceOriginal);
				dialog.setSupplierName(supplier.getSupplierName());
				dialog.open();
				refreshSupplierEditPriceResult(row, supplier.getId(), editPriceItemResultMap, bidPriceResult, priceOriginal);
			}
		};
	}
	
	private void refreshSupplierEditPriceResult(int row, String supplierId, Map<String, EditPriceItemResult> editPriceItemResultMap, BidPriceResult bidPriceResult, BigDecimal priceOriginal) {
		for (int j = 0; j < editPriceItemList.size(); j++) {
			EditPriceItem editPriceItem = editPriceItemList.get(j);
			EditPriceItemResult editPriceItemResult = getEditPriceItemResult(supplierId, editPriceItem.getId(), editPriceItemResultMap);
			
			contentMap.put(new Point(row, j * 2 + headCol), getEditPriceString(editPriceItemResult.getEditPrice(), editPriceItem.getEditType(), priceOriginal));
			contentMap.put(new Point(row, j * 2 + headCol + 1), editPriceItemResult.getEditReason());
		}
		
		bidPriceResult.setEvaluationPrice(getEvaluationPrice(priceOriginal, editPriceItemResultMap));
		
		contentMap.put(new Point(row, evaluationPriceCol), bidPriceResult.getFormatEvaluatoinPriceByUnit(tenderProjectRuleEntity.getEvalPriceUnit()));
	}
	
	/**
	 * @Description: 获取修正报价
	 * @author chenxw
	 * @param editPrice
	 * @param editType
	 * @param priceOriginal
	 * @return
	 */
	private String getEditPriceString(BigDecimal editPrice, String editType, BigDecimal priceOriginal) {
		StringBuilder editPriceString = new StringBuilder();
		if (null != editPrice) {
			if (BidPriceEnum.EDIT_ADD_SUB.equals(editType)) {
				if (editPrice.compareTo(BigDecimal.ZERO) < 0) {
					editPriceString.append("减少");
					editPrice = editPrice.multiply(BigDecimal.valueOf(-1));
				} else {
					editPriceString.append("增加");
				}
				editPriceString.append(MoneyUtils.getMoneyWidthUnit(editPrice, tenderProjectRuleEntity.getPriceUnitUseDefault()));
			} else if (BidPriceEnum.EDIT_FLOAT.equals(editType)) {
				if (editPrice.compareTo(BigDecimal.ZERO) < 0) {
					editPriceString.append("下浮");
					editPrice = editPrice.multiply(BigDecimal.valueOf(-1));
				} else {
					editPriceString.append("上浮");
				}
				editPriceString.append(moneyToFloat(editPrice, priceOriginal));
			}
		}
		return editPriceString.toString();
	}
	
	/**
	 * @Description: 金额转浮动
	 * @author chenxw
	 * @param editPrice
	 * @param priceOriginal
	 * @return 
	 */
	private String moneyToFloat(BigDecimal editPrice, BigDecimal priceOriginal) {
		return editPrice.multiply(BigDecimal.valueOf(100)).divide(priceOriginal, 2, BigDecimal.ROUND_HALF_UP).toPlainString().concat("%");
	}
	
	/**
	 * @Description: 设置单元格渲染器
	 * @author chenxw
	 * @param model
	 */
	private void setCellRender(final CommonKtableCModel model) {
		model.setCellContentRender(new CellContentRender() {
			public Object receiveContent(int row, int col) {
				return ObjectUtils.getObjString(contentMap.get(new Point(row, col)));
			}
		});
		
		// 设置单元格渲染器
		final FixedWrapCellRenderer fixedWrapCellRenderer = new FixedWrapCellRenderer();
		final LinkCellRenderer linkCellRenderer = new LinkCellRenderer();
		final TextWrapCellRenderer textWrapCellRenderer = new TextWrapCellRenderer();
		model.setCellRender(new CellRender() {
			public Object receiveCellRender(int row, int col) {
				if (model.isFixedCell(col, row)) return fixedWrapCellRenderer;
				if (col == operateCol) return linkCellRenderer;
				return textWrapCellRenderer;
			}
		});
		
		model.setCellEditorRender(new CellEditorRender() {
			public Object receiveCellEditor(int row, int col) {
				CellEventActionRender eventActionRender = eventActionRenderMap.get(new Point(row, col));
				if (null == eventActionRender) return null;
				return new KTableCellEditorLink(resultTable, eventActionRender);
			}
		});
		
		// 设置单元格图片
		final Image editImage = ResourceManager.getPluginImage(IconsActivator.PLUGIN_ID, "icons/btn/blue/edit.png");
		model.setCellImageRender(new CellImageRender() {
			public Image receiveCellImage(int row, int col) {
				if (row >= headRow && col == operateCol) return editImage;
				return null;
			}
		});
		
		// 编辑单元格对齐方式
		model.setCellAlignmentRender(new CellAlignmentRender() {
			public int receiveCellAlignment(int row, int col) {
				if (row < headRow) return SWTX.ALIGN_VERTICAL_CENTER | SWTX.ALIGN_HORIZONTAL_CENTER;
				if (col == evaluationPriceCol) return SWTX.ALIGN_VERTICAL_CENTER | SWTX.ALIGN_HORIZONTAL_RIGHT;
				return SWTX.ALIGN_VERTICAL_CENTER | SWTX.ALIGN_HORIZONTAL_LEFT;
			}
		});
	}
	
	/**
	 * @Description: 设置修正报价项
	 * @author chenxw 
	 */
	private void setEditPriceItemAction() {
		if (!setEditPriceItemLink.getEnabled()) return;
		new SetEditPriceItemDialog(getShell(), tenderProjectEntity).open();
		refreshTenderInfo();
		saveEditPriceResult();
	}
	
	/**
	 * @Description: 保存评标结果
	 * @author chenxw
	 */
	protected void saveEvaluationResultAction() {
		super.saveEvaluationResultAction();
		
		if (saveEditPriceResult()) {
			MessageDialog.openShortMessage(Messages.Tips_saveEvalResultSuccess);
		} else {
			MessageDialog.openInformation(getShell(), Messages.Dialog_warmTips, Messages.Tips_saveEvalResultFailed);
		}
	}
	
	/**
	 * @Description: 评审完成
	 * @author chenxw
	 */
	protected boolean submitEvaluationResultAction() {
		if (!saveEditPriceResult()) {
			MessageDialog.openWarning(getShell(), Messages.Dialog_warmTips, Messages.Tips_saveEvalResultFailed);
			return false;
		}
		if (!super.submitEvaluationResultAction()) {
			return false;
		}
		if (!expertEvaluationStepService.submitEditPriceResult(tenderProjectEntity.getId(), evaluationStep, curExpert.getUserId())) {
			MessageDialog.openWarning(getShell(), Messages.Dialog_warmTips, Messages.Tips_submitEvalResultFailed);
			return false;
		}
		goBackAction();
		return true;
	}
	
	/**
	 * @Description: 保存修正报价结果
	 * @author chenxw
	 * @return
	 */
	private boolean saveEditPriceResult() {
		List<EditPriceItemResult> editPriceItemResultList = CollectionUtils.mapToArrayList(editPriceItemResultMapMap);
		List<BidPriceResult> bidPriceResultList = CollectionUtils.mapToArrayList(bidPriceResultMap);
		
		return expertEvaluationStepService.saveEditPriceResult(tenderProjectEntity.getId(), evaluationStep, editPriceItemResultList, bidPriceResultList);
	}
	
	protected void checkSubclass() {}
	
}
