package com.hzs.third.pay.service.impl;

import cn.hutool.json.JSONUtil;
import com.huifu.bspay.sdk.opps.client.BasePayClient;
import com.huifu.bspay.sdk.opps.core.request.V2TradePaymentJspayRequest;
import com.huifu.bspay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
import com.huifu.bspay.sdk.opps.core.utils.DateTools;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.text.CharsetKit;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.third.pay.TOnlinePayment;
import com.hzs.third.pay.config.HuiFuConfig;
import com.hzs.third.pay.constants.HuiFuPayConstants;
import com.hzs.third.pay.constants.PayRedisConstants;
import com.hzs.third.pay.dto.WechatStateDTO;
import com.hzs.third.pay.service.IHuiFuPayService;
import com.hzs.third.pay.util.PayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 汇付新支付服务
 * @Author: jiang chao
 * @Time: 2024/12/5 10:49
 * @Classname: HuiFuPayServiceImpl
 * @PackageName: com.hzs.third.pay.service.impl
 */
@Slf4j
@Service
public class HuiFuPayServiceImpl implements IHuiFuPayService {

    @Autowired
    private HuiFuConfig huiFuConfig;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public R<String> wechatPrePayUrl(TOnlinePayment tOnlinePayment, boolean urlFlag) {
        try {
            // 缓存对象
            WechatStateDTO wechatStateDTO = new WechatStateDTO();
            wechatStateDTO.setType(tOnlinePayment.getBusinessType());
            wechatStateDTO.setOrderCode(tOnlinePayment.getBusinessCode());
            wechatStateDTO.setPkMember(tOnlinePayment.getPkModified());
            // redis 缓存KEY
            String stateKey = String.format(PayRedisConstants.HUIFU_STATE_KEY, tOnlinePayment.getBusinessCode());
            // 放到redis中缓存（有效期24小时）
            redisTemplate.opsForValue().set(stateKey, JSONUtil.toJsonStr(wechatStateDTO), 24, TimeUnit.HOURS);

            if (urlFlag) {
                StringBuilder url = new StringBuilder("https://open.weixin.qq.com/connect/oauth2/authorize");
                // 公众号appId
                url.append("?appid=").append(huiFuConfig.getPublicAppId());
                // 重写向的URL
                url.append("&redirect_uri=").append(URLEncoder.encode(huiFuConfig.getRedirectUri(), CharsetKit.UTF_8));
                url.append("&response_type=code");
                // 默认授权，只拿openId
                url.append("&scope=snsapi_base");
                // 重定向后会带上 state 参数，开发者可以填写a-zA-Z0-9的参数值，最多128字节
                url.append("&state=").append(tOnlinePayment.getBusinessCode());
                url.append("#wechat_redirect");

                log.info("新汇付支付生成公众号跳转URL：{}, businessCode: {}", url, tOnlinePayment.getBusinessCode());

                return R.ok(url.toString());
            } else {
                return R.ok();
            }
        } catch (Exception e) {
            log.error("新汇付跳转公众号支付返回异常", e);
        }
        return R.fail("跳转微信支付失败");
    }

    @Override
    public R<String> aliPrePayUrl(TOnlinePayment tOnlinePayment) {
        try {
            // 订单编号
            String orderCode = tOnlinePayment.getBusinessCode();
            // 同一订单不能重复，此处添加随机数，防止多次调用
            String thirdOrderCode = PayUtil.getThirdOrderCode(orderCode, null);

            // 实际支付金额（外层统一下单已经随机立减，这个位置直接用）
            BigDecimal amount = tOnlinePayment.getPayMoney();
            if (null == amount) {
                amount = PayUtil.handleAmountRandom(tOnlinePayment.getBusinessMoney());
            }

            // 组装交易参数
            V2TradePaymentJspayRequest request = new V2TradePaymentJspayRequest();
            // 请求日期
            request.setReqDate(DateTools.getCurrentDateYYYYMMDD());
            // 请求流水号（保证唯一）
            request.setReqSeqId(thirdOrderCode);
            // 商户id
            request.setHuifuId(huiFuConfig.getSysId());
            // 商品描述
            request.setGoodsDesc("支付：" + tOnlinePayment.getBusinessCode());
            // 交易类型
            // A_NATIVE：支付宝正扫
            request.setTradeType("A_NATIVE");
            // 交易金额（单位元）
            request.setTransAmt(new DecimalFormat("#0.00").format(amount.doubleValue()));

            Map<String, Object> extendInfoMap = new HashMap<>();
            // 该笔交易的异步通知地址（http/https异步通知地址，必须以virgo://开头）
            extendInfoMap.put("notify_url", huiFuConfig.getNotifyUrl());
            // 交易有效期（24小时）
            extendInfoMap.put("time_expire", DateTools.dateToDateString(DateUtils.addHours(tOnlinePayment.getModifiedTime(), 24), DateTools.DATE_TIME_YYYYMMDDHHMMSS));
            // 备注（交易后原样返回）
            extendInfoMap.put("remark", tOnlinePayment.getBusinessType().toString());
            // 扩展参数
            request.setExtendInfo(extendInfoMap);

            log.info("新汇付跳转支付宝支付调用参数：{}", JSONUtil.toJsonStr(request));

            Map<String, Object> response = BasePayClient.request(request);

            log.info("新汇付跳转支付宝支付调用返回：{}", JSONUtil.toJsonStr(response));

            if (HuiFuPayConstants.TRANS_SUCCESS.equals(response.get("trans_stat").toString())
                    || HuiFuPayConstants.TRANS_PROCESSING.equals(response.get("trans_stat").toString())) {
                // 返回成功
                // 更新新汇付全局流水号
                tOnlinePayment.setPayNumber(response.get("hf_seq_id").toString());

                // 微信支付数据
                String qrCode = response.get("qr_code").toString();
                return R.ok(qrCode);
            } else {
                log.error("新汇付跳转支付宝支付返回失败! resp_desc: {}, bank_message: {}, hf_seq_id: {}", response.get("resp_desc"), response.get("bank_message"), response.get("hf_seq_id"));
            }
        } catch (Exception e) {
            log.error("新汇付跳转支付宝支付返回异常", e);
        }
        return R.fail("跳转支付宝支付失败");
    }

    @Override
    public String queryPayInfo(TOnlinePayment onlinePayment) {
        try {
            // 组装交易参数
            V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
            // 商户id
            request.setHuifuId(huiFuConfig.getSysId());
            // 请求日期
            request.setOrgReqDate(DateTools.getCurrentDateYYYYMMDD());
            // 新汇付全局流水号
            request.setOrgHfSeqId(onlinePayment.getPayNumber());

            log.info("新汇付查询支付结果调用参数：{}", JSONUtil.toJsonStr(request));

            Map<String, Object> response = BasePayClient.request(request);

            log.info("新汇付查询支付结果调用返回：{}", JSONUtil.toJsonStr(response));

            if (HuiFuPayConstants.TRANS_SUCCESS.equals(response.get("trans_stat").toString())) {
                // 交易状态成功
                return "订单支付成功";
            } else {
                log.error("支付单号 {} 查询支付结果【未支付】", onlinePayment.getBusinessCode());
            }
        } catch (Exception e) {
            log.error("新汇付查询支付结果异常!", e);
        }
        return null;
    }

}
