package com.fdkankan.platform.order.service;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.fdkankan.common.constant.ConstantFilePath;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.MD5;
import com.fdkankan.pay.alipay.AlipayDefaultConfig;
import com.fdkankan.pay.alipay.sdk.AlipayGoodsDetail;
import com.fdkankan.pay.alipay.sdk.AlipayService;
import com.fdkankan.pay.alipay.sdk.AlipayUtil;
import com.fdkankan.pay.alipay.sdk.AlipaymentEx;
import com.fdkankan.pay.paypal.sdk.PayPalmentEx;
import com.fdkankan.pay.paypal.sdk.PaypalService;
import com.fdkankan.pay.wx.WXPayDefaultConfig;
import com.fdkankan.pay.wx.sdk.WXPay;
import com.fdkankan.pay.wx.sdk.WXPayUtil;
import com.fdkankan.common.factory.LogFactory;
import com.paypal.api.payments.Links;
import com.paypal.api.payments.Payment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Service
public class PayOrderService {

    @Autowired
    private AlipayService alipayService;
    @Autowired
    private AlipayDefaultConfig alipayDefaultConfig;
    @Autowired
    private PaypalService paypalService;

    @Value("${main.url}")
    private String mainUrl;

    public JSONObject aliPayScanPay(String orderSn, String subject, String body, BigDecimal totalFee, List<AlipayGoodsDetail> goodsDetailList) throws Exception{
        AlipaymentEx alipaymentEx = new AlipaymentEx();
        alipaymentEx.setOutTradeNo(orderSn);
        alipaymentEx.setSubject(subject);
        alipaymentEx.setBody(body);
        alipaymentEx.setTotalAmount(totalFee);
        alipaymentEx.setStoreId("test_store_id");
        alipaymentEx.setOperatorId("test_operator_id");
        alipaymentEx.setTimeoutExpress("120m");
        alipaymentEx.setGoodsDetailList(goodsDetailList);
        String pngPath = ConstantFilePath.ALI_QRCODE_FOLDER + orderSn + ".png";
        try {
            Map<String, String> alipayMap = alipayService.tradePrecreate(alipaymentEx, mainUrl + alipayDefaultConfig.getNotifyUrl());
            if ("0".equals(alipayMap.get("code"))){
                BufferedImage image = AlipayUtil.getQRCodeImge(alipayMap.get("qr_code"));
                File file = new File(pngPath);
                if (file.exists()){
                    file.delete();
                }
                ImageIO.write(image, "png", file);
            }else{
                throw new BusinessException(ErrorCode.ERROR_MSG);
            }
        } catch (AlipayApiException e) {
            LogFactory.P_LOG.error(e.getMessage());
            throw new BusinessException(ErrorCode.ERROR_MSG);
        }

        JSONObject j = new JSONObject();
        j.put("src", pngPath.replace(ConstantFilePath.BASE_PATH, ""));
        j.put("price", totalFee);
        return j;
    }

    public JSONObject aliPayH5Pay(String orderSn, String subject, String body, BigDecimal totalFee) {
        // 超时时间 可空
        String timeoutExpress = "2m";
        // 销售产品码 必填
        String productCode = "QUICK_WAP_WAY";
        /**********************/
        // SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签
        //调用RSA签名方式，这个不用你管，只要你配置文件是正确的
        AlipayClient client = new DefaultAlipayClient(alipayDefaultConfig.getGatewayUrl(),
                alipayDefaultConfig.getAppid(), alipayDefaultConfig.getAppPrivateKey(), alipayDefaultConfig.getFormate(),
                alipayDefaultConfig.getCharset(), alipayDefaultConfig.getAlipayPublicKey(), alipayDefaultConfig.getSignType());
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        // 封装请求支付信息
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        //带！的都是你需要传递的参数 其他的是支付宝必须的
        //！本地生成的订单编号
        model.setOutTradeNo(orderSn);
        //！商品名称
        model.setSubject(subject);
        //！商品价格
        model.setTotalAmount(String.valueOf(totalFee));
        //！商品介绍
        model.setBody(body);
        //超时时间
        model.setTimeoutExpress(timeoutExpress);
        //产品销售码
        model.setProductCode(productCode);
        //将参数传入到 BizModel中
        alipayRequest.setBizModel(model);
        //异步回调地址
        alipayRequest.setNotifyUrl(mainUrl + alipayDefaultConfig.getNotifyUrl());
        //同步回调地址
        alipayRequest.setReturnUrl(mainUrl + alipayDefaultConfig.getReturnUrl());

        String result = "";
        try {
            // 调用SDK生成表单
            //get方式生成表单 主要解决在微信中对支付宝屏蔽问题，如果不是在微信中可post提交，将form的注释解开，result注释掉即可
            result = client.pageExecute(alipayRequest, "get").getBody();
            LogFactory.P_LOG.warn("支付宝调用SDK生成表单：" + result);
            //form = client.pageExecute(alipay_request).getBody();
//                System.out.println(form);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            LogFactory.P_LOG.error("生成表单失败！");
        }
        JSONObject j = new JSONObject();
        j.put("form", result);
        return j;
    }

    public JSONObject payPalPay(String orderSn, String subject, String body, BigDecimal totalFee, BigDecimal goodsFee, String successUrl, String cancelUrl) throws Exception {
        PayPalmentEx payPalmentEx = new PayPalmentEx();
        payPalmentEx.setOrderSn(orderSn);
        payPalmentEx.setOrderTotal(totalFee);
        payPalmentEx.setSubTotal(goodsFee);
        payPalmentEx.setDescription(body);

        Payment payment = paypalService.createPayment(payPalmentEx, successUrl, cancelUrl);
        for(Links links : payment.getLinks()){
            if(links.getRel().equals("approval_url")){
                // 客户付款登陆地址
                JSONObject j = new JSONObject();
                j.put("redirect", links.getHref());
                j.put("price", totalFee);
                return j;
            }
        }
        throw new BusinessException(ErrorCode.FAILURE_CODE_8002);
    }

    public JSONObject wechatScanPay(String orderSn, String subject, String body, BigDecimal totalFee) throws Exception {
        WXPayDefaultConfig config = new WXPayDefaultConfig();
        WXPay wxPay = new WXPay(config);

        Map<String, String> data = new HashMap<String, String>();
        data.put("body", body);
        data.put("detail", subject);
        data.put("out_trade_no", orderSn + "_" + new Random().nextInt(100));
        data.put("device_info", "WEB");
        data.put("fee_type", "CNY");
        data.put("total_fee", totalFee.stripTrailingZeros().toPlainString());
        data.put("spbill_create_ip", config.getCreateIP());
        data.put("notify_url", mainUrl + config.getNotifyURL());
        data.put("trade_type", "NATIVE");  // 此处指定为扫码支付
        data.put("product_id", orderSn); //多个商品，使用订单号

        String pngPath = ConstantFilePath.WEIXIN_QRCODE_FOLDER + orderSn + ".png";
        try {
            //发起支付
            Map<String, String> resp = wxPay.unifiedOrder(data);
            BufferedImage image = AlipayUtil.getQRCodeImge(resp.get("code_url"));
            File file = new File(pngPath);
            if (file.exists()){
                file.delete();
            }
            ImageIO.write(image, "png", file);
        } catch (Exception e) {
            LogFactory.P_LOG.error(e.getMessage());
            throw new BusinessException(ErrorCode.ERROR_MSG);
        }
        JSONObject j = new JSONObject();
        j.put("src", pngPath.replace(ConstantFilePath.BASE_PATH, ""));
        j.put("price", totalFee.divide(new BigDecimal("100"), 2));
        return j;
    }

    public JSONObject wechatH5Pay(String orderSn, String subject, String body, BigDecimal totalFee, String ipAddress) throws Exception {
        LogFactory.P_LOG.warn("ipAddress:"+ipAddress);
        WXPayDefaultConfig config = new WXPayDefaultConfig();
        WXPay wxPay = new WXPay(config);

        Map<String, String> data = new HashMap<String, String>();
        data.put("body", subject);
        data.put("detail", body);
        data.put("out_trade_no", orderSn + "_" + new Random().nextInt(100));
        data.put("device_info", "H5");
        data.put("fee_type", "CNY");
        data.put("total_fee", totalFee.stripTrailingZeros().toPlainString());
        data.put("spbill_create_ip", ipAddress);
        data.put("notify_url", mainUrl + config.getNotifyURL());
        data.put("trade_type", "MWEB");  // 此处指定为扫码支付
        data.put("product_id", orderSn); //多个商品，使用订单号
        data.put("nonce_str", MD5.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes()));

        String mweb_url = "";
        Map<String, String> resp = wxPay.unifiedOrder(data);
        LogFactory.P_LOG.warn("wechatH5Pay" + resp);
        String return_code = resp.get("return_code");
        String return_msg = resp.get("return_msg");
        if ("SUCCESS".equals(return_code) && "OK".equals(return_msg)) {
            mweb_url = resp.get("mweb_url");//调微信支付接口地址
            mweb_url += "&redirect_url=" + URLEncoder.encode(mainUrl + config.getH5RedirectURL(), "UTF-8");
            LogFactory.P_LOG.warn("mweb_url=" + mweb_url);
        } else {
            LogFactory.P_LOG.error("微信统一支付接口获取预支付订单出错");
        }
        JSONObject j = new JSONObject();
        j.put("mweb_url", mweb_url);
        return j;
    }

    public Map<String, String> wechatPay(String orderSn, String subject, String body, BigDecimal totalFee, String ipAddress, String openid) throws Exception {
        WXPayDefaultConfig config = new WXPayDefaultConfig();
        WXPay wxPay = new WXPay(config);

        Map<String, String> data = new HashMap<String, String>();
        data.put("body", subject);
        data.put("detail", body);
        data.put("out_trade_no", orderSn + "_" + new Random().nextInt(100));
        data.put("device_info", "wechat");
        data.put("fee_type", "CNY");
        data.put("total_fee", totalFee.stripTrailingZeros().toPlainString());
        data.put("spbill_create_ip", ipAddress);
        data.put("notify_url", mainUrl + config.getNotifyURL());
        data.put("trade_type", "JSAPI");
        data.put("product_id", orderSn);
        data.put("openid", openid);

        Map<String, String> resp = wxPay.unifiedOrder(data);
        LogFactory.P_LOG.warn("wechatPay" + resp);

        Map<String, String> sign = new HashMap<>();
        sign.put("package", "prepay_id="+resp.get("prepay_id"));
        sign.put("appId", config.getAppID());
        sign.put("timeStamp",String.valueOf(System.currentTimeMillis() / 1000));
        sign.put("nonceStr", resp.get("nonce_str"));
        sign.put("signType", "MD5");
        String paySign = WXPayUtil.generateSignature(sign, config.getKey());

        resp.put("signType", "MD5");
        resp.put("paySign", paySign);
        LogFactory.P_LOG.warn("wechatPay" + resp);
        return resp;
    }

}
