package com.fs.huifuPay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.spring.SpringUtils;
import com.fs.huifuPay.domain.*;
import com.fs.huifuPay.sdk.opps.core.config.MerConfig;
import com.fs.huifuPay.sdk.opps.core.request.*;
import com.fs.huifuPay.sdk.opps.core.utils.SequenceTools;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.huifuPay.sdk.opps.core.utils.DateTools;
import com.fs.store.domain.FsPayConfig;
import com.fs.system.domain.SysConfig;
import com.fs.system.mapper.SysConfigMapper;
import com.google.gson.Gson;
import io.lettuce.core.ScriptOutputType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

import static com.fs.huifuPay.demo.init.BaseCommon.doExecute;
import static com.fs.huifuPay.demo.init.BaseCommon.doInit;

@Service
public class HuiFuServiceImpl implements HuiFuService {
    FsPayConfig config;
    Logger logger= LoggerFactory.getLogger(getClass());

    @Override
    public HuifuCreateOrderResult createOrder(HuiFuCreateOrder order) {
        HuifuCreateOrderResult huifuCreateOrderResult =null;
        try {
            doInit(getMerConfig());
            V2TradePaymentJspayRequest request = new V2TradePaymentJspayRequest();
            request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
            request.setReqSeqId(order.getReqSeqId());
            Map<String, Object> extendInfoMap = new HashMap<>();
            // 交易有效期
            LocalDateTime now = LocalDateTime.now();
            order.setTransAmt(new BigDecimal(order.getTransAmt()).setScale(2, BigDecimal.ROUND_HALF_UP).toString());
            // 增加一个小时
            LocalDateTime oneHourLater = now.plusHours(1);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            String formattedTime = oneHourLater.format(formatter);
            extendInfoMap.put("time_expire", formattedTime);
            // 禁用信用卡标记
            extendInfoMap.put("limit_pay_type", "NO_CREDIT");
            // 是否延迟交易
            extendInfoMap.put("delay_acct_flag", "N");
            extendInfoMap.put("pay_scene", "02");
            // 传入分帐遇到优惠的处理规则
            extendInfoMap.put("term_div_coupon_type", "0");
            if (order.getTradeType().equals("T_MINIAPP")||order.getTradeType().equals("T_JSAPI")){
                JSONObject dto = new JSONObject();
                // 子商户公众账号id
                dto.put("sub_appid", config.getAppId());
                // 用户标识
                dto.put("openid", order.getOpenid());
                extendInfoMap.put("wx_data", dto);
            }
            if (order.getTradeType().equals("T_JSAPI")){
                JSONObject dto = new JSONObject();
                // 子商户公众账号id
                dto.put("sub_appid", config.getAppId());
                // 用户标识
                dto.put("sub_openid", order.getOpenid());
                extendInfoMap.put("wx_data", dto);
            }
            // 交易类型
            request.setTradeType(order.getTradeType());
            // 交易金额
            request.setTransAmt(order.getTransAmt());
            // 商品描述
            request.setGoodsDesc(order.getGoodsDesc());
            extendInfoMap.put("fq_mer_discount_flag", "N");
            extendInfoMap.put("notify_url", config.getHfPayNotifyUrl());
            extendInfoMap.put("remark", "string");
            request.setExtendInfo(extendInfoMap);
            Map<String, Object> response = doExecute(request);
            logger.info("汇付返回："+response);
            String jsonString = JSONObject.toJSONString(response);
            huifuCreateOrderResult = JSON.parseObject(jsonString, HuifuCreateOrderResult.class);

        }catch (Exception e){
            logger.info("汇付支付失败 ："+e);
            e.printStackTrace();
            throw  new CustomException("支付创建失败");
        }
        return huifuCreateOrderResult;

    }

    @Override
    public HuiFuQueryOrderResult queryOrder(V2TradePaymentScanpayQueryRequest request) throws Exception{
        doInit(getMerConfig());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        HuiFuQueryOrderResult huiFuQueryOrderResult = JSON.parseObject(jsonString, HuiFuQueryOrderResult.class);
        return huiFuQueryOrderResult;
    }

    @Override
    public HuiFuCloseResult closeOrder(V2TradePaymentScanpayCloseRequest request) throws Exception{
        doInit(getMerConfig());
        request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        HuiFuCloseResult huiFuCloseResult = JSON.parseObject(jsonString, HuiFuCloseResult.class);
        return huiFuCloseResult;
    }

    @Override
    public HuiFuRefundResult refund(V2TradePaymentScanpayRefundRequest request) {
        HuiFuRefundResult huiFuRefundResult=null;
        try {
            doInit(getMerConfig());
            request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
            Map<String, Object> response = doExecute(request);
            String jsonString = JSONObject.toJSONString(response);
            huiFuRefundResult = JSON.parseObject(jsonString, HuiFuRefundResult.class);
        } catch (Exception e){
            throw  new CustomException("退款创建失败");
        }
        return huiFuRefundResult;

    }

    @Override
    public HuiFuRefundResult queryRefundOrder(V2TradePaymentScanpayRefundqueryRequest request)throws Exception {
        doInit(getMerConfig());
        Map<String, Object> extendInfoMap = request.getExtendInfos();
        extendInfoMap.put("notify_url", config.getHfRefundNotifyUrl());
        request.setExtendInfo(extendInfoMap);
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        HuiFuRefundResult huiFuRefundResult = JSON.parseObject(jsonString, HuiFuRefundResult.class);
        return huiFuRefundResult;

    }

    @Override
    public HuiFuOnlinePayResult onlinepaymentTransferAccount(V2TradeOnlinepaymentTransferAccountRequest request) throws Exception {
        doInit(getMerConfig());
        request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
//        String bankCardNo = request.getBankCardNo();
//        String PublicKeyStr = config.getHfRsaPublicKey();
//        String encrypt = RsaUtils.encrypt(bankCardNo, PublicKeyStr);
//        request.setBankCardNo(encrypt);
        request.setNotifyUrl(config.getHfPayOnlineNotifyUrl());
        // 设置非必填字段
        Map<String, Object> extendInfoMap = new HashMap<>();
        // 收款方用户客户号
        extendInfoMap.put("bank_mode", "SNYH");
        // 收款方账户号
        extendInfoMap.put("acct_mode", "MA");
        extendInfoMap.put("user_huifu_id", "6666000149635112");

        // 备注
        extendInfoMap.put("remark", "标记123");
        request.setExtendInfo(extendInfoMap);
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        HuiFuOnlinePayResult huiFuOnlinePayResult = JSON.parseObject(jsonString, HuiFuOnlinePayResult.class);
        return huiFuOnlinePayResult;
    }

    @Override
    public HuiFuOnlinePayQueryResult onlinepaymentTransferAccountQuery(V2TradeOnlinepaymentTransferAccountQueryRequest request) throws Exception {
        doInit(getMerConfig());
        request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
        request.setReqSeqId(SequenceTools.getReqSeqId32());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        HuiFuOnlinePayQueryResult huFuOnlinePayResult = JSON.parseObject(jsonString, HuiFuOnlinePayQueryResult.class);
        return huFuOnlinePayResult;
    }

    @Override
    public HuiFuOnlineRefundResult onlinepaymentRefund(V2TradeOnlinepaymentRefundRequest request) throws Exception {
        doInit(getMerConfig());
        request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
        Map<String, Object> extendInfoMap = request.getExtendInfos();
        Map<String, Object> bankInfoData = new HashMap<>();
        extendInfoMap.put("bank_info_data", bankInfoData);
        extendInfoMap.put("notify_url", config.getHfOnlineRefundNotifyUrl());
        extendInfoMap.put("remark", "标注");
        request.setExtendInfo(extendInfoMap);
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        HuiFuOnlineRefundResult result = JSON.parseObject(jsonString, HuiFuOnlineRefundResult.class);
        return result;
    }

    @Override
    public HuiFuOnlineRefundQueryResult onlinepaymentRefundQuery(V2TradeOnlinepaymentRefundQueryRequest request) throws Exception {
        doInit(getMerConfig());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        HuiFuOnlineRefundQueryResult result = JSON.parseObject(jsonString, HuiFuOnlineRefundQueryResult.class);
        return result;
    }

    @Override
    public acctPayResult acctPay(V2TradeAcctpaymentPayRequest request) throws Exception{
        doInit(getMerConfig());
        request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        acctPayResult result = JSON.parseObject(jsonString, acctPayResult.class);
        return result;
    }

    @Override
    public acctPayQueryResult acctPayQuery(V2TradeAcctpaymentPayQueryRequest request) throws Exception {
        doInit(getMerConfig());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        acctPayQueryResult result = JSON.parseObject(jsonString, acctPayQueryResult.class);
        return result;
    }
    @Override
    public acctPayRefundResult acctPayRefund(V2TradeAcctpaymentRefundRequest request) throws Exception {
        doInit(getMerConfig());
        request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        acctPayRefundResult result = JSON.parseObject(jsonString, acctPayRefundResult.class);
        return result;
    }

    @Override
    public acctPayRefundQueryResult acctPayRefundQuery(V2TradeAcctpaymentRefundQueryRequest request) throws Exception {
        doInit(getMerConfig());
        Map<String, Object> response = doExecute(request);
        String jsonString = JSONObject.toJSONString(response);
        acctPayRefundQueryResult result = JSON.parseObject(jsonString, acctPayRefundQueryResult.class);
        return result;
    }


    public MerConfig getMerConfig(){
        SysConfigMapper sysConfigMapper= SpringUtils.getBean(SysConfigMapper.class);
        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("store.pay");
        FsPayConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), FsPayConfig.class);
        config=fsPayConfig;
        MerConfig merConfig = new MerConfig();
        merConfig.setProcutId(fsPayConfig.getHfProductId());
        merConfig.setSysId(fsPayConfig.getHfSysId());
        merConfig.setRsaPrivateKey(fsPayConfig.getHfRsaPrivateKey());
        merConfig.setRsaPublicKey(fsPayConfig.getHfRsaPublicKey());
        merConfig.setHuifuId(fsPayConfig.getHuifuId());
        return merConfig;
    }
}
