package com.ruoyi.hezhi.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.weixin.config.WeiXinPayConfig;
import com.ruoyi.common.weixin.utils.WeiXinPayV3Utils;
import com.ruoyi.hezhi.domain.TbMemberOrder;
import com.ruoyi.hezhi.domain.TbStudent;
import com.ruoyi.hezhi.mapper.TbMemberOrderMapper;
import com.ruoyi.hezhi.mapper.TbStudentMapper;
import com.ruoyi.hezhi.service.ITbMemberOrderService;
import com.ruoyi.hezhi.service.IWxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

/**
 * @Author haoxuyang
 * @Date 2025/2/6 14:08
 */
@Service
@Slf4j
public class WxPayService implements IWxPayService {
    @Resource
    private ITbMemberOrderService memberOrderService;

    @Resource
    private WeiXinPayV3Utils weiXinPayV3Utils;

    @Resource
    private WeiXinPayConfig weiXinPayConfig;
    @Resource
    private TbStudentMapper tbStudentMapper;


    @Override
    public Object createOrder(String orderNo) {
        if (StrUtil.isBlank(orderNo)) {
            throw new ServiceException("参数错误");
        }

        TbMemberOrder order = memberOrderService.selectOrderByOrderNo(orderNo);
        if (ObjectUtils.isEmpty(order)) {
            throw new ServiceException("订单错误");
        }

        BigDecimal payPrice = order.getPayPrice();

        if (payPrice.compareTo(BigDecimal.ZERO) < 1) {
            // 无需支付
            JSONObject data = new JSONObject();
            data.put("isNeedPay", 0);
            memberOrderService.orderPayNotify(orderNo, 1);
            return AjaxResult.success(data);
        } else {
            //获取openId
            TbStudent tbStudent = tbStudentMapper.selectTbStudentByStudentId(order.getMemberUserId());
            if (ObjectUtils.isEmpty(tbStudent) || ObjectUtils.isEmpty(tbStudent.getOpenId())) {
                throw new ServiceException("参数错误");
            }
            JSONObject amount = new JSONObject();
            //单位为人民币（分）
            amount.put("total", order.getPayPrice().multiply(new BigDecimal("100")).intValue());
            amount.put("currency", "CNY");

            JSONObject payer = new JSONObject();
            //发起者
            payer.put("openid", tbStudent.getOpenId());

            JSONObject postData = new JSONObject();
            postData.put("appid", weiXinPayConfig.getAppId());
            postData.put("mchid", weiXinPayConfig.getMchId());
            postData.put("description", order.getRemarks());
            postData.put("out_trade_no", orderNo);
            postData.put("notify_url", weiXinPayConfig.getNotifyUrl());
            postData.put("amount", amount);
            postData.put("payer", payer);

            log.info("微信下单-参数 => {}", postData.toJSONString());

            // 请求JSAPI下单
            JSONObject result = weiXinPayV3Utils.sendPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", postData);
            if (result.containsKey("prepay_id")) {
                // 支付参数
                Map<String, String> payInfo = new HashMap<>();
                // 小程序ID
                payInfo.put("appId", weiXinPayConfig.getAppId());
                // 时间戳
                payInfo.put("timeStamp", String.valueOf((int) (System.currentTimeMillis() / 1000)));
                // 随机字符串
                payInfo.put("nonceStr", IdUtils.fastSimpleUUID());
                // 订单详情扩展字符串
                payInfo.put("package", "prepay_id=" + result.getString("prepay_id"));
                // 签名方式
                payInfo.put("signType", "RSA");
                // 加密字符串，每行一个参数
                String paySignParam = payInfo.get("appId") + "\n" + payInfo.get("timeStamp") + "\n" + payInfo.get("nonceStr") + "\n" + payInfo.get("package") + "\n";
                // 签名
                String paySign = weiXinPayV3Utils.signRSA(paySignParam);
                payInfo.put("paySign", paySign);

                // 订单信息
                Map<String, Object> orderInfo = new HashMap<>();
                orderInfo.put("totalAmount", amount);
                orderInfo.put("orderSn", orderNo);
                orderInfo.put("payAt", DateUtils.getTime());

                Map<String, Object> data = new HashMap<>();
                data.put("payInfo", payInfo);
                data.put("orderInfo", orderInfo);
                return data;
            }else{
                log.error("微信下单调起失败 <{}> 参数：{}，结果：{}", DateUtils.getTime(), postData.toJSONString(), result.toJSONString());
                throw new ServiceException("微信下单调起失败");
            }
        }
    }

}
