package com.hzs.third.pay.controller.notify;

import cn.hutool.json.JSONUtil;
import com.hzs.common.core.constant.Constants;
import com.hzs.common.core.enums.EPayChannel;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.third.pay.config.BaoFuPayConfig;
import com.hzs.third.pay.constants.BaoFuPayConstants;
import com.hzs.third.pay.controller.base.PayBaseController;
import com.hzs.third.pay.service.IPayService;
import com.hzs.third.pay.util.PayUtil;
import com.hzs.third.pay.util.baofu.SignatureUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * 宝付支付回调控制器
 */
@Slf4j
@RestController
@RequestMapping("/baofu")
public class BaoFuPayNotifyController extends PayBaseController {

    @Autowired
    private BaoFuPayConfig baoFuPayConfig;
    @Autowired
    private IPayService iPayService;

    /**
     * 支付回调
     *
     * @param request
     */
    @PostMapping("/notify")
    public String payNotify(HttpServletRequest request) throws Exception {
        try {
            // 通知传输的编码为UTF-8
            request.setCharacterEncoding(Constants.UTF8);
            // 动态遍历获取所有收到的参数,此步非常关键,因为收银宝以后可能会加字段,动态获取可以兼容
            TreeMap<String, String> params = PayUtil.getParams(request);

            log.info("宝付支付回调 body： {}", params);

            if (BaoFuPayConstants.SUCCESS.equals(params.get("returnCode"))) {
                // 接口返回成功
                if (SignatureUtils.verifySignature(baoFuPayConfig.getCerPath(), params.get("dataContent"), params.get("signStr"))) {
                    // 验证通过
                    // 业务数据
                    Map<String, Object> dataContent = JSONUtil.toBean(params.get("dataContent"), HashMap.class);

                    if (BaoFuPayConstants.SUCCESS.equals(dataContent.get("txnState"))) {
                        // 交易成功
                        // 宝付交易流水号
                        String payNumber = dataContent.get("tradeNo").toString();
                        // 支付完成时间
                        Date payTime = DateUtils.parseDateOne(dataContent.get("finishTime"), DateUtils.YAMMERERS);
                        // 支付扩展类型
                        String type = "";

                        // 回调订单编号
                        String thirdOrderCode = dataContent.get("outTradeNo").toString();
                        // 订单编号
                        String orderCode = thirdOrderCode;
                        // 处理订单号以及扩展类型
                        if (thirdOrderCode.indexOf("_") > 0) {
                            // 带有分隔，需要处理
                            orderCode = thirdOrderCode.split("_")[0];
                            // 微信没有支付扩展参数，目前添加到三方订单号上用以区分
                            type = thirdOrderCode.split("_")[1].substring(0, 1);
                        }
                        log.info("宝付支付对应扩展类型：{}", type);

                        int succAmt = (int) dataContent.get("succAmt");
                        // 订单金额
                        BigDecimal payMoney = new BigDecimal(succAmt).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);

                        // 渠道流水号
                        String channelNumber = "";
                        Object chlRetParam = dataContent.get("chlRetParam");
                        if (null != chlRetParam) {
                            Object channelNumberObj = JSONUtil.parseObj(chlRetParam).get("transaction_id");
                            if (null != channelNumberObj) {
                                channelNumber = channelNumberObj.toString();
                            }
                        }

                        // 支付后续业务处理
                        if (iPayService.notifyHandle(type, orderCode, thirdOrderCode, payNumber, payTime, payMoney, EPayChannel.BAOFU, channelNumber)) {
                            return "OK";
                        }
                    } else {
                        log.error("宝付支付回调订单状态异常");
                    }
                } else {
                    log.error("宝付支付回调签名验证失败");
                }
            } else {
                log.error("宝付支付回调交易失败");
            }
        } catch (Exception e) {
            log.error("宝付支付回调处理异常", e);
        }
        throw new Exception("处理异常");
    }

}
