package nc.ui.cmp.settlement.actions;

import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.swing.Action;

import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.cmp.pub.exception.ExceptionHandler;
import nc.cmp.settlement.validate.SettleValidate;
import nc.cmp.utils.CmpUtils;
import nc.cmp.utils.DataUtil;
import nc.cmp.utils.SettleUtils;
import nc.funcnode.ui.action.INCAction;
import nc.itf.cmp.ebank.ICMPPaymentService;
import nc.itf.cmp.pub.CmpSelfDefButtonNameConst;
import nc.itf.cmp.settlement.ISettlementQueryService;
import nc.pubitf.bbd.CurrtypeQuery;
import nc.ui.pub.beans.MessageDialog;
import nc.ui.pub.beans.UIDialog;
import nc.ui.uif2.ShowStatusBarMsgUtil;
import nc.ui.uif2.model.AbstractUIAppModel;
import nc.vo.cmp.BusiStatus;
import nc.vo.cmp.SettleStatus;
import nc.vo.cmp.settlement.CheckException;
import nc.vo.cmp.settlement.NetpayTransferVO;
import nc.vo.cmp.settlement.PaymentInfoVO4Batch;
import nc.vo.cmp.settlement.SettleEnumCollection.Direction;
import nc.vo.cmp.settlement.SettlementAggVO;
import nc.vo.cmp.settlement.SettlementBodyVO;
import nc.vo.cmp.settlement.SettlementHeadVO;
import nc.vo.cmp.settlement.international.util.SettleInternationalValidate;
import nc.vo.cmp.validate.CMPValidate;
import nc.vo.obm.pay.OnlinePaymentVO;
import nc.vo.obm.sec.ObmCAInfoAccessor;
import nc.vo.obm.sec.ObmCASignature;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDouble;
import nc.vo.tmpub.util.TMCurrencyUtil;

/**
 * 结算信息列表界面网上转账按钮类
 * 
 * @author xwq
 * 
 */
@SuppressWarnings("restriction")
public class SettleListNetPayTransferAction extends SettleDefaultAction {

	/**
	 *
	 */
	private static final long serialVersionUID = 8899125168078379198L;

	public SettleListNetPayTransferAction() {

		setBtnName(CmpSelfDefButtonNameConst.getInstance().getConstBtnnameNetpaytransferName());
		putValue(Action.SHORT_DESCRIPTION, getBtnName());
		putValue(INCAction.CODE, "网上转账");/*-=notranslate=-*/

	}

	@Override
	public void doAction(ActionEvent e) throws Exception {
		SettlementAggVO[] selectedOperaDatas = getSelectedAggVOs();
		
		CheckException
				.checkArgument(selectedOperaDatas == null,
						nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0052")/*@res "请选择需要操作的单据"*/);
		StringBuffer error = new StringBuffer("业务单据编号:");
		for (SettlementAggVO settlementAggVO : selectedOperaDatas) {
			//表头原币金额
			UFDouble headPrimal = (UFDouble) settlementAggVO.getParentVO().getAttributeValue("primal");
			//表体原币金额
			UFDouble bodyPrimal = new UFDouble(0.00);
			SettlementBodyVO [] settlementBodyVOs = (SettlementBodyVO[]) settlementAggVO.getChildrenVO();
			for (SettlementBodyVO settlementBodyVO : settlementBodyVOs) {
				bodyPrimal = bodyPrimal.add(settlementBodyVO.getPay_last());
			}
			if(headPrimal.compareTo(bodyPrimal) != 0) {
				String billcode = (String) settlementAggVO.getParentVO().getAttributeValue("billcode");
				error.append(billcode);
				error.append(",");
			}
		}
		if(error.length() != 7) {
			throw new BusinessException(error+"表体合计金额不等于表头金额!");
		}
		List<SettlementAggVO> aggLst = SettleUtils.filterSettleInfo4NetSettleFlagUnSettle(selectedOperaDatas);
		if (aggLst.size() == 0) {
			ShowStatusBarMsgUtil
					.showErrorMsg(
							nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set1_0", "03607set1-0078")/*@res "提示"*/,
							nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set1_0", "03607set1-0079")/*@res "没有可网银支付的表体记录"*/,
							getModel().getContext());
			return;
		}
		
		selectedOperaDatas =aggLst.toArray(new SettlementAggVO[0]);

		int len = selectedOperaDatas.length;

		if (len > 1) {
			for (Object aggvo : selectedOperaDatas) {
				SettlementHeadVO settlementHeadVO = (SettlementHeadVO) ((SettlementAggVO) aggvo).getParentVO();
				// 付款结算工资发放单据不能批量网上转账
				if ("DS".equals(settlementHeadVO.getPk_tradetype())) {
					ExceptionHandler.createandthrowException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID(
							"3607set1_0", "03607set1-0227"));
				}
			}
		} else {
			SettlementHeadVO head = (SettlementHeadVO) ((SettlementAggVO) selectedOperaDatas[0]).getParentVO();
			// 工资发放单据,走特殊网银支付接口
			String pk_tradetype = head.getPk_tradetype();
			if ("DS".equals(pk_tradetype)) {

				int num = MessageDialog
						.showYesNoDlg(
								getEdit(),
								nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0029")/*@res "提示"*/,
								nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0050")/*@res "确定进行网上支付？"*/);
				if (num != UIDialog.ID_YES) {
					return;
				}
				this.getEdit().getClientSigner().identifyCA();

				doSalaryBillNetPay((SettlementAggVO) selectedOperaDatas[0]);
				String id = selectedOperaDatas[0].getParentVO().getPrimaryKey();
				
				// 重新查一次，数据已经被更新。
				SettlementAggVO[] newaggvos = NCLocator.getInstance().lookup(ISettlementQueryService.class).querySettlementAggVOsByPks(new String[]{id});
				showNetPayTransferInfo(this.getModel() ,newaggvos);
				return ;

			}
		}

		SettlementAggVO[] aggvos = new SettlementAggVO[len];
		List<String> ids = new LinkedList<String>();
		for (int i = 0; i < len; i++) {
			aggvos[i] = (SettlementAggVO) selectedOperaDatas[i];
			ids.add(aggvos[i].getParentVO().getPrimaryKey());
		}
		
		NCLocator.getInstance().lookup(ICMPPaymentService.class).validatePay(selectedOperaDatas);

		int num = MessageDialog
				.showYesNoDlg(
						getEdit(),
						nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0029")/*@res "提示"*/,
						nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0050")/*@res "确定进行网上支付？"*/);
		if (num != UIDialog.ID_YES) {
			return;
		}
		

		try {
			// 执行批量网上转账
			PaymentInfoVO4Batch[] retnsgs = doBatchZhuanzhang(aggvos);
			
			// 重新查一次，数据已经被更新。
			SettlementAggVO[] newaggvos = NCLocator.getInstance().lookup(ISettlementQueryService.class)
					.querySettlementAggVOsByPks(ids.toArray(new String[0]));
			getModel().directlyUpdate(newaggvos);
			// 如果是取消操作，则不提示信息
			if (retnsgs == null) {
				return;
			}
			showNetPayTransferInfo(this.getModel(), retnsgs);
		} catch (BusinessException ex) {
			Logger.error(ex.getMessage(), ex);
			throw new BusinessException(ex.getMessage());
		}
	}

	@Override
	protected boolean isActionEnable() {

		SettlementAggVO[] aggvos = getSelectedAggVOs();
		if (aggvos == null || aggvos.length == 0 || aggvos[0] == null) {
			return false;
		}

		for (SettlementAggVO settlementAggVO : aggvos) {
			
			

			SettlementAggVO currentAggvo = settlementAggVO;
			SettlementHeadVO head = (SettlementHeadVO) currentAggvo.getParentVO();
			// 收款类不能 支付
			if (nc.vo.cmp.settlement.SettleEnumCollection.Direction.REC.VALUE.equals(head.getDirection())) {
				return false;
			}

			if (head.getBusistatus() == null || !head.getBusistatus().equals(BusiStatus.Sign.getBillStatusKind())) {
				// 非签字态的不能网上支付
				return false;
			}
			if (head.getPk_ftsbill() != null) {
				// 资金组织生成的结算信息不能网上支付
				return false;
			}
			if (SettleUtils.isExistInnerAccount(currentAggvo)) {
				// 有内部账户的不能网上支付
				return false;
			}
			for (SettlementBodyVO body : (SettlementBodyVO[]) settlementAggVO.getChildrenVO()) {
				if (body.getSettlestatus() != null
						&& body.getSettlestatus().equals(SettleStatus.SETTLERESET.getStatus())) {
					// 含有结算红冲的信息，不能反操作
					return false;
				}
			}
		
		}
		return true;

	}

	/**
	 * 工资发放网上支付
	 * 
	 * @param settlement
	 * @throws BusinessException
	 */
	private void doSalaryBillNetPay(SettlementAggVO settlement) throws BusinessException {

		ICMPPaymentService service = NCLocator.getInstance().lookup(ICMPPaymentService.class);
		service.doNetTransfer4SalaryBill(DataUtil.getCurrentUser(), settlement);
	}

	// 提示网上支付成功信息
	public static void showNetPayTransferInfo(AbstractUIAppModel model, PaymentInfoVO4Batch[] batch)
			throws BusinessException {

		int successCount = 0;
		StringBuffer successMsg = new StringBuffer();

		int failCount = 0;
		StringBuffer failMsg = new StringBuffer();

		for (PaymentInfoVO4Batch one : batch) {
			if (one.getEx() != null) {
				failCount++;
				failMsg.append(((SettlementHeadVO) one.getAggvo().getParentVO()).getBillcode());
				failMsg.append("\n");
				failMsg.append(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0053")/*@res "错误原因："*/);
				failMsg.append(one.getEx().getMessage());
				failMsg.append("\n");
			} else {
				successCount++;
				successMsg.append(((SettlementHeadVO) one.getAggvo().getParentVO()).getBillcode());
				successMsg.append(" ;");
			}
		}

		StringBuffer allMsg = new StringBuffer();
		if (successCount > 0) {
			allMsg.append(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0051")/*@res "网上支付成功"*/)
					.append(successCount)
					.append(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0054")/*@res "张单据"*/);
			allMsg.append("\n");
			allMsg.append(successMsg);
		} else {
			allMsg.append(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0055")/*@res "网上支付失败"*/)
					.append(successCount)
					.append(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0054")/*@res "张单据"*/);
			allMsg.append("\n");
			allMsg.append(failMsg);
		}
		ShowStatusBarMsgUtil.showStatusBarMsg(allMsg.toString(), model.getContext());

	}
	
	
	
	// 提示网上支付成功信息
		public static void showNetPayTransferInfo(AbstractUIAppModel model, SettlementAggVO[] bills)
				throws BusinessException {

			Map<String, UFDouble> map = new HashMap<String, UFDouble>();
			int size = 0;

			for (SettlementAggVO aggvo : bills) {
				size++;
				SettlementBodyVO[] children = (SettlementBodyVO[]) aggvo.getChildrenVO();
				for (SettlementBodyVO child : children) {
					if (child.getDirection().equals(Direction.PAY.VALUE)
							&& Integer.valueOf(SettleStatus.PAYFAIL.getStatus()).equals(child.getSettlestatus())) {
						String currtype = child.getPk_currtype();
						int orgCurrRateDigit = TMCurrencyUtil.getCurrtypeDigit(child.getPk_currtype());
						UFDouble money = new UFDouble(child.getPay().getDouble(), orgCurrRateDigit);
						if (map.containsKey(currtype)) {
							UFDouble sumMoney = map.get(currtype);
							map.put(currtype, sumMoney.add(money));

						} else {
							map.put(currtype, money);
						}
					}
				}
			}

			if (size > 0) {
				CurrtypeQuery currtypeQuery = CurrtypeQuery.getInstance();
				StringBuffer sBuffer = new StringBuffer();
				sBuffer.append(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0051")/*
																													* @
																													* res
																													* "发送网银成功"
																													*/)
						.append(size)
						.append(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("3607set_0", "03607set-0011")/*
																													 * @
																													 * res
																													 * "张单据。"
																													 */);
				Iterator iterator = map.entrySet().iterator();
				while (iterator.hasNext()) {
					Map.Entry entry = (Map.Entry) iterator.next();
					sBuffer.append("	").append(currtypeQuery.getCurrtypeName((String) entry.getKey())).append(": ");
					sBuffer.append(entry.getValue()).append("\n");
				}

				ShowStatusBarMsgUtil.showStatusBarMsg(sBuffer.toString(), model.getContext());
			}
		}
	
	

	/**
	 * 执行批量支付
	 * 
	 * @param bills
	 * @throws BusinessException
	 */
	private PaymentInfoVO4Batch[] doBatchZhuanzhang(SettlementAggVO[] aggvos) throws BusinessException {
		OnlinePaymentDelegator delegator = new OnlinePaymentDelegator();
		NetpayTransferVO[] netPayTransferVOs = delegator.doBatchBulu(aggvos, getEdit());
		if(CmpUtils.isListNull(netPayTransferVOs)){ 
			return null;
		}
		List<OnlinePaymentVO> lst = CmpUtils.makeList();
		for (NetpayTransferVO netpayTransferVO : netPayTransferVOs) {
			lst.addAll(CmpUtils.covertArraysToList(netpayTransferVO.getOnlinePaymentVOs()));			
		}
		
		// 传递签名信息
		ObmCASignature obmca = new ObmCASignature();
		// 只要支付前签名处理就行，验签交给网银处理
		 obmca.signPayInfo(lst.toArray(new OnlinePaymentVO[]{}), new ObmCAInfoAccessor(), DataUtil.getCurrentUser());
		
		return delegator.doBatchNetTransfer(netPayTransferVOs);
	}

}