package nc.ui.cmp.settlement.actions;

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

import javax.swing.Action;

import nc.bs.framework.common.NCLocator;
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.cmp.netpayment.PaymentProc;
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.SettleEnumCollection.Direction;
import nc.vo.cmp.settlement.international.util.SettleInternationalValidate;
import nc.vo.cmp.settlement.SettlementAggVO;
import nc.vo.cmp.settlement.SettlementBodyVO;
import nc.vo.cmp.settlement.SettlementHeadVO;
import nc.vo.cmp.validate.CMPValidate;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.data.ValueUtils;
import nc.vo.pubapp.pattern.pub.MathTool;
import nc.vo.tmpub.util.TMCurrencyUtil;

/**
 * 网上转账
 * 
 * @author wuzhwa
 * @since v6.0
 * 
 */
public class SettleNetPayTransferAction extends SettleDefaultAction {

	private static final long serialVersionUID = -4257102182028309094L;

	public SettleNetPayTransferAction() {

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

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * nc.ui.cmp.settlement.actions.SettleDefaultAction#doAction(java.awt.event
	 * .ActionEvent)
	 *
	 * @see V57 void
	 * nc.ui.cmp.settlement.SettlementCardEventHandler.onBoNetTransfer()
	 */
	@Override
	public void doAction(ActionEvent e) throws Exception {

		/**
		 * 已经结算成功的单据 不能进行网上转账 网上支付的单据结算方式不能为空，且应为勾选网银属性的档案 否则支付时给出提示
		 * 单据状态应为已生效，才能进行网上转账 单据必须录入收付款银行账户，且账户应开通网银支付 否则支付时给出提示
		 * 符合条件的单据，点网上转账之后，弹出补录网银信息对话框，如已录入网银信息，可在此进行修改
		 * 补录网银信息之后确定，单据将被传到资金的网上银行，同时单据状态变为付款中 支付确认单确认为成功 结算状态结算成功
		 * 测试多条单据的支付，部分确认为成功，部分确认为失败 每个单据的结算状态正确回写
		 */

		SettlementAggVO aggvo = (SettlementAggVO) getEdit().getValue();
		if (aggvo == null) {
			return;
		}
		//表头原币金额
		UFDouble headPrimal = (UFDouble) aggvo.getParentVO().getAttributeValue("primal");
		//表体原币金额
		UFDouble bodyPrimal = new UFDouble(0.00);
		SettlementBodyVO [] settlementBodyVOs = (SettlementBodyVO[]) aggvo.getChildrenVO();
		for (SettlementBodyVO settlementBodyVO : settlementBodyVOs) {
			bodyPrimal = bodyPrimal.add(settlementBodyVO.getPay_last());
		}
		if(headPrimal.compareTo(bodyPrimal) != 0) {
			String billcode = (String) aggvo.getParentVO().getAttributeValue("billcode");
			throw new BusinessException("业务单据编号:"+billcode+"，表体合计金额不等于表头金额!");
		}
		List<SettlementAggVO> aggLst = SettleUtils.filterSettleInfo4NetSettleFlagUnSettle(aggvo);
		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;
		}
		aggvo = aggLst.get(0);
		validate(aggvo);
		SettlementHeadVO head = (SettlementHeadVO) aggvo.getParentVO();
		// 工资发放单据,走特殊网银支付接口
		String pk_tradetype = head.getPk_tradetype();
		// 换用新的签名处理，在paymentproc里面
		
		if ("DS".equals(pk_tradetype)) {
			// 强制CA
			this.getEdit().getClientSigner().identifyCA();
		}else{
			this.getEdit().getClientSigner().checkIfCASign();
		}
		// CAAuthor.INSTANCE.author4Net();
		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;
		}

		// SettlementHeadVO head=(SettlementHeadVO)aggvo.getParentVO();
		// 转账操作
		try {

			// 工资发放单据,走特殊网银支付接口
			
			if ("DS".equals(pk_tradetype)) {
				doSalaryBillNetPay(aggvo);

			} else {
				Integer rtn = new PaymentProc().doZhuanzhang(getEdit(), aggvo);
				if (rtn == -1) {
					return;
				}
			}
			

			// 提示网上支付成功信息
			showNetPayTransferInfo(this.getModel(), new SettlementAggVO[] { aggvo });

		} catch (BusinessException ex) {
			throw new BusinessException(ex);
		}finally{
			aggvo = NCLocator.getInstance().lookup(
					ISettlementQueryService.class).querySettlementAggVOsByPks(
					new String[] { aggvo.getParentVO().getPrimaryKey() })[0];

			this.getEdit().setValue(aggvo);
			this.getEdit().setLoadBean(aggvo);
			getModel().directlyUpdate(aggvo);
		}
		/**
		 * ====================================================================
		 * =====
		 */

	}

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

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

	/**
	 * 校验
	 * 
	 * @throws BusinessException
	 */
	private void validate(SettlementAggVO aggvo) throws BusinessException {

		// 校验rmb业务
		// SettleValidate.validateCurrency(aggvo);
		// 校验支付业务数据
		SettleValidate.validatePayData(aggvo);
		// 是否启用
		SettleValidate.validateOBM(new SettlementAggVO[] { aggvo });
		// 校验单据状态
		SettleValidate.validateNetPayState(aggvo);
		// 网上支付的单据单据行校验
		SettleValidate.validateNetPayNegativeRow(aggvo);

		SettleValidate.validateCombin(new SettlementAggVO[] { aggvo }, true);

		// 校验供应商是否已经付款冻结
		SettleValidate.validateSupplier(aggvo);

		SettleValidate.dataIntegralityValidate(aggvo);
		SettleInternationalValidate.checkInternationalNotSupportedOperate(aggvo);

		CMPValidate.validate(aggvo);

	}

	// 提示网上支付成功信息
	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());
		}
	}

	@Override
	protected boolean isActionEnable() {

		// return super.isActionEnable();
		SettlementAggVO[] aggvos = getSelectedAggVOs();
		if (CmpUtils.isListNull(aggvos)) {
			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.getSettlestatus() != null
			// &&
			// (head.getSettlestatus().equals(SettleStatus.PAYING.getStatus())
			// ||
			// head.getSettlestatus().equals(SettleStatus.CHANGEING.getStatus())
			// ||
			// head.getSettlestatus().equals(SettleStatus.RECEIVING.getStatus())
			// ||
			// head.getSettlestatus().equals(SettleStatus.SUCCESSPART.getStatus())
			// || head
			// .getSettlestatus().equals(SettleStatus.SUCCESSSETTLE.getStatus())))
			// {
			// /**
			// * 支付中，划账中、已经结算的不能支付
			// */
			// 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;
	}
}