package com.izouma.nineth.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.izouma.nineth.config.Constants;
import com.izouma.nineth.config.GeneralProperties;
import com.izouma.nineth.config.WxPayProperties;
import com.izouma.nineth.domain.Order;
import com.izouma.nineth.domain.PaymentInfo;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.repo.OrderRepo;
import com.izouma.nineth.repo.PaymentInfoRepo;
import com.izouma.nineth.service.pay.PayHelper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.collections.MapUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 微信支付服务
 */
@Service
@AllArgsConstructor
@Slf4j
public class WeixinService {

    private GeneralProperties generalProperties;

    private WxPayService wxPayService;
    private PayHelper payHelper;

    private WxPayProperties wxPayProperties;

    private PaymentInfoRepo paymentInfoRepo;


    public Object payOrderWeixin(PaymentInfo paymentInfo, String clientIp, String openId) throws Exception {
        String tradeType = WxPayConstants.TradeType.MWEB;
        int totalFee =  paymentInfo.getPayAmt().multiply(BigDecimal.valueOf(100)).intValue();
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        request.setBody(paymentInfo.getGoodsTitle());
        request.setOutTradeNo(paymentInfo.getOrderNo());
        request.setTotalFee(totalFee);
        //request.setSpbillCreateIp("180.102.110.170");
        request.setSpbillCreateIp(clientIp);
        request.setNotifyUrl(paymentInfo.getNotifyUrl());
        request.setTradeType(tradeType);
        request.setOpenid(openId);
        request.setSignType("MD5");
        JSONObject body = new JSONObject();
        body.put("userId", paymentInfo.getUserId());
        body.put("orderId", paymentInfo.getOrderId());
        body.put("giftOrderId", paymentInfo.getGiftOrderId());
        request.setAttach(body.toJSONString());
        if (WxPayConstants.TradeType.MWEB.equals(tradeType)) {
            WxPayMwebOrderResult result = wxPayService.createOrder(request);
            String returnUrl = payHelper.resolveReturnUrl(paymentInfo);
            return result.getMwebUrl() + "&redirect_url=" + new URLCodec().encode(returnUrl);
        } else if (WxPayConstants.TradeType.JSAPI.equals(tradeType)) {
            return wxPayService.<WxPayMpOrderResult>createOrder(request);
        }

        throw new BusinessException("不支持此付款方式");

    }


    /**
     * 退款
     * @param orderNo
     * @param refundOrderNo
     * @return
     * @throws WxPayException
     */
    public WxPayRefundResult refund(String orderNo, String refundOrderNo, String refundReason) throws WxPayException {
        PaymentInfo paymentInfo = paymentInfoRepo.findByOrderNo(orderNo).orElseThrow(new BusinessException("支付信息不存在"));
        int totalFee = paymentInfo.getPayAmt().multiply(BigDecimal.valueOf(100)).intValue();
        String notifyUrl = payHelper.resolveRefundNotifyUrl(orderNo);
        WxPayRefundRequest request = new WxPayRefundRequest();
        request.setOutTradeNo(paymentInfo.getOrderNo());
        request.setTransactionId(paymentInfo.getTransactionId());
        request.setTotalFee(totalFee);
        request.setRefundFee(totalFee);
        request.setRefundDesc(refundReason);
        request.setOutRefundNo(refundOrderNo);
        request.setNotifyUrl(notifyUrl);

        WxPayRefundResult response = wxPayService.refund(request);
        return response;

    }

    /**
     * 退款通知响应
     * @param reqBody
     * @return
     */
    public String refundNotify(String  orderNo, String reqBody) throws Exception{
        throw new BusinessException("不支持的操作");
    }


}
