package com.clx.performance.service.impl.thirdparty.nbbank;

import com.alibaba.fastjson.JSONObject;
import com.clx.performance.component.IdGenerateSnowFlake;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.service.thirdparty.nbbank.NbBankService;
import com.clx.performance.service.thirdparty.nbbank.NbBankThirdpartyService;
import com.clx.performance.utils.LocalDateTimeUtils;
import com.clx.performance.vo.pc.nbbank.NbBankOrderPayResultVO;
import com.clx.performance.vo.pc.nbbank.NbBankOrderResultVO;
import com.msl.common.exception.ServiceSystemException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 易付通
 */
@Slf4j
@Service
public class NbBankServiceImpl implements NbBankService {

    @Autowired
    private NbBankThirdpartyService bankThirdpartyService;

    @Autowired
    private IdGenerateSnowFlake idGenerateSnowFlake;


    /**
     * 转账支付
     * @param amount 金额分
     */
    @Override
    public NbBankOrderPayResultVO orderTransferPay(Integer amount) {
        String merSeqNo = idGenerateSnowFlake.nextIdToString(3L);

        String merDtTm = LocalDateTimeUtils.formatTime();
        JSONObject data = bankThirdpartyService.directBankTransferOrder(merSeqNo, merDtTm, amount);

        String transSeqNo = data.getString("transSeqNo");
        String cardNo = data.getString("cardNo");
        String signNo = getSignNo(data.getString("signNo"), cardNo);

        NbBankOrderPayResultVO result = new NbBankOrderPayResultVO();
        result.setAmount(amount);
        result.setMerDtTm(merDtTm);
        result.setMerSeqNo(merSeqNo);
        result.setTransSeqNo(transSeqNo);
        result.setSignNo(signNo);

        return result;
    }

    /**
     * 订单支付
     * @param loanNo 借款单号
     * @param amount 金额分
     * @param payAcctOpenBankId 开户行号
     * @param payAcctNo 付款账号
     * @param payAcctNm 付款户名
     */
    @Override
    public NbBankOrderPayResultVO orderDirectPay(Long loanNo, Integer amount,
                                                 String payAcctOpenBankId, String payAcctNo, String payAcctNm) {
        String merSeqNo = idGenerateSnowFlake.nextIdToString(3L);

        String merDtTm = LocalDateTimeUtils.formatTime();
        JSONObject data = bankThirdpartyService.unionPayDirectOrder(merSeqNo, merDtTm, amount,
                payAcctOpenBankId,payAcctNo, payAcctNm);

        String transSeqNo = data.getString("transSeqNo");
        if (StringUtils.isBlank(transSeqNo)) {
            log.info("宁波银行订单支付失败,借款单号{},返回结果:{}", loanNo, data);
            throw new ServiceSystemException(PerformanceResultEnum.NB_BANK_ORDER_PAY_ERROR);
        }
        NbBankOrderPayResultVO result = new NbBankOrderPayResultVO();
        result.setAmount(amount);
        result.setMerDtTm(merDtTm);
        result.setMerSeqNo(merSeqNo);
        result.setTransSeqNo(transSeqNo);

        return result;
    }

    /**
     * 获取交易结果
     * @param orgMerSeqNo 商户流水号 （原）
     */
    @Override
    public NbBankOrderResultVO getResult(String orgMerSeqNo) {
        JSONObject data = bankThirdpartyService.queryOrder(orgMerSeqNo);

        NbBankOrderResultVO result = new NbBankOrderResultVO();

        String transStatus = data.getString("transStatus");
        if (StringUtils.equals(transStatus, "00")){result.setTransStatus(1);}            //交易成功
        else if (StringUtils.equals(transStatus, "01")){result.setTransStatus(2);}       //交易失败
        else if (StringUtils.equals(transStatus, "02")){result.setTransStatus(3);}       //交易已受理
        else if (StringUtils.equals(transStatus, "80")){result.setTransStatus(4);}       //订单初始状态
        else if (StringUtils.equals(transStatus, "90")){result.setTransStatus(5);}       //交易不存在
        else if (StringUtils.equals(transStatus, "99")){result.setTransStatus(6);}       //交易超时,须发起交易结果查询

        BigDecimal trxAmt = data.getBigDecimal("trxAmt");
        BigDecimal realTrxAmt = data.getBigDecimal("realTrxAmt");
        String transSeqNo = data.getString("transSeqNo");
        String signNo = data.getString("signNo");

        result.setAmount(trxAmt==null? null : trxAmt.movePointLeft(2).intValue());
        result.setRealAmount(trxAmt==null? null : realTrxAmt.movePointLeft(2).intValue());
        result.setMerSeqNo(orgMerSeqNo);
        result.setTransSeqNo(transSeqNo);
        result.setSignNo(signNo);

        return result;
    }

    /**
     * 调账
     * @param amount 金额分
     */
    @Override
    public NbBankOrderResultVO adjust(Integer amount) {
        String merSeqNo = idGenerateSnowFlake.nextIdToString(3L);

        String merDtTm = LocalDateTimeUtils.formatTime();
        JSONObject data = bankThirdpartyService.fundTransferOrder(merSeqNo, merDtTm, amount,
                null, null);

        NbBankOrderResultVO result = new NbBankOrderResultVO();

        String transStatus = data.getString("transStatus");
        if (StringUtils.equals(transStatus, "00")){result.setTransStatus(1);}            //交易成功
        else if (StringUtils.equals(transStatus, "01")){result.setTransStatus(2);}       //交易失败
        else if (StringUtils.equals(transStatus, "02")){result.setTransStatus(3);}       //交易已受理
        else if (StringUtils.equals(transStatus, "80")){result.setTransStatus(4);}       //订单初始状态
        else if (StringUtils.equals(transStatus, "90")){result.setTransStatus(5);}       //交易不存在
        else if (StringUtils.equals(transStatus, "99")){result.setTransStatus(6);}       //交易超时,须发起交易结果查询

        String transSeqNo = data.getString("transSeqNo");

        result.setAmount(amount);
        result.setRealAmount(amount);
        result.setMerDtTm(merDtTm);
        result.setMerSeqNo(merSeqNo);
        result.setTransSeqNo(transSeqNo);

        return result;
    }

    /**
     * 退款
     * @Param type: 1普通退款 2银行转账退款
     * @param orgMerSeqNo 商户流水号（原）
     * @param amount 金额分
     * @param orgTransSeqNo 第三方流水号 (原)
     */
    @Override
    public NbBankOrderResultVO refund(Integer type, String orgMerSeqNo, Integer amount, String orgTransSeqNo) {
        String merSeqNo = idGenerateSnowFlake.nextIdToString(3L);

        String merDtTm = LocalDateTimeUtils.formatTime();
        JSONObject data = bankThirdpartyService.refund(type, merSeqNo, merDtTm, amount,
                orgMerSeqNo, orgTransSeqNo);

        NbBankOrderResultVO result = new NbBankOrderResultVO();

        String transStatus = data.getString("transStatus");
        if (StringUtils.equals(transStatus, "00")){result.setTransStatus(1);}            //交易成功
        else if (StringUtils.equals(transStatus, "01")){result.setTransStatus(2);}       //交易失败
        else if (StringUtils.equals(transStatus, "02")){result.setTransStatus(3);}       //交易已受理
        else if (StringUtils.equals(transStatus, "80")){result.setTransStatus(4);}       //订单初始状态
        else if (StringUtils.equals(transStatus, "90")){result.setTransStatus(5);}       //交易不存在
        else if (StringUtils.equals(transStatus, "99")){result.setTransStatus(6);}       //交易超时,须发起交易结果查询

        String transSeqNo = data.getString("transSeqNo");

        result.setAmount(amount);
        result.setRealAmount(amount);
        result.setMerDtTm(merDtTm);
        result.setMerSeqNo(merSeqNo);
        result.setTransSeqNo(transSeqNo);

        return result;
    }

    /**
     * 银行回调
     * @param merSeqNo 商户流水号
     * @param transSeqNo 第三方流水号
     * @param trxAmt 订单金额分
     * @param realTrxAmt 实收金额分
     * @param transStatus 交易状态
     * @param signNo 转账编码
     */
    @Override
    public void orderPayCallback(String merSeqNo, String transSeqNo,
                                 Integer trxAmt, Integer realTrxAmt,
                                 String transStatus,
                                 String signNo) {
        log.info("宁波银行支付回调, merSeqNo:{}, transSeqNo:{}, trxAmt:{}, realTrxAmt:{}, transSeqNo:{}, signNo:{}",
                merSeqNo, transSeqNo, trxAmt, realTrxAmt, transStatus, signNo);

        NbBankOrderResultVO result = new NbBankOrderResultVO();
        if (StringUtils.equals(transStatus, "00")){     //交易成功
            result.setTransStatus(1);
        }
        if (StringUtils.equals(transStatus, "01")){     //交易失败
            result.setTransStatus(2);
        }
        if (StringUtils.equals(transStatus, "02")){     //交易已受理
            result.setTransStatus(3);
        }
        if (StringUtils.equals(transStatus, "80")){     //订单初始状态
            result.setTransStatus(4);
        }
        if (StringUtils.equals(transStatus, "90")){     //交易不存在
            result.setTransStatus(5);
        }
        if (StringUtils.equals(transStatus, "99")){     //交易超时,须发起交易结果查询
            result.setTransStatus(6);
        }

        orderPayCallback(merSeqNo, transSeqNo, trxAmt, realTrxAmt, result.getTransStatus(), signNo);
    }


    /**
     * 银行回调
     * @param merSeqNo 商户流水号
     * @param transSeqNo 第三方流水号
     * @param trxAmt 订单金额分
     * @param realTrxAmt 实收金额分
     * @param transStatus 交易状态
     * @param signNo 转账编码
     */
    @Override
    public void orderPayCallback(String merSeqNo, String transSeqNo,
                                 Integer trxAmt, Integer realTrxAmt,
                                 Integer transStatus,
                                 String signNo) {
        log.info("宁波银行支付回调, merSeqNo:{}, transSeqNo:{}, trxAmt:{}, realTrxAmt:{}, transSeqNo:{}, signNo:{}",
                merSeqNo, transSeqNo, trxAmt, realTrxAmt, transStatus, signNo);

    }

    /**
     * 获取转账编码，默认银行卡后7位
     */
    private String getSignNo(String signNo, String cardNo){
        return StringUtils.isBlank(signNo)? StringUtils.right(cardNo,7) : signNo;
    }

}
