package com.gxwebsoft.shop.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.shop.entity.Order;
import com.gxwebsoft.shop.entity.OrderInfo;
import com.gxwebsoft.shop.entity.Payment;
import com.gxwebsoft.shop.service.OrderInfoService;
import com.gxwebsoft.shop.service.OrderService;
import com.gxwebsoft.shop.service.UsersService;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RSANotificationConfig;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;

/**
 * 会员特权购买记录表控制器
 *
 * @author 科技小王子
 * @since 2023-06-20 18:07:50
 */
@Api(tags = "微信支付结果通知")
@RestController
@RequestMapping("/api/shop/wx-pay")
public class WxPayNotifyController extends BaseController {
    @Value("${spring.profiles.active}")
    String active;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderInfoService orderInfoService;
    @Resource
    private UsersService usersService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private ConfigProperties conf;
    // 本地证书
    public static String wechatpayCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/wechatpay_4A3231584E93B6AE77820074D07EADEACCB7E223.pem";  // 平台证书

  @ApiModelProperty("异步通知")
  @PostMapping("/notify/{tenantId}")
  public String wxNotify(@RequestHeader Map<String, String> header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) {
    System.out.println("异步通知*************** = ");
    System.out.println("request header = " + header);
    System.out.println("request body = " + body);
    System.out.println("tenantId = " + tenantId);

    // 获取支付配置信息用于解密
    String key = "Payment:1:".concat(tenantId.toString());
    final Payment payment = redisUtil.get(key, Payment.class);
    String privateKey = payment.getApiKey();
    String apiclientCert = conf.getUploadPath().concat("/file").concat(payment.getApiclientCert());
    // 开发环境配置
    if(active.equals("dev")){
      apiclientCert = wechatpayCertPath;
    }

    com.wechat.pay.java.core.notification.RequestParam requestParam = new com.wechat.pay.java.core.notification.RequestParam.Builder()
      .serialNumber(header.get("wechatpay-serial"))
      .nonce(header.get("wechatpay-nonce"))
      .signature(header.get("wechatpay-signature"))
      .timestamp(header.get("wechatpay-timestamp"))
      .body(body)
      .build();

    System.out.println("payment = " + payment);
    System.out.println("requestParam = " + requestParam);

    // 如果已经初始化了 RSAAutoCertificateConfig，可直接使用
    // 没有的话，则构造一个
    NotificationConfig config = new RSANotificationConfig.Builder()
      .apiV3Key(privateKey)
      .certificatesFromPath(apiclientCert)
      .build();


    // 初始化 NotificationParser
    NotificationParser parser = new NotificationParser(config);

    // 以支付通知回调为例，验签、解密并转换成 Transaction
    try {
      Transaction transaction = parser.parse(requestParam, Transaction.class);
      final String outTradeNo = transaction.getOutTradeNo();
      final String transactionId = transaction.getTransactionId();
      final Integer total = transaction.getAmount().getTotal();
      final String tradeStateDesc = transaction.getTradeStateDesc();
      final Transaction.TradeStateEnum tradeState = transaction.getTradeState();
      final Transaction.TradeTypeEnum tradeType = transaction.getTradeType();
      System.out.println("transaction = " + transaction);
      System.out.println("tradeStateDesc = " + tradeStateDesc);
      System.out.println("tradeType = " + tradeType);
      System.out.println("tradeState = " + tradeState);
      System.out.println("outTradeNo = " + outTradeNo);
      System.out.println("amount = " + total);

      if (StrUtil.equals("支付成功", tradeStateDesc)) {
        // 1. 查询要处理的订单
        Order order = orderService.getByOutTradeNo(outTradeNo);
        // 2. 已支付则跳过
        if (order.getPayStatus().equals(1)) {
          return "SUCCESS";
        }
        // 2. 未支付则处理更新订单状态
        if (order.getPayStatus().equals(0)) {
          // 5. TODO 处理订单状态
          order.setPayTime(DateUtil.date());
          order.setPayStatus(1);
          order.setTransactionId(transactionId);
          order.setPayPrice(new BigDecimal(NumberUtil.decimalFormat("0.00", total * 0.01)));
          order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 10));
          System.out.println("实际付款金额 = " + order.getPayPrice());
          orderService.updateByOutTradeNo(order);
          // 6. TODO 同步更新订单明细的支付状态
          orderInfoService.update(new LambdaUpdateWrapper<OrderInfo>().eq(OrderInfo::getOrderId,order.getOrderId()).set(OrderInfo::getPayStatus,1));
//          orderInfoService.updateByOutTradeNo(order);
          // 7.同步会员卡状态
//          if(order.getType().equals(2)){
//            final UserCard userCard = userCardService.getById(order.getCardId());
//            userCard.setStatus(1);
//            userCardService.updateById(userCard);
//          }
          // 8.发放积分
          usersService.addIntegral(order);

          return "SUCCESS";
        }
      }
    } catch (Exception $e) {
      System.out.println($e.getMessage());
    }

    return "fail";
  }


}
