package org.dromara.settlement.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;

import com.alibaba.nacos.shaded.com.google.gson.JsonArray;
import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.resource.api.RemoteFileService;
import org.dromara.resource.api.domain.RemoteFile;
import org.dromara.settlement.api.RemoteConfigService;
import org.dromara.settlement.api.domain.*;
import org.dromara.settlement.common.bank.zhaoshang.ZhaoShangConfig;
import org.dromara.settlement.common.bank.zhaoshang.ZhaoShangResponse;
import org.dromara.settlement.common.bank.zhaoshang.ZhaoShangUtil;
import org.dromara.settlement.common.file.FileUtils;
import org.dromara.settlement.domain.SysLog;
import org.dromara.settlement.mapper.SysLogMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class ZhaoShangServiceImpl
{
	private static final Logger log = LoggerFactory.getLogger(ZhaoShangServiceImpl.class);

	@Autowired
	private RemoteConfigService wConfigService;// 配置

	@Autowired
	private SysLogMapper sysLogDao;//日志


	@DubboReference
	private RemoteFileService remoteFileService;

	private ZhaoShangResponse request(long unitId, String funcode, JsonObject body, boolean record) {
		return request(unitId, funcode, body, record, null);
	}

	private ZhaoShangResponse request(long unitId,String funcode,JsonObject body,boolean record,Long tranId) {
		ZhaoShangResponse response = null;
		ZhaoShangConfig config = getZhaoShangConfig(unitId);
		String reqid = DateUtils.parseDateToString("yyyyMMddHHmmssSSS", new Date());
		SysLog sysLog = new SysLog();
		if(record) {
			sysLog.setTranId(tranId);
		}
		sysLogDao.insert(sysLog);
		reqid = reqid + sysLog.getId();
		if(record) {
			sysLog.setReqid(reqid);
			sysLog.setRequestTime(new Date());
		}
		Result<String> requsetRtn = ZhaoShangUtil.getInstance().request(config,funcode, reqid, body);
		if(record && requsetRtn != null) {
			sysLog.setRequest(requsetRtn.getResult());
		}
		if (requsetRtn != null) {
			Result<ZhaoShangResponse> responseRtn = ZhaoShangUtil.getInstance().response(config,requsetRtn.getRtnData());
			if(record) {
				sysLog.setResponseTime(new Date());
			}
			if (responseRtn.hasError()) {
				log.error(responseRtn.getResult());
			}
			response = responseRtn.getRtnData();
			if(record && responseRtn != null) {
				sysLog.setResponse(responseRtn.getResult());
			}
		}
		if (sysLog.getId() != null) {
			if(record) {
				if (tranId != null) {
					sysLogDao.deleteByTranId(tranId, sysLog.getId());
				}
				sysLogDao.updateByPrimaryKeySelective(sysLog);
			}else
				sysLogDao.deleteByPrimaryKey(sysLog.getId());
		}
		return response;
	}

	private ZhaoShangConfig getZhaoShangConfig(long unitId) {
		ZhaoShangConfig config = new ZhaoShangConfig();
		if (wConfigService != null && unitId > 0) {
			config.ACCNBR = wConfigService.getItem(unitId, "zhaoshang_accnbr");
			config.AESKEY = wConfigService.getItem(unitId, "zhaoshang_aeskey");
			config.prikeyStr = wConfigService.getItem(unitId, "zhaoshang_prikey");
			config.pubkeyStr = wConfigService.getItem(unitId, "zhaoshang_pubkey");
			config.UID = wConfigService.getItem(unitId, "zhaoshang_uid");
			config.URL = wConfigService.getItem(unitId, "zhaoshang_api");
			config.BBKNBR = wConfigService.getItem(unitId, "zhaoshang_bbknbr");
            config.KHH =  wConfigService.getItem(unitId, "zhaoshang_khh");
            config.LHH = wConfigService.getItem(unitId, "zhaoshang_llh");
			if (StringUtils.isBlank(config.BBKNBR)) {
				String key = "config:"+unitId;
                RedisUtils.deleteObject(key);
			}
			log.info("读取结算中心的账户配置（"+unitId+"）："+config.ACCNBR+","+config.UID+","+config.AESKEY);
		}
		return config;
	}

	/**
	 * 创建招商银行记账子单位（虚拟账户）
	 * @author 张涛
	 * @date 2021年8月24日
	 * @param unitId 结算单位id
	 * @param code 记账子单元编号
	 * @param name 记账子单元名称
	 * @param prefix 记账子单元编号前缀
	 */
	public Account createAccount(long unitId,String code,String name,String prefix) {
		JsonObject body = new JsonObject();
		JsonObject ntdmaaddx = new JsonObject();
        ZhaoShangConfig config = getZhaoShangConfig(unitId);
        ntdmaaddx.addProperty("accnbr", config.ACCNBR);
        int total = 10;
        if(StringUtils.isNotEmpty(prefix)) {
        	total -= prefix.length();
        }
        if (code.length() < 10) {
			for (int i = code.length(); i < total; i++) {
				code = "0"+code;
			}
			if(StringUtils.isNotEmpty(prefix)) {
				code = prefix + code;
			}
		}
        ntdmaaddx.addProperty("dmanbr", code);
        ntdmaaddx.addProperty("dmanam", name);
        ntdmaaddx.addProperty("ovrctl", "N");
        ntdmaaddx.addProperty("bcktyp", "Y");
        ntdmaaddx.addProperty("clstyp", "N");
        body.add("ntdmaaddx", ntdmaaddx);
        ZhaoShangResponse res = request(unitId,"NTDMAADD", body,false);
        if (res != null) {
        	//新开通主账户，发现code存在时，Resultcode不一致，所以这里也用中文判断了
        	if (res.getResultcode().equals("SUC0000") || res.getResultcode().equals("NCB6608") || (StringUtils.isNotBlank(res.getResultmsg()) && res.getResultmsg().indexOf("子单元编号已存在") != -1)) {//成功或已存在
    			Account account = new Account();
    			account.setBankType("招商银行");
    			account.setBankTypeName("招商银行");
                account.setBankNo(config.LHH);
                account.setBankName(config.KHH);
    			account.setBankCard(config.ACCNBR + code);
    			account.setBalance(0l);
    			return account;
    		}
		}
        return null;
	}



    public AccountSyn synAccountNew(AccountSyn acc)  {
		try{
			Thread.sleep(1000*10);
		}catch (Exception e){

		}
        JsonObject body = new JsonObject();
        String curDate = DateUtils.getDate();
        String synDate = null;//最近同步日期
        if (acc.getSynTime() != null) {
            synDate = DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, acc.getSynTime());
            if (StringUtils.isBlank(acc.getSynPosition()) && DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate).getTime() < DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, curDate).getTime()) {
                //如果交易日同步完成，则开始同步下一天的
                synDate = DateUtils.getEndDateByDays(synDate,1);
            }
        }else {
            synDate = curDate;
        }
        ZhaoShangConfig config = getZhaoShangConfig(acc.getUnitId());

        JsonObject ntdmtqrdy1 = new JsonObject();
        ntdmtqrdy1.addProperty("bbknbr", config.BBKNBR);
        ntdmtqrdy1.addProperty("inbacc", config.ACCNBR);
        ntdmtqrdy1.addProperty("dyanbr", acc.getBankCard().replace(config.ACCNBR,""));
        String funcode = "NTDMTQRD";
        if (StringUtils.isNotBlank(acc.getSynPosition())) {
            ntdmtqrdy1.addProperty("ctnkey", acc.getSynPosition());
        }

        if(!curDate.equals(synDate)){
            ntdmtqrdy1.addProperty("begdat",synDate.replaceAll("-",""));
            ntdmtqrdy1.addProperty("enddat",synDate.replaceAll("-",""));
            funcode ="NTDMTQRY";
            body.add("ntdmtqryy1",ntdmtqrdy1);
        }else{
            body.add("ntdmtqrdy1",ntdmtqrdy1);
        }

        ZhaoShangResponse res = request(acc.getUnitId(),funcode, body,false);
        String todaySynPosition = "";
        if (res != null) {
            JsonArray rtnBody = null;
            if(res.getData().has("ntdmtqryz1")) {
                rtnBody = res.getData().getAsJsonArray("ntdmtqryz1");
            }
            if(res.getData().has("ntdmtqryy1")) {
                JsonArray ntdmtlsty = res.getData().getAsJsonArray("ntdmtqryy1");
                JsonObject ntdmtlstyItem = ntdmtlsty.get(0).getAsJsonObject();
                todaySynPosition = ntdmtlstyItem.get("ctnkey").getAsString();
                if(StringUtils.isEmpty(todaySynPosition)) {//已查完交易日的所有交易
                    acc.setSynPosition("");
                }else {
                    acc.setSynPosition(todaySynPosition);
                }
            }else {
                acc.setSynPosition("");
            }
            if (rtnBody != null && rtnBody.size() > 0) {
                if (acc.getLogs() == null) {
                    acc.setLogs(new ArrayList<AccountLog>());
                }
                Date curTime = new Date();
                for (int i = 0, len = rtnBody.size(); i < len; i++) {
                    JsonObject item = rtnBody.get(i).getAsJsonObject();
                    String frmcod = item.has("dyanbr") ? item.get("dyanbr").getAsString() : "";
                    if ((config.ACCNBR + frmcod).equals(acc.getBankCard())) {
                        AccountLog log = new AccountLog();
                        log.setAccId(acc.getId());
                        log.setAddBy("系统");
                        log.setAddTime(curTime);
                        log.setBankCard(acc.getBankCard());
                        log.setBankType(acc.getBankType());
                        //log.setCcynbr(item.getString("ccynbr"));
                        //R：冲账,冲正标志
                        log.setMthflg(item.has("rvstag") ? item.get("rvstag").getAsString() : null);
                        //交易识别编码，
                        log.setNarinn(item.has("narinn") ? item.get("narinn").getAsString() : null);
                        log.setRpyacc(item.has("rpyacc") ? item.get("rpyacc").getAsString() : null);
                        log.setRpynam(item.has("rpynam") ? item.get("rpynam").getAsString() : null);
                        //交易时间
                        String trxtim = item.get("trxtim").getAsString();
                        //交易日期
                        String trxdat = item.has("trxdat") ? item.get("trxdat").getAsString() : "";

                        if(StringUtils.isNotBlank(trxdat)) {
                            trxtim = trxdat.substring(0,4)+"-"+trxdat.substring(4,6)+"-"+trxdat.substring(6,8) + " " + trxtim.substring(0,2)+":"+trxtim.substring(2,4)+":"+trxtim.substring(4,6);
                        }else {
                            trxtim = curDate + " " + trxtim.substring(0,2)+":"+trxtim.substring(2,4)+":"+trxtim.substring(4,6);
                        }
                        log.setTranTime(DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD_HH_MM_SS, trxtim));
                        //交易金额
                        log.setTrxamt(new BigDecimal(item.get("trxamt").getAsString()).multiply(new BigDecimal(100)).longValue());
                        //交易方向 D：借方（支出）   C：贷方（收入）
                        String trxdir = item.get("trxdir").getAsString();
                        if(trxdir.equals("D")) {
                            log.setTrxdir((short)2);
                        }else if (trxdir.equals("C")) {
                            log.setTrxdir((short)1);
                            //退款交易：关联原交易
                            if(item.get("rlttrx") != null ){
                                log.setRefundTrxnbr(item.get("rlttrx").getAsString());
                                log.setRefundDate(trxdat);
                            }
                        }
                        log.setBalance(acc.getBalance());
                        //记账流水号
                        log.setTrxnbr(item.get("trxnbr").getAsString());
                        //交易摘要
                        if(item.has("trxtxt")) {
                            log.setTrxtxt(item.get("trxtxt").getAsString());
                        }
                        log.setUnitId(acc.getUnitId());
                        acc.getLogs().add(log);
                        if (StringUtils.isNotBlank(acc.getTrxnbrs())) {
                            acc.setTrxnbrs(acc.getTrxnbrs()+",");
                        }
                        acc.setTrxnbrs(acc.getTrxnbrs()+"'"+log.getTrxnbr()+"'");
                    }
                }
            }
            //不是今天，或者当前没有同步完
            if (DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate).getTime() < DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, curDate).getTime() || StringUtils.isNotBlank(acc.getSynPosition())) {
                acc.setSynTime(DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate));
                acc = synAccountNew(acc);
            }else if(StringUtils.isNotBlank(todaySynPosition)){//今天时间还没有过完，需要根据同步位置继续同步
                acc.setSynPosition(todaySynPosition);
            }
            acc.setSynTime(new Date());
        }
        return acc;
    }

	/**
	 * 同步招商银行账户
	 * @author 张涛
	 * @date 2021年9月6日
	 * @param bankCard 银行卡号
	 * @return
	 */

    @Deprecated
	public AccountSyn synAccount(AccountSyn acc) {
		JsonObject body = new JsonObject();
		String curDate = DateUtils.getDate();
		String synDate = null;//最近同步日期
		if (acc.getSynTime() != null) {
			synDate = DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, acc.getSynTime());
			if (StringUtils.isBlank(acc.getSynPosition()) && DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate).getTime() < DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, curDate).getTime()) {
				//如果交易日同步完成，则开始同步下一天的
				synDate = DateUtils.getEndDateByDays(synDate,1);
			}
		}else {
			synDate = curDate;
		}
		ZhaoShangConfig config = getZhaoShangConfig(acc.getUnitId());
		body.addProperty("bbknbr", config.BBKNBR);
		body.addProperty("accnbr", config.ACCNBR);
        body.addProperty("trsdat", synDate.replace("-", ""));
        if (StringUtils.isNotBlank(acc.getSynPosition())) {
        	body.addProperty("trsseq", Integer.parseInt(acc.getSynPosition())+1);
		}
        ZhaoShangResponse res = request(acc.getUnitId(),"DCTRSINF", body,false);
        String todaySynPosition = "";
        if (res != null) {
        	JsonArray rtnBody = null;
    		if(res.getData().has("ntqactrsz2")) {
    			rtnBody = res.getData().getAsJsonArray("ntqactrsz2");
    		}
    		if(res.getData().has("ntrbptrsz1")) {
    			JsonArray ntdmtlsty = res.getData().getAsJsonArray("ntrbptrsz1");
    			JsonObject ntdmtlstyItem = ntdmtlsty.get(0).getAsJsonObject();
    			todaySynPosition = ntdmtlstyItem.get("trsseq").getAsString();
    			if(ntdmtlstyItem.get("cotflg").getAsString().equals("N")) {//已查完交易日的所有交易
    				acc.setSynPosition("");
    			}else {
    				acc.setSynPosition(todaySynPosition);
    			}
    		}else {
    			acc.setSynPosition("");
    		}
			if (rtnBody != null && rtnBody.size() > 0) {
				if (acc.getLogs() == null) {
					acc.setLogs(new ArrayList<AccountLog>());
				}
				Date curTime = new Date();
				for (int i = 0, len = rtnBody.size(); i < len; i++) {
					JsonObject item = rtnBody.get(i).getAsJsonObject();
					String frmcod = item.has("frmcod") ? item.get("frmcod").getAsString() : "";
					if ((config.ACCNBR + frmcod).equals(acc.getBankCard())) {
						AccountLog log = new AccountLog();
						log.setAccId(acc.getId());
						log.setAddBy("系统");
						log.setAddTime(curTime);
						log.setBankCard(acc.getBankCard());
						log.setBankType(acc.getBankType());
						//log.setCcynbr(item.getString("ccynbr"));
						log.setMthflg(item.has("rsvflg") ? item.get("rsvflg").getAsString() : null);
						log.setNarinn(item.has("yurref") ? item.get("yurref").getAsString() : null);
						log.setRpyacc(item.has("rpyacc") ? item.get("rpyacc").getAsString() : null);
						log.setRpynam(item.has("rpynam") ? item.get("rpynam").getAsString() : null);
						String trxtim = item.get("etytim").getAsString();
						String trxdat = item.has("etydat") ? item.get("etydat").getAsString() : "";
						if(StringUtils.isNotBlank(trxdat)) {
							trxtim = trxdat.substring(0,4)+"-"+trxdat.substring(4,6)+"-"+trxdat.substring(6,8) + " " + trxtim.substring(0,2)+":"+trxtim.substring(2,4)+":"+trxtim.substring(4,6);
						}else {
							trxtim = curDate + " " + trxtim.substring(0,2)+":"+trxtim.substring(2,4)+":"+trxtim.substring(4,6);
						}
						log.setTranTime(DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD_HH_MM_SS, trxtim));
						log.setTrxamt(new BigDecimal(item.get("trsamt").getAsString()).multiply(new BigDecimal(100)).longValue());
						String trxdir = item.get("amtcdr").getAsString();
						if(trxdir.equals("D")) {
							log.setTrxdir((short)2);
						}else if (trxdir.equals("C")) {
							log.setTrxdir((short)1);
						}
						log.setBalance(acc.getBalance());
						log.setTrxnbr(item.get("refnbr").getAsString());
						if(item.has("naryur")) {
							log.setTrxtxt(item.get("naryur").getAsString());
						}
						log.setUnitId(acc.getUnitId());
						acc.getLogs().add(log);
						if (StringUtils.isNotBlank(acc.getTrxnbrs())) {
							acc.setTrxnbrs(acc.getTrxnbrs()+",");
						}
						acc.setTrxnbrs(acc.getTrxnbrs()+"'"+log.getTrxnbr()+"'");
					}
				}
			}
			//不是今天，或者当前没有同步完
	        if (DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate).getTime() < DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, curDate).getTime() || StringUtils.isNotBlank(acc.getSynPosition())) {
	        	acc.setSynTime(DateUtils.parseStringToDate(DateUtils.YYYY_MM_DD, synDate));
	        	acc = synAccount(acc);
			}else if(!"0".equals(todaySynPosition)){//今天时间还没有过完，需要根据同步位置继续同步
				acc.setSynPosition(todaySynPosition);
			}
	        acc.setSynTime(new Date());
        }
		return acc;
	}


	/**
	 * 查询记账子单元信息(只用于提供测试报告)
	 */
	public void synAccountOld(long unitId,String accnbr,String dmanbr) {
		JsonObject body = new JsonObject();
		JsonArray ntdmalstx = new JsonArray();
		JsonObject ntdmalstx1 = new JsonObject();
		ntdmalstx1.addProperty("accnbr", accnbr);
		ntdmalstx1.addProperty("dmanbr", dmanbr);
		ntdmalstx.add(ntdmalstx1);
		body.add("ntdmalstx", ntdmalstx);
	    request(unitId,"NTDMALST", body,false);
	}

	/**
	 * 关闭记账子单元(只用于提供测试报告)
	 */
	public void delAccount(long unitId,String accnbr,String dmanbr) {
		JsonObject body = new JsonObject();
		JsonObject ntdmaaddx = new JsonObject();
        ntdmaaddx.addProperty("accnbr", accnbr);
        ntdmaaddx.addProperty("dmanbr", dmanbr);
        ntdmaaddx.addProperty("dmanam", "测试");
        ntdmaaddx.addProperty("ovrctl", "N");
        ntdmaaddx.addProperty("bcktyp", "Y");
        ntdmaaddx.addProperty("clstyp", "N");
        body.add("ntdmaaddx", ntdmaaddx);
        request(unitId,"NTDMAADD", body,false);
		body = new JsonObject();
		JsonArray ntdmadltx1 = new JsonArray();
		JsonArray ntdmadltx2 = new JsonArray();
		JsonObject ntdmadltx11 = new JsonObject();
		ntdmadltx11.addProperty("accnbr", accnbr);
		JsonObject ntdmadltx21 = new JsonObject();
		ntdmadltx21.addProperty("dmanbr", dmanbr);
		ntdmadltx1.add(ntdmadltx11);
		ntdmadltx2.add(ntdmadltx21);
		body.add("ntdmadltx1", ntdmadltx1);
		body.add("ntdmadltx2", ntdmadltx2);
	    request(unitId,"NTDMADLT", body,false);
	}

	/**
	 * 内部转账
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog innerTransfer(TransactionLog log) {
		JsonObject body = new JsonObject();
        ZhaoShangConfig config = getZhaoShangConfig(log.getUnitId());
        JsonObject ntdmatrxx1 = new JsonObject();
        ntdmatrxx1.addProperty("accnbr", config.ACCNBR);
        ntdmatrxx1.addProperty("dmadbt", log.getSourceCard().substring(config.ACCNBR.length()));
        ntdmatrxx1.addProperty("dmacrt", log.getTargetCard().substring(config.ACCNBR.length()));
        ntdmatrxx1.addProperty("trxamt", String.format("%.2f", log.getAmount()/100.0));
        ntdmatrxx1.addProperty("trxtxt", log.getRemark());
        body.add("ntdmatrxx1", ntdmatrxx1);



        ZhaoShangResponse res = request(log.getUnitId(),"NTDMATRX", body,true,log.getId());
        if (res == null || !res.getResultcode().equals("SUC0000") || !res.getData().has("ntdmatrxz1")) {
        	ZhaoShangServiceImpl.log.error(res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "内部转账失败");
        	log.setResult((short)-1);
    		return log;
        }
        JsonArray rtnBody = res.getData().getAsJsonArray("ntdmatrxz1");
        for (int i = 0,len = rtnBody.size(); i < len; i++) {
        	JsonObject item = rtnBody.get(i).getAsJsonObject();
			if (item.get("trxdir").getAsString().equals("D")) {//D:付款方
				log.setSourceBankNo(item.get("trxnbr").getAsString());
			}else if (item.get("trxdir").getAsString().equals("C")) {//C:收款方
				log.setTargetBankNo(item.get("trxnbr").getAsString());
			}
		}

		JsonArray ntoprrtnz = res.getData().getAsJsonArray("ntoprrtnz");

		if(ntoprrtnz != null && ntoprrtnz.size() > 0){
			if(!"S".equals(ntoprrtnz.get(0).getAsJsonObject().get("rtnflg").getAsString())){
				throw new ServiceException("内部转账交易失败");
			}
		}


		if (StringUtils.isBlank(log.getSourceBankNo()) || StringUtils.isBlank(log.getTargetBankNo())) {
        	throw new ServiceException("内部转账交易失败");
		}
        log.setResult((short)2);
		return log;
	}

	/***
	 * 业务模式
	 * @param log
	 */
	public void dcLismod(TransactionLog log){
		JsonObject body = new JsonObject();
		body.addProperty("buscod","N03020");
		ZhaoShangResponse res = request(log.getUnitId(),"DCLISMOD", body,true,log.getId());
	}

	/**
	 * 对私跨行转账
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog crossPersionTransfer(TransactionLog log) {
//		test(log);
		JsonObject body = new JsonObject();
        ZhaoShangConfig config = getZhaoShangConfig(log.getUnitId());
        JsonObject ntbusmody = new JsonObject();
        ntbusmody.addProperty("busmod", wConfigService.getItem(log.getUnitId(), "zhaoshang_busmod"));
        JsonObject ntagcsaix1 = new JsonObject();
        ntagcsaix1.addProperty("yurref", log.getOrderNo());
        ntagcsaix1.addProperty("bbknbr", wConfigService.getItem(log.getUnitId(), "zhaoshang_bbknbr"));
        ntagcsaix1.addProperty("payacc", config.ACCNBR);
        ntagcsaix1.addProperty("bustya", "BYBK");
        ntagcsaix1.addProperty("trxrmk", log.getRemark());
        ntagcsaix1.addProperty("begtag", "Y");
        ntagcsaix1.addProperty("endtag", "Y");
        String amount = String.format("%.2f", log.getAmount()/100.0);
        ntagcsaix1.addProperty("ttlamt", amount);
        ntagcsaix1.addProperty("ttlcnt", "1");
        ntagcsaix1.addProperty("curamt", amount);
        ntagcsaix1.addProperty("curcnt", "1");
        ntagcsaix1.addProperty("ttlnum", "1");
        ntagcsaix1.addProperty("jzbnbr", log.getSourceCard().substring(config.ACCNBR.length()));
        JsonArray ntagcsaix2 = new JsonArray();
        JsonObject ntagcsaixItem = new JsonObject();
        ntagcsaixItem.addProperty("trxseq", "00000001");
        ntagcsaixItem.addProperty("eacnbr", log.getTargetCard());
        ntagcsaixItem.addProperty("eacnam", log.getTargetAccName());
        ntagcsaixItem.addProperty("rcvamt", amount);
        ntagcsaix2.add(ntagcsaixItem);
        body.add("ntbusmody", ntbusmody);
        body.add("ntagcsaix1", ntagcsaix1);
        body.add("ntagcsaix2", ntagcsaix2);
        ZhaoShangResponse res = request(log.getUnitId(),"NTAGCAPI", body,true,log.getId());
        if (res == null || !res.getResultcode().equals("SUC0000") || !res.getData().has("ntagcagcz1")) {
        	throw new ServiceException(res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "对私跨行转账失败");
        }
        JsonArray rtnBody = res.getData().getAsJsonArray("ntagcagcz1");
		log.setSourceBankNo(rtnBody.get(0).getAsJsonObject().get("reqnbr").getAsString());
		log.setTargetBankNo(log.getSourceBankNo());
        if (StringUtils.isBlank(log.getSourceBankNo()) || StringUtils.isBlank(log.getTargetBankNo())) {
        	throw new ServiceException("对私跨行转账申请失败");
		}
        log.setResult((short)1);
		return log;
	}


    /***
     * 业务模式
     * @param log
     */
    public void dcLismod1(TransactionLog log){
        JsonObject body = new JsonObject();
        body.addProperty("buscod","N02030");
        ZhaoShangResponse res = request(log.getUnitId(),"DCLISMOD", body,true,log.getId());
    }
	/**
	 * 对公跨行转账
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog crossEnterpriseTransfer(TransactionLog log) {
//        dcLismod1(log);
		JsonObject body = new JsonObject();
        ZhaoShangConfig config = getZhaoShangConfig(log.getUnitId());
        JsonArray bb1paybmx1 = new JsonArray();
        JsonObject bb1paybmx1Item = new JsonObject();
        bb1paybmx1Item.addProperty("busCod", "N02030");
        bb1paybmx1Item.addProperty("busMod", wConfigService.getItem(log.getUnitId(), "zhaoshang_busmod_enterprise"));
        bb1paybmx1.add(bb1paybmx1Item);
        JsonArray bb1payopx1 = new JsonArray();
        JsonObject bb1payopx1Item = new JsonObject();
        bb1payopx1Item.addProperty("ccyNbr", "10");
        bb1payopx1Item.addProperty("crtAcc", log.getTargetCard());
        bb1payopx1Item.addProperty("crtNam", log.getTargetAccName());
        bb1payopx1Item.addProperty("crtBnk", log.getBankType());
        bb1payopx1Item.addProperty("crtAdr", log.getTargetAccBankAddr());
        bb1payopx1Item.addProperty("dmaNbr", log.getSourceCard().substring(config.ACCNBR.length()));
        bb1payopx1Item.addProperty("dbtAcc", config.ACCNBR);
        bb1payopx1Item.addProperty("nusAge", log.getRemark());
        //测试
//        bb1payopx1Item.addProperty("brdNbr","102100099996");
//        bb1payopx1Item.addProperty("crtAdr","北京市");
        bb1payopx1Item.addProperty("bnkFlg", log.getBankType().contains("招商银行") ? "Y" : "N");
        String amount = String.format("%.2f", log.getAmount()/100.0);
        bb1payopx1Item.addProperty("trsAmt", amount);
        bb1payopx1Item.addProperty("yurRef", log.getOrderNo());
        bb1payopx1Item.addProperty("busNar", log.getRemark());
        bb1payopx1.add(bb1payopx1Item);
        body.add("bb1paybmx1", bb1paybmx1);
        body.add("bb1payopx1", bb1payopx1);
        ZhaoShangResponse res = request(log.getUnitId(),"BB1PAYOP", body,true,log.getId());
        if (res == null || !res.getResultcode().equals("SUC0000") || !res.getData().has("bb1payopz1")) {
        	throw new ServiceException(res != null && StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "对公跨行转账失败");
        }
        JsonArray rtnBody = res.getData().getAsJsonArray("bb1payopz1");
		log.setSourceBankNo(rtnBody.get(0).getAsJsonObject().get("reqNbr").getAsString());
		log.setTargetBankNo(log.getSourceBankNo());
        if (StringUtils.isBlank(log.getSourceBankNo()) || StringUtils.isBlank(log.getTargetBankNo())) {
        	throw new ServiceException("对公跨行转账申请失败");
		}
        log.setResult((short)1);
		return log;
	}

	/**
	 * 同步对私银行账户交易结果
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog synPersionTransfer(TransactionLog log) {
		JsonObject body = new JsonObject();
		JsonObject ntagcinyx1 = new JsonObject();
        ntagcinyx1.addProperty("buscod", "N03020");
        ntagcinyx1.addProperty("yurref", log.getOrderNo());
        String endDate = DateUtils.getDate();
        String beginDate = DateUtils.getEndDateByDays(endDate, -3);
        ntagcinyx1.addProperty("bgndat", beginDate.replace("-", ""));
        ntagcinyx1.addProperty("enddat", endDate.replace("-", ""));
        body.add("ntagcinyx1", ntagcinyx1);
        ZhaoShangResponse res = request(log.getUnitId(),"NTAGCINY", body,false,log.getId());
        if(res != null) {
	        if (!res.getResultcode().equals("SUC0000") || !res.getData().has("ntagcinqz")) {
	        	throw new ServiceException(StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "同步对私银行账户交易结果失败");
	        }
	        JsonArray rtnBody = res.getData().getAsJsonArray("ntagcinqz");
	        JsonObject item = rtnBody.get(0).getAsJsonObject();
	        if (item.get("reqsta").getAsString().equals("FIN")) {
	        	String rtnFlg = item.get("rtnflg").getAsString();
	        	if(rtnFlg.equals("S")) {
	        		body = new JsonObject();
	        		JsonObject ntagdinfy1 = new JsonObject();
	        		ntagdinfy1.addProperty("reqnbr", item.get("reqnbr").getAsString());
	        		body.add("ntagdinfy1", ntagdinfy1);
	        		ZhaoShangResponse ores = request(log.getUnitId(),"NTAGDINF", body,false,log.getId());
	        		if(ores != null) {
	        	        if (!ores.getResultcode().equals("SUC0000") || !ores.getData().has("ntagcdtly1")) {
	        	        	throw new ServiceException(StringUtils.isNotBlank(ores.getResultmsg()) ? ores.getResultmsg() : "同步对私银行账户交易结果2失败");
	        	        }
	        	        JsonArray ortnBody = ores.getData().getAsJsonArray("ntagcdtly1");
	        	        JsonObject oitem = ortnBody.get(0).getAsJsonObject();
	        	        String stscod = oitem.get("stscod").getAsString();
	        	        if (stscod.equals("S")) {
	        	        	log.setResult((short)2);
						}else if(stscod.equals("E")){
							String errdsp = oitem.has("errdsp") ? oitem.get("errdsp").getAsString() : "";
			        		if (StringUtils.isNotBlank(errdsp)) {
			        			log.setReason(errdsp);
							}else{
								log.setReason("银行支付失败[NTAGDINF]");
							}
						}
	        		}
	        	}else{
	        		String errdsp = item.has("errdsp") ? item.get("errdsp").getAsString() : "";
	        		if (StringUtils.isNotBlank(errdsp)) {
	        			log.setReason(errdsp);
					}else if (rtnFlg.equals("F")) {
						log.setReason("银行支付失败");
					}else if (rtnFlg.equals("B")) {
						log.setReason("支付被退票");
					}else if (rtnFlg.equals("R")) {
						log.setReason("审批否决");
					}else if (rtnFlg.equals("D")) {
						log.setReason("过期不审批");
					}else if (rtnFlg.equals("C")) {
						log.setReason("企业撤销");
					}else if (rtnFlg.equals("M")) {
						log.setReason("商户撤销订单");
					}else if (rtnFlg.equals("V")) {
						log.setReason("委托贷款被借款方拒绝");
					}else if (rtnFlg.equals("E")) {
						log.setReason("已提交到银行");
					}else if (rtnFlg.equals("U")) {
						log.setReason("银行挂账");
					}
	        		log.setResult((short)3);
				}
	        	log.setTranTime(new Date());
			}
        }
		return log;
	}

	/**
	 * 同步对公银行账户交易结果
	 * @author 张涛
	 * @date 2021年9月7日
	 * @param log
	 * @return
	 */
	public TransactionLog synEnterpriseTransfer(TransactionLog log) {
		JsonObject body = new JsonObject();
		JsonArray bb1payqrx1 = new JsonArray();
		JsonObject bb1payqrx1Item = new JsonObject();
		bb1payqrx1Item.addProperty("busCod", "N02030");
		bb1payqrx1Item.addProperty("yurRef", log.getOrderNo());
		bb1payqrx1.add(bb1payqrx1Item);
        body.add("bb1payqrx1", bb1payqrx1);
        ZhaoShangResponse res = request(log.getUnitId(),"BB1PAYQR", body,false,log.getId());
        if(res != null) {
	        if (!res.getResultcode().equals("SUC0000") || !res.getData().has("bb1payqrz1")) {
	        	throw new ServiceException(StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "同步对公银行账户交易结果失败");
	        }
	        JsonArray rtnBody = res.getData().getAsJsonArray("bb1payqrz1");
	        JsonObject item = rtnBody.get(0).getAsJsonObject();
	        if (item.get("reqSts").getAsString().equals("FIN")) {
	        	String rtnFlg = item.get("rtnFlg").getAsString();
	        	if(rtnFlg.equals("S")) {
	        		log.setResult((short)2);
	        	}else{
	        		String rtnNar = item.has("rtnNar") ? item.get("rtnNar").getAsString() : "";
	        		if (StringUtils.isNotBlank(rtnNar)) {
	        			log.setReason(rtnNar);
					}else if (rtnFlg.equals("F")) {
						log.setReason("银行支付失败");
					}else if (rtnFlg.equals("B")) {
						log.setReason("支付被退票");
					}else if (rtnFlg.equals("R")) {
						log.setReason("审批否决");
					}else if (rtnFlg.equals("D")) {
						log.setReason("过期不审批");
					}else if (rtnFlg.equals("C")) {
						log.setReason("企业撤销");
					}else if (rtnFlg.equals("U")) {
						log.setReason("银行挂账");
					}
	        		log.setResult((short)3);
				}
	        	log.setTranTime(new Date());
			}
        }
		return log;
	}

	/**
	 * 获取交易回置单
	 * @author 张涛
	 * @date 2021年9月16日
	 * @param log
	 * @return
	 */
	public String getTransferCallback(TransactionLog log) {
		ZhaoShangConfig config = getZhaoShangConfig(log.getUnitId());
		JsonObject body = new JsonObject();
        body.addProperty("eacnbr", config.ACCNBR);
        String endDate = DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, log.getTranTime());
        body.addProperty("quedat", endDate);
        body.addProperty("trsseq", log.getTargetBankNo());
        ZhaoShangResponse res = request(log.getUnitId(),"DCSIGREC", body,false,log.getId());
        if (res == null || !res.getResultcode().equals("SUC0000")) {
        	if(!res.getResultcode().equals("HOST001")) {
        		throw new ServiceException(StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "获取交易回置单失败");
        	}
        }
        String callBackFile = "";
        if(res.getData().has("fildat")) {
        	String fildat = res.getData().get("fildat").getAsString();

			byte[] bytes = Base64.getDecoder().decode(fildat);
			String fileName = log.getTargetBankNo()+"_cb.pdf";
			RemoteFile remoteFile = this.remoteFileService.upload(fileName,fileName,"application/pdf",bytes);
//        	String uploadNetPath = wConfigService.getUploadNetPath(log.getUnitId());
//        	String uploadPhyPath = wConfigService.getUploadPhyPath(log.getUnitId())+"/";
//
//        	FileUtils.base64ToFile(fildat, fileName, uploadPhyPath);
//        	callBackFile = uploadNetPath + fileName;
			callBackFile = remoteFile.getUrl();
        }
		return callBackFile;
	}

	/**
	 * 获取交易流水号
	 * @author 张涛
	 * @date 2021年9月22日
	 * @param log
	 * @param trsseq 断点续传编号
	 * @return
	 */
	public String getTransferBankNo(TransactionLog log,String trsseq) {
		ZhaoShangConfig config = getZhaoShangConfig(log.getUnitId());
		JsonObject body = new JsonObject();
        body.addProperty("bbknbr", wConfigService.getItem(log.getUnitId(), "zhaoshang_bbknbr"));
        String endDate = DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, log.getTranTime());
        body.addProperty("trsdat", endDate.replace("-", ""));
        body.addProperty("accnbr", config.ACCNBR);
        body.addProperty("trsseq", trsseq);
        ZhaoShangResponse res = request(log.getUnitId(),"DCTRSINF", body,false,log.getId());
        if (res == null || !res.getResultcode().equals("SUC0000")) {
        	throw new ServiceException(StringUtils.isNotBlank(res.getResultmsg()) ? res.getResultmsg() : "获取交易回置单失败");
        }
        String result = "";
        if(res.getData().has("ntrbptrsz1")) {
	        JsonArray ntrbptrsz1 = res.getData().getAsJsonArray("ntrbptrsz1");
	        JsonObject ntrbptrsz1Item = ntrbptrsz1.get(0).getAsJsonObject();
	        if(res.getData().has("ntqactrsz2")) {
		        JsonArray rtnBody = res.getData().getAsJsonArray("ntqactrsz2");
		        for (int i = 0,len = rtnBody.size(); i < len; i++) {
		        	JsonObject item = rtnBody.get(i).getAsJsonObject();
		        	if (item.get("yurref").getAsString().equals(log.getOrderNo())) {
		        		result = item.get("refnbr").getAsString();
		        		break;
					}
				}
	        }
	        if(StringUtils.isBlank(result) && ntrbptrsz1Item.get("cotflg").getAsString().equals("Y")) {
		        return getTransferBankNo(log,(Long.parseLong(ntrbptrsz1Item.get("trsseq").getAsString()) + 1)+"");
	        }
        }
		return result;
	}
}
