package shop.alien.lawyer.util.ali;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import shop.alien.entity.result.R;
import shop.alien.entity.store.*;
import shop.alien.lawyer.service.StoreAliPayRefundLogService;
import shop.alien.lawyer.service.StoreAliPayErrorLogService;
import shop.alien.util.common.UniqueRandomNumGenerator;
import shop.alien.util.common.UrlEncode;
import shop.alien.util.system.OSUtil;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 支付宝相关组件
 *
 * @author ssk
 * @version 1.0
 * @date 2024/12/10 8:49
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AliApi {


private final StoreAliPayRefundLogService storeAliPayRefundLogService;
private final StoreAliPayErrorLogService storeAliPayErrorLogService;

    /**
     * 商家端appId
     */
    @Value("${app.business.appId}")
    private String businessAppId;

    /**
     * 商家端app私钥
     */
    @Value("${app.business.appPrivateKey}")
    private String businessAppPrivateKey;

    /**
     * 商家端app公钥
     */
    @Value("${app.business.appPublicKey}")
    private String businessAppPublicKey;

    /**
     * windows应用公钥证书文件路径
     */
    @Value("${app.business.win.appCertPath}")
    private String businessWinAppCertPath;

    /**
     * windows支付宝公钥证书文件路径
     */
    @Value("${app.business.win.alipayPublicCertPath}")
    private String businessWinAlipayPublicCertPath;

    /**
     * windows支付宝根证书文件路径
     */
    @Value("${app.business.win.alipayRootCertPath}")
    private String businessWinAlipayRootCertPath;

    /**
     * linux应用公钥证书文件路径
     */
    @Value("${app.business.linux.appCertPath}")
    private String businessLinuxAppCertPath;

    /**
     * linux支付宝公钥证书文件路径
     */
    @Value("${app.business.linux.alipayPublicCertPath}")
    private String businessLinuxAlipayPublicCertPath;

    /**
     * linux支付宝根证书文件路径
     */
    @Value("${app.business.linux.alipayRootCertPath}")
    private String businessLinuxAlipayRootCertPath;

    /**
     * 支对称加密算法密钥
     */
    @Value("${ali.aes.encryptKey}")
    private String encryptKey;


    /**
     * 填写阿里配置
     *
     * @return AlipayConfig
     */
    private AlipayConfig setAlipayConfig(String type) {
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId(businessAppId);
        alipayConfig.setPrivateKey(businessAppPrivateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        if ("windows".equals(OSUtil.getOsName())) {
            alipayConfig.setAppCertPath(businessWinAppCertPath);
            alipayConfig.setAlipayPublicCertPath(businessWinAlipayPublicCertPath);
            alipayConfig.setRootCertPath(businessWinAlipayRootCertPath);
        } else {
            alipayConfig.setAppCertPath(businessLinuxAppCertPath);
            alipayConfig.setAlipayPublicCertPath(businessLinuxAlipayPublicCertPath);
            alipayConfig.setRootCertPath(businessLinuxAlipayRootCertPath);
        }
        if ("aes".equals(type)) {
            alipayConfig.setEncryptType("AES");
            alipayConfig.setEncryptKey(encryptKey);
        }
        return alipayConfig;
    }

    public JSONObject promotionPackagePay(String price, String subject) {
        try {
            JSONObject jsonObject = new JSONObject();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            String orderNo = UniqueRandomNumGenerator.generateUniqueCode(19);
            AlipayClient alipayClient = new DefaultAlipayClient(setAlipayConfig(null));
            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setOutTradeNo(orderNo);
            model.setTotalAmount(price);
            model.setSubject(subject);
            model.setPassbackParams(UrlEncode.getUrlEncode(dateFormat.toString()));
            request.setBizModel(model);
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            String orderStr = "";
            if (response.isSuccess()) {
                orderStr = response.getBody();
            } else {
                System.out.println("调用失败 response：" + response);
                orderStr = "调用失败";
            }
            jsonObject.put("orderStr", orderStr);
            jsonObject.put("orderNo", orderNo);
            return jsonObject;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 退款
     *
     * @param outTradeNo
     * @param refundAmount
     * @param refundReason
     * @return
     */

    public String processRefund(String outTradeNo, String refundAmount, String refundReason, String partialRefundCode) {
        try {
            // TODO 部分退款支付宝接口修改
            AlipayClient alipayClient = new DefaultAlipayClient(setAlipayConfig(null));
            AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
            AlipayTradeRefundModel model = new AlipayTradeRefundModel();
            model.setOutTradeNo(outTradeNo);
            model.setRefundAmount(refundAmount);
            model.setRefundReason(refundReason);
            if (StringUtils.isNotBlank(partialRefundCode)) {
                model.setOutRequestNo(partialRefundCode);
            }
            request.setBizModel(model);
            AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
            String refundReslut = "";
            if (response.isSuccess()) {
                refundReslut = "调用成功";
                // 保存退款信息进入到退款记录表
                JSONObject responseBody = JSONObject.parseObject(response.getBody());
                JSONObject refundResponse = responseBody.getJSONObject("alipay_trade_refund_response");
                
                StoreAliPayRefundLog refundLog = new StoreAliPayRefundLog();
                // 响应基本信息
                refundLog.setResponseCode(refundResponse.getString("code"));
                refundLog.setResponseMsg(refundResponse.getString("msg"));
                // 买家信息
                refundLog.setBuyerLogonId(refundResponse.getString("buyer_logon_id"));
                refundLog.setBuyerOpenId(refundResponse.getString("buyer_open_id"));
                // 资金变动信息
                refundLog.setFundChange(refundResponse.getString("fund_change"));
                // 订单信息
                refundLog.setOutTradeNo(refundResponse.getString("out_trade_no"));
                refundLog.setTradeNo(refundResponse.getString("trade_no"));
                // 退款金额信息
                refundLog.setRefundFee(refundResponse.getString("refund_fee"));
                refundLog.setSendBackFee(refundResponse.getString("send_back_fee"));
                // 退款渠道明细（转换为JSON字符串）
                if (refundResponse.containsKey("refund_detail_item_list")) {
                    JSONArray refundDetailList = refundResponse.getJSONArray("refund_detail_item_list");
                    if (refundDetailList != null) {
                        refundLog.setRefundDetailItemList(JSON.toJSONString(refundDetailList));
                    }
                }
                // 退款时间（字符串转Date）
                String gmtRefundPayStr = refundResponse.getString("gmt_refund_pay");
                if (StringUtils.isNotBlank(gmtRefundPayStr)) {
                    try {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        refundLog.setGmtRefundPay(sdf.parse(gmtRefundPayStr));
                    } catch (ParseException e) {
                        log.warn("解析退款时间失败: {}", gmtRefundPayStr, e);
                    }
                }
                // 退款原因和部分退款编号（从请求参数中获取）
                refundLog.setRefundReason(refundReason);
                refundLog.setOutRequestNo(partialRefundCode);
                // 证书和签名信息
                refundLog.setAlipayCertSn(responseBody.getString("alipay_cert_sn"));
                refundLog.setSign(responseBody.getString("sign"));
                // 标准字段
                refundLog.setDeleteFlag(0);
                refundLog.setCreatedTime(new Date());
                
                storeAliPayRefundLogService.save(refundLog);

            } else {
                log.warn("AliPayConfig.processRefund ERROR Msg={}", response.getBody());
                // 退款失败，保存错误信息到错误日志表
                JSONObject refundResponse = null;
                try {
                    JSONObject responseBody = JSONObject.parseObject(response.getBody());
                    refundResponse = responseBody.getJSONObject("alipay_trade_refund_response");
                    
                    StoreAliPayErrorLog errorLog = new StoreAliPayErrorLog();
                    // 订单金额
                    errorLog.setTransAmount(refundAmount);
                    // 阿里返回错误信息
                    errorLog.setSubMsg(refundResponse.getString("sub_msg"));
                    // 阿里返回状态码
                    errorLog.setSubCode(refundResponse.getString("sub_code"));
                    // 阿里返回参数具体内容（保存完整的响应体）
                    errorLog.setBizContent(response.getBody());
                    // 错误信息（优先使用sub_msg，如果没有则使用msg）
                    String errorMsg = refundResponse.getString("sub_msg");
                    if (StringUtils.isBlank(errorMsg)) {
                        errorMsg = refundResponse.getString("msg");
                    }
                    if (StringUtils.isBlank(errorMsg)) {
                        errorMsg = "支付宝退款失败";
                    }
                    errorLog.setInformation(errorMsg);
                    // 标准字段
                    errorLog.setDeleteFlag(0);
                    errorLog.setCreatedTime(new Date());
                    
                    storeAliPayErrorLogService.save(errorLog);
                    log.info("退款失败错误信息已保存到错误日志表，订单号: {}, 错误信息: {}", outTradeNo, errorMsg);
                } catch (Exception e) {
                    log.error("保存退款失败错误信息到错误日志表时发生异常，订单号: {}", outTradeNo, e);
                }
                
                // 设置返回的错误信息
                if (refundResponse != null) {
                    refundReslut = refundResponse.getString("sub_msg");
                    if (StringUtils.isBlank(refundReslut)) {
                        refundReslut = refundResponse.getString("msg");
                    }
                }
                if (StringUtils.isBlank(refundReslut)) {
                    refundReslut = "退款失败";
                }
            }
            return refundReslut;
        } catch (AlipayApiException e) {
            // 异常情况，也保存错误信息到错误日志表
            try {
                StoreAliPayErrorLog errorLog = new StoreAliPayErrorLog();
                // 订单金额
                errorLog.setTransAmount(refundAmount);
                // 错误信息
                String errorMsg = "支付宝退款接口调用异常: " + e.getMessage();
                errorLog.setInformation(errorMsg);
                // 异常信息保存到bizContent
                errorLog.setBizContent("异常类型: " + e.getClass().getName() + ", 异常信息: " + e.getMessage());
                // 标准字段
                errorLog.setDeleteFlag(0);
                errorLog.setCreatedTime(new Date());
                
                storeAliPayErrorLogService.save(errorLog);
                log.info("退款异常错误信息已保存到错误日志表，订单号: {}, 异常信息: {}", outTradeNo, errorMsg);
            } catch (Exception ex) {
                log.error("保存退款异常错误信息到错误日志表时发生异常，订单号: {}", outTradeNo, ex);
            }
            log.error("AliPayConfig.processRefund 调用支付宝退款接口异常，订单号: {}", outTradeNo, e);
            throw new RuntimeException("支付宝退款接口调用失败: " + e.getMessage(), e);
        }
    }



//   public R<String> queryPayment(String outTradeNo) {
//
//       try {
//           AlipayClient alipayClient = new DefaultAlipayClient(setAlipayConfig(null));
//           // 2. 构造查询请求
//           AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
//           // 设置biz_content（JSON格式）
//           String bizContent = "{\"out_trade_no\":\" "+outTradeNo+"\"}";
//           request.setBizContent(bizContent);
//           // 3. 调用接口并获取响应
//           AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
//           if (response.isSuccess()) {
//               // 4. 解析支付状态
//               String tradeStatus = response.getTradeStatus();
//               log.info("订单查询成功，支付状态：" + tradeStatus);
//
//               // 支付状态说明：
//               // WAIT_BUYER_PAY：等待买家付款
//               // TRADE_CLOSED：交易关闭（超时未支付/已取消）
//               // TRADE_SUCCESS：支付成功（即时到账/普通转账）
//               // TRADE_FINISHED：交易完成（不可退款的场景，如即时到账）
//                if ("TRADE_SUCCESS".equals(tradeStatus)){
//                    return  R.success("支付成功");
//                }
//           } else {
//               System.out.println();
//
//               return R.fail("订单查询失败：" + response.getMsg() + "(" + response.getSubMsg() + ")");
//           }
//       } catch (AlipayApiException e) {
//           e.printStackTrace();
//       }
//       return R.fail("支付失败");
//    }


    public R<String> queryPayment(String outTradeNo, String tradeNo) {
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(setAlipayConfig(null));
            // 2. 构造查询请求
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

            // 设置biz_content（JSON格式）
            JSONObject bizContent = new JSONObject();
            if (StringUtils.isNotBlank(outTradeNo)) {
                bizContent.put("out_trade_no", outTradeNo);
            }
//            if (StringUtils.isNotBlank(tradeNo)) {
//                bizContent.put("trade_no", tradeNo);
//            }
            request.setBizContent(bizContent.toJSONString());

            // 3. 调用接口并获取响应
            AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);
            if (response.isSuccess()) {
                // 4. 解析支付状态
                String tradeStatus = response.getTradeStatus();
                log.info("订单查询成功，支付状态：" + tradeStatus);

                // 支付状态说明：
                // WAIT_BUYER_PAY：等待买家付款
                // TRADE_CLOSED：交易关闭（超时未支付/已取消）
                // TRADE_SUCCESS：支付成功（即时到账/普通转账）
                // TRADE_FINISHED：交易完成（不可退款的场景，如即时到账）
                if ("TRADE_SUCCESS".equals(tradeStatus)) {
                    return R.success("支付成功");
                } else if ("TRADE_CLOSED".equals(tradeStatus)) {
                    return R.fail("交易已关闭");
                } else if ("WAIT_BUYER_PAY".equals(tradeStatus)) {
                    return R.fail("等待买家付款");
                } else if ("TRADE_FINISHED".equals(tradeStatus)) {
                    return R.success("交易完成");
                }
                return R.success("订单状态：" + tradeStatus);
            } else {
                return R.fail("订单查询失败：" + response.getMsg() + "(" + response.getSubMsg() + ")");
            }
        } catch (AlipayApiException e) {
            log.error("支付宝订单查询异常", e);
            return R.fail("查询异常：" + e.getMessage());
        }
    }

    // 保持原有方法以兼容旧调用
    public R<String> queryPayment(String outTradeNo) {
        return queryPayment(outTradeNo, null);
    }









}
