package com.gxwebsoft.common.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.Order;
import com.gxwebsoft.common.system.entity.Payment;
import com.gxwebsoft.common.system.mapper.OrderMapper;
import com.gxwebsoft.common.system.param.OrderParam;
import com.gxwebsoft.common.system.service.OrderService;
import com.gxwebsoft.common.system.service.PaymentService;
import com.gxwebsoft.common.system.service.SettingService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

/**
 * 订单Service实现
 *
 * @author 科技小王子
 * @since 2024-04-24 13:46:21
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
  @Value("${spring.profiles.active}")
  String active;
  @Resource
  private ConfigProperties config;
  @Resource
  private SettingService settingService;
  @Resource
  private RedisUtil redisUtil;
  @Resource
  private PaymentService paymentService;
  public static String privateKeyPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/apiclient_key.pem";
  public static String privateCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/apiclient_cert.pem";
  public static String serialNumber = "48749613B40AA8F1D768583FC352358E13EB5AF0";
  public static String merchantId = "1246610101";
  public static String appId = "wx541db955e7a62709";
  public static String apiV3Key = "zGufUcqa7ovgxRL0kF5OlPr482EZwtn9";

  /**
   * 平台证书生成命令(勿删)
   * java -jar CertificateDownloader.jar -k zGufUcqa7ovgxRL0kF5OlPr482EZwtn9 -m 1246610101 -f /www/wwwroot/file.ws//file/20240511/280fb6cf7eec4c2d9661c2508123c6a8.pem -s 48749613B40AA8F1D768583FC352358E13EB5AF0 -o /www/cert/
   */
  public static String wechatpayCertPath = "/Users/gxwebsoft/JAVA/com.gxwebsoft.core/src/main/resources/cert/wechatpay_4A3231584E93B6AE77820074D07EADEACCB7E223.pem";  // 平台证书

  @Override
  public PageResult<Order> pageRel(OrderParam param) {
    PageParam<Order, OrderParam> page = new PageParam<>(param);
    page.setDefaultOrder("create_time desc");
    List<Order> list = baseMapper.selectPageRel(page, param);
    return new PageResult<>(list, page.getTotal());
  }

  @Override
  public List<Order> listRel(OrderParam param) {
    List<Order> list = baseMapper.selectListRel(param);
    // 排序
    PageParam<Order, OrderParam> page = new PageParam<>();
    return page.sortRecords(list);
  }

  @Override
  public Order getByIdRel(Integer orderId) {
    OrderParam param = new OrderParam();
    param.setOrderId(orderId);
    return param.getOne(baseMapper.selectListRel(param));
  }

  @Override
  public Order getByOutTradeNo(String outTradeNo) {
    System.out.println("outTradeNo = " + outTradeNo);
    OrderParam param = new OrderParam();
    param.setOrderNo(outTradeNo);
    return param.getOne(baseMapper.getByOutTradeNo(param));
  }

  @Override
  public void updateByOutTradeNo(Order order) {
    baseMapper.updateByOutTradeNo(order);
  }

  /**
   * 创建微信支付
   *
   * @param order
   * @return
   */
  @Override
  public HashMap<String, String> createWxOrder(Order order) {
    // 服务器本地路径
    final String uploadPath = config.getUploadPath();
    final HashMap<String, String> orderInfo = new HashMap<>();
    // 微信小程序(微信支付)
    String key = "Payment:wxPay:".concat(order.getTenantId().toString());
    final Payment payment = redisUtil.get(key, Payment.class);

    final JSONObject mpWx = settingService.getBySettingKey("mp-weixin");

    // 计算金额
    BigDecimal decimal = order.getTotalPrice();
    final BigDecimal multiply = decimal.multiply(new BigDecimal(100));
    // 将 BigDecimal 转换为 Integer
    Integer money = multiply.intValue();
    String privateKey = uploadPath.concat("/file").concat(payment.getApiclientKey());    // 秘钥证书
    String apiclientCert = uploadPath.concat("/file").concat(payment.getApiclientCert());
    // 开发环境配置
    if(active.equals("dev")){
      privateKey = privateKeyPath;
      apiclientCert = wechatpayCertPath;
    }
    Config config =
      new RSAConfig.Builder()
        .merchantId(payment.getMchId())
        .privateKeyFromPath(privateKey)
        .merchantSerialNumber(payment.getMerchantSerialNumber())
        .wechatPayCertificatesFromPath(apiclientCert)
        .build();

    // 构建service
    JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
    // 跟之前下单示例一样，填充预下单参数
    PrepayRequest request = new PrepayRequest();
    Amount amount = new Amount();
    amount.setTotal(money);
    amount.setCurrency("CNY");
    request.setAmount(amount);
    request.setAppid(mpWx.getString("appId"));
    request.setMchid(payment.getMchId());
    request.setDescription(order.getComments());
    request.setNotifyUrl("https://server.gxwebsoft.com/api/system/wx-pay/notify/" + order.getTenantId());
    request.setOutTradeNo(order.getOrderNo());
    request.setAttach(order.getTenantId().toString());
    final Payer payer = new Payer();
    payer.setOpenid(order.getOpenid());
    request.setPayer(payer);
    if (StrUtil.isNotBlank(payment.getNotifyUrl())) {
      request.setNotifyUrl(payment.getNotifyUrl().concat("/").concat(order.getTenantId().toString()));
    }
    // 测试金额
    if(active.equals("dev")){
      amount.setTotal(1);
      request.setAmount(amount);
    }
    System.out.println("request = " + request);
    PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
    orderInfo.put("provider", "wxpay");
    orderInfo.put("timeStamp", response.getTimeStamp());
    orderInfo.put("nonceStr", response.getNonceStr());
    orderInfo.put("package", response.getPackageVal());
    orderInfo.put("signType", "RSA");
    orderInfo.put("paySign", response.getPaySign());
    return orderInfo;
  }
}
