package com.ruoyi.web.controller.common;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.ServiceConstants;
import com.ruoyi.common.enums.PayChannel;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.ss.callback.domain.CallbackLog;
import com.ruoyi.ss.callback.mapper.CallbackLogMapper;
import com.ruoyi.ss.callback.service.ICallbackService;
import com.wechat.pay.java.core.exception.ValidationException;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import com.ruoyi.common.utils.http.HttpUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.ruoyi.common.pay.tm.TmPayService ;
import com.ruoyi.common.pay.tm.enums.PayStatus;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 支付回调
 */
@Slf4j
@RestController
@RequestMapping("/payment/callback")
public class CallbackController {

    @Autowired
    private ICallbackService callbackService;

    @Autowired
    private TmPayService tmPayService;

    @Autowired
    private ScheduledExecutorService scheduledExecutorService;

    @Resource
    private CallbackLogMapper callbackLogMapper;

    /**
     * 微信支付回调
     */
    @ApiOperation(value = "微信支付回调")
    @RequestMapping(value = "/wechat", method = RequestMethod.POST)
    public ResponseEntity<Boolean> weChat(HttpServletRequest request) {
        try {
            callbackService.weChat(request);
        } catch (ValidationException e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
        return ResponseEntity.status(HttpStatus.OK).body(null);
    }

    /**
     * 微信退款回调
     */
    @ApiOperation(value = "微信退款回调")
    @RequestMapping(value = "/wechat/refund", method = RequestMethod.POST)
    public ResponseEntity<Boolean> weChatRefund(HttpServletRequest request) {
        try {
            callbackService.weChatRefund(request);
        } catch (ValidationException e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
        return ResponseEntity.status(HttpStatus.OK).body(null);
    }

    /**
     * 太米微信支付回调
     */
    @ApiOperation(value = "太米微信支付回调")
    @RequestMapping(value = "/tmwx", method = RequestMethod.POST)
    public String tmwx(HttpServletRequest request) {
        try {
            String body = HttpUtils.getBody(request);
            log.info("【太米微信支付回调】接收对象 : {}", body);
            // 先把body转成map
            Map<String, Object> params = JSON.parseObject(body, Map.class);
            // 验证签名
            boolean sign = tmPayService.validSign(params);
            if (sign) {
                JSONObject tradeInfo = (JSONObject)params.get("tradeInfo");
                String payType = (String)tradeInfo.get("payType"); // 交易类型
                String outTradeNo = (String)tradeInfo.get("outTradeId");   // 商户自定义订单号
                String trxStatus = (String)tradeInfo.get("payStatus");    // 交易结果
                if(PayStatus.isSuccess(trxStatus) && payType.equals("wx_pay")) {
                    // 新版支付订单
                    callbackService.businessHandle(outTradeNo, ServiceConstants.PAY_TYPE_TMWX,DateUtils.toLocalDateTime(tradeInfo.getDate("payTime")));
                }
                //异步保存回调日志
                asynchronousSaveCallbackLog(body);// tradeInfo -> {JSONObject@14208}  size = 34
            }else {
                throw new ServiceException("签名验证失败");
            }
            return "{\"result\":\"SUCCESS\"}";
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    private void asynchronousSaveCallbackLog(String body) {
        //开异步线程保存回调参数
        scheduledExecutorService.schedule(() -> {
            log.info("【微信支付回调】异步保存回调参数");
            CallbackLog callbackLog = new CallbackLog();
            callbackLog.setBody(body);
            callbackLog.setType("1");
            callbackLog.setCreateTime(DateUtils.getNowDate());
            int i = callbackLogMapper.insertEtCallbackLog(callbackLog);
            if(i>0){
                log.info("【微信支付回调】异步保存回调参数成功");
            }
        }, 0, TimeUnit.SECONDS);
    }


}
