package com.ruoyi.database.service;

import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.service.WxPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.security.MessageDigest;
import java.util.*;

@Service
public class WechatMiniProgramPayService {

    @Autowired
    private WxPayService wxPayService;

    @Value("${wx.pay.notifyUrl}")
    private String notifyUrl;

    /**
     * 创建小程序支付订单
     */
    public Map<String, Object> createJsapiOrder(String openid, String orderId, Integer amount,
                                                String description, String clientIp) {
        try {
            System.out.println("开始创建支付订单: " + orderId + ", openid: " + openid + ", 金额: " + amount + "分");

            // 构建支付请求
            WxPayUnifiedOrderRequest request = WxPayUnifiedOrderRequest.newBuilder()
                    .outTradeNo(orderId)          // 商户订单号
                    .totalFee(amount)            // 金额（分）
                    .body(description)           // 商品描述
                    .tradeType("JSAPI")          // 交易类型：小程序支付
                    .openid(openid)              // 用户openid
                    .spbillCreateIp(clientIp)    // 终端IP
                    .notifyUrl(notifyUrl)        // 支付结果通知地址
                    .build();

            System.out.println("调用微信支付统一下单API...");
            // 调用微信支付API
            WxPayUnifiedOrderResult result = wxPayService.unifiedOrder(request);

            // 生成小程序支付参数
            Map<String, String> paymentParams = createPaymentParams(result);

            System.out.println("支付订单创建成功: " + orderId + ", prepay_id: " + result.getPrepayId());

            // 返回结果
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("paymentParams", paymentParams);
            response.put("prepayId", result.getPrepayId());
            return response;

        } catch (Exception e) {
            System.err.println("创建支付订单失败: " + orderId + ", 错误: " + e.getMessage());
            e.printStackTrace();

            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "创建支付订单失败: " + e.getMessage());
            return response;
        }
    }

    /**
     * 生成小程序支付参数
     */
    private Map<String, String> createPaymentParams(WxPayUnifiedOrderResult result) {
        Map<String, String> paymentParams = new HashMap<>();

        // 小程序支付必需的参数
        paymentParams.put("appId", result.getAppid());
        paymentParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
        paymentParams.put("nonceStr", result.getNonceStr());
        paymentParams.put("package", "prepay_id=" + result.getPrepayId());
        paymentParams.put("signType", "MD5");

        // 生成签名
        String sign = generateSign(paymentParams);
        paymentParams.put("paySign", sign);

        System.out.println("生成支付参数: " + paymentParams);
        return paymentParams;
    }

    /**
     * 生成支付签名
     */
    private String generateSign(Map<String, String> params) {
        try {
            // 按照参数名ASCII字典序排序
            List<String> keys = new ArrayList<>(params.keySet());
            Collections.sort(keys);

            // 拼接字符串
            StringBuilder sb = new StringBuilder();
            for (String key : keys) {
                if ("sign".equals(key) || key.isEmpty() || params.get(key) == null) {
                    continue;
                }
                sb.append(key).append("=").append(params.get(key)).append("&");
            }

            // 加上API密钥
            sb.append("key=").append(wxPayService.getConfig().getMchKey());

            String signStr = sb.toString();
            System.out.println("签名原串: " + signStr);

            // MD5加密并转大写
            String sign = md5(signStr).toUpperCase();
            System.out.println("生成签名: " + sign);

            return sign;
        } catch (Exception e) {
            throw new RuntimeException("生成签名失败", e);
        }
    }

    /**
     * MD5加密
     */
    private String md5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    }

    /**
     * 获取客户端IP地址
     */
    public String getClientIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        // 如果是多级代理，取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.substring(0, ip.indexOf(",")).trim();
        }

        // 本地开发环境处理
        if ("0:0:0:0:0:0:0:1".equals(ip) || "127.0.0.1".equals(ip)) {
            ip = "123.123.123.123"; // 替换为你的服务器公网IP
        }

        System.out.println("获取到客户端IP: " + ip);
        return ip;
    }

    /**
     * 获取WxPayService实例
     */
    public WxPayService getWxPayService() {
        return wxPayService;
    }
}
