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.IRefundService;
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-refund")
public class BaoFuRefundNotifyController extends PayBaseController {

    @Autowired
    private BaoFuPayConfig baoFuPayConfig;
    @Autowired
    private IRefundService iRefundService;

    /**
     * 宝付退款回调
     *
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping("/notify")
    public String refundNotify(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);

                    // 宝付交易流水号
                    String refundNumber = dataContent.get("tradeNo").toString();
                    // 退款编号
                    String refundCode = dataContent.get("outTradeNo").toString();
                    // 退款完成时间
                    Date finishTime = DateUtils.parseDateOne(dataContent.get("finishTime"), DateUtils.YAMMERERS);
                    // 退款金额
                    int succAmt = Integer.parseInt(dataContent.get("succAmt").toString());
                    BigDecimal finishMoney = new BigDecimal(succAmt).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);

                    // 返回状态正常
                    if (BaoFuPayConstants.SUCCESS.equals(dataContent.get("refundState").toString())) {
                        // 退款成功
                        // 退款后续业务处理
                        if (iRefundService.notifyHandle(EPayChannel.BAOFU, refundCode, refundNumber, finishTime, finishMoney)) {
                            return "OK";
                        }
                    } else {
                        // 退款失败
                        log.error("宝付退款失败");

                        if (iRefundService.notifyErrorHandle(EPayChannel.BAOFU, refundCode, refundNumber, "宝付退款失败")) {
                            return "OK";
                        }
                    }
                } else {
                    log.error("宝付退款回调签名验证失败");
                }
            } else {
                log.error("宝付退款回调交易失败");
            }
        } catch (Exception e) {
            log.error("宝付退款回调处理异常", e);
        }
        throw new Exception("处理异常");
    }

}
