package com.fzm.mall.server.front.repo.wxpay;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fzm.mall.server.front.asset.model.OrderPay;
import com.fzm.mall.server.front.constant.MALLGlobalConfig;
import com.fzm.mall.server.front.order.service.IDeliveryService;
import com.fzm.mall.server.front.order.service.IOrderService;
import com.fzm.mall.server.front.repo.wxpay.wxpaysdk.WXPay;
import com.fzm.mall.server.front.repo.wxpay.wxpaysdk.WXPayConstants;
import com.fzm.mall.server.front.repo.wxpay.wxpaysdk.WXPayConstants.SignType;
import com.fzm.mall.server.front.repo.wxpay.wxpaysdk.WXPayUtil;
import com.fzm.mall.server.front.util.UUIdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
@RequestMapping("/xls/newwxpay")
public class NewWxpayController {
	@Autowired
	private MyWxpayConfig wxpayConfig;
	private WXPay wxPay;
	@Autowired
	private IDeliveryService deliveryService;

	@Value("${wxpay.postfee-url}")
	private String postFeeUrl;

	@Value("${wxpay.pay-notify-url}")
	private String payNotifyUrl;

	@Value("${alipay.quit-url}")
	private String quitUrl;

	@PostConstruct
	private void initWxPay() {
		try {
			wxPay = new WXPay(wxpayConfig, null, false, false);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@PostMapping("/without/payPostFee")
	public String payPostFee(@RequestBody String resXml) {
		try {
			Map<String, String> resMap = WXPayUtil.xmlToMap(resXml);
			// 验签
			if (wxPay.isPayResultNotifySignatureValid(resMap, WXPayConstants.SignType.HMACSHA256)) {
				String outTradeNo = resMap.get("out_trade_no");
				// 微信支付订单号
				String txId = resMap.get("transaction_id");
				log.error("wx.payPostFee:" + outTradeNo);
				String returnCode = resMap.get("return_code");
				if (!MALLGlobalConfig.WXPAY_SUCCESS.equals(returnCode)) {
					// 错误信息
					String returnMsg = resMap.get("return_msg");
					// 支付失败，关闭订单
					Map<String, String> closeData = new HashMap<>();
					closeData.put("out_trade_no", outTradeNo);
					wxPay.closeOrder(closeData);
				} else {
					deliveryService.paymentsPostFee(outTradeNo, txId, 2);
				}

				return MALLGlobalConfig.WXPAY_RES_SUCCESS;
			} else {
				log.error("wx.payPostFee.resMap:" + resMap);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return MALLGlobalConfig.WXPAY_RES_FAIL;
	}

	public String payPostFee(OrderPay payResult, String ip) {
		if (payResult.getTotal().compareTo(BigDecimal.ZERO) == 0) {
			try {
				deliveryService.paymentsPostFee(payResult.getPayId(), "", 2);
				return "success";
			} catch (Exception e) {
				return "fail";
			}
		}
		Map<String, String> data = new HashMap<String, String>();
		String outTradeNo = UUIdUtil.getUUID();
		JSONObject sceneInfoObj = new JSONObject();
		JSONObject h5Info = new JSONObject();
		h5Info.put("wap_url", "http://xls.huowulian365.com");
		h5Info.put("wap_name", "泽坤-新零售");
		sceneInfoObj.put("h5_info", h5Info);
		String total = payResult.getTotal().multiply(BigDecimal.valueOf(100)).setScale(0).toPlainString();
		System.out.println(total);
		data.put("body", "快递费测试 0.01");
		data.put("out_trade_no", payResult.getPayId());
		data.put("total_fee", total);
		data.put("spbill_create_ip", ip);
		data.put("scene_info", JSONObject.toJSONString(sceneInfoObj));
		data.put("trade_type", "APP");
		data.put("notify_url", postFeeUrl);
		data.put("limit_pay", "no_credit");
		try {
			Map<String, String> resMap = wxPay.unifiedOrder(data);
			log.info(JSONObject.toJSONString(resMap));
			String returnCode = resMap.get("return_code");
			if (!MALLGlobalConfig.WXPAY_SUCCESS.equals(returnCode)) {
				return "error";
			}

			String resultCode = resMap.get("result_code");
			if (!MALLGlobalConfig.WXPAY_SUCCESS.equals(resultCode)) {
				return "error";
			}

			// mweb_url的有效期为5分钟
			String mwebUrl = resMap.get("mweb_url");
			String redirectUrl = URLEncoder.encode(wxpayConfig.getReturnUrl() + outTradeNo, "GBK");
			Map<String, String> chooseWXPay = new HashMap<>();
			/* 这里的key值都是小写的，而JSAPI是驼峰式写法 */
			chooseWXPay.put("appid", resMap.get("appid"));
			chooseWXPay.put("partnerid", resMap.get("mch_id"));
			chooseWXPay.put("prepayid", resMap.get("prepay_id"));
			chooseWXPay.put("package", "Sign=WXPay");
			chooseWXPay.put("noncestr", resMap.get("nonce_str"));
			chooseWXPay.put("timestamp", LocalDateTime.now().getSecond() + ""); // 秒
			String signature = WXPayUtil.generateSignature(chooseWXPay, wxpayConfig.getKey(),
					WXPayConstants.SignType.HMACSHA256);
			chooseWXPay.put("sign", signature);
			chooseWXPay.put("returnUrl", wxpayConfig.getReturnUrl() + payResult.getPayId());
			chooseWXPay.put("quitUrl", quitUrl);
			return JSON.toJSONString(chooseWXPay);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return "err";
	}

	@PostMapping("/pay")
	public String pay() {
		Map<String, String> data = new HashMap<String, String>();
		String outTradeNo = UUIdUtil.getUUID();

		JSONObject sceneInfoObj = new JSONObject();
		JSONObject h5Info = new JSONObject();
		h5Info.put("wap_url", "http://xls.huowulian365.com");
		h5Info.put("wap_name", "泽坤-新零售");
		sceneInfoObj.put("h5_info", h5Info);
		String total = "";
		System.out.println(total);
		data.put("body", "数字酒商品");
		data.put("out_trade_no", "");
		data.put("total_fee", total);
		data.put("spbill_create_ip", "");
		data.put("scene_info", JSONObject.toJSONString(sceneInfoObj));
		data.put("trade_type", "APP");
		data.put("notify_url", payNotifyUrl);
		data.put("limit_pay", "no_credit");

		try {
			Map<String, String> resMap = wxPay.unifiedOrder(data);
			log.info(JSONObject.toJSONString(resMap));
			String returnCode = resMap.get("return_code");
			if (!MALLGlobalConfig.WXPAY_SUCCESS.equals(returnCode)) {
				return "error";
			}

			String resultCode = resMap.get("result_code");
			if (!MALLGlobalConfig.WXPAY_SUCCESS.equals(resultCode)) {
				return "error";
			}

			// mweb_url的有效期为5分钟
			String mwebUrl = resMap.get("mweb_url");
			String redirectUrl = URLEncoder.encode(wxpayConfig.getReturnUrl() + outTradeNo, "GBK");
			Map<String, String> chooseWXPay = new HashMap<>();
			/* 这里的key值都是小写的，而JSAPI是驼峰式写法 */
			chooseWXPay.put("appid", resMap.get("appid"));
			chooseWXPay.put("partnerid", resMap.get("mch_id"));
			chooseWXPay.put("prepayid", resMap.get("prepay_id"));
			chooseWXPay.put("package", "Sign=WXPay");
			chooseWXPay.put("noncestr", resMap.get("nonce_str"));
			chooseWXPay.put("timestamp", (System.currentTimeMillis() / 1000) + ""); // 秒
			System.out.println(LocalDateTime.now().getSecond() + "");
			String signature = WXPayUtil.generateSignature(chooseWXPay, wxpayConfig.getKey(),
					SignType.HMACSHA256);
			chooseWXPay.put("sign", signature);
			chooseWXPay.put("returnUrl", wxpayConfig.getReturnUrl());
			chooseWXPay.put("quitUrl", quitUrl);
			return JSON.toJSONString(chooseWXPay);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return "err";
	}

	// 具体回调参数 https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_7&index=8
	@PostMapping("/without/payNotify")
	public String payNotify(@RequestBody String resXml) {
		try {
			Map<String, String> resMap = WXPayUtil.xmlToMap(resXml);
			// 验签
			if (wxPay.isPayResultNotifySignatureValid(resMap, SignType.HMACSHA256)) {
				String outTradeNo = resMap.get("out_trade_no");
				// 微信支付订单号
				String txId = resMap.get("transaction_id");

				String returnCode = resMap.get("return_code");
				if (!MALLGlobalConfig.WXPAY_SUCCESS.equals(returnCode)) {
					// 错误信息
					String returnMsg = resMap.get("return_msg");
					// 支付失败，关闭订单
					Map<String, String> closeData = new HashMap<>();
					closeData.put("out_trade_no", outTradeNo);
					wxPay.closeOrder(closeData);
				} else {

				}

				return MALLGlobalConfig.WXPAY_RES_SUCCESS;
			} else {
				log.error("验签失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return MALLGlobalConfig.WXPAY_RES_FAIL;
	}

	@PostMapping("/refund")
	public String refund(@RequestParam String outTradeNo, @RequestParam String txId) {
		Map<String, String> data = new HashMap<>();
		String outRefundNo = UUIdUtil.getUUID();

		// outTradeNo 和 txId 二选一
		data.put("outTradeNo", outTradeNo);
		// data.put("transaction_id", txId);

		data.put("out_refund_no", outRefundNo);
		data.put("total_fee", "0");
		data.put("refund_fee", "0");
		data.put("notify_url", wxpayConfig.getRefundNotifyUrl());

		return "error";
	}

	@PostMapping("/query")
	public void query(@RequestParam String outTradeNo) {
		Map<String, String> data = new HashMap<>();
		data.put("out_trade_no", outTradeNo);

		try {
			// 查询订单
			Map<String, String> res = wxPay.orderQuery(data);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@PostMapping("/refundNotify")
	public String refundNotify(@RequestBody String resXml) {
		return MALLGlobalConfig.WXPAY_RES_SUCCESS;
	}

	// 生成沙箱密钥
	@PostMapping("genSandSignKey")
	public void genSandSignKey() throws Exception {
		HashMap<String, String> data = new HashMap<String, String>();
		// 商户号
		data.put("mch_id", wxpayConfig.getMchID());
		// 获取随机字符串
		data.put("nonce_str", WXPayUtil.generateNonceStr());
		// 生成签名
		String sign = WXPayUtil.generateSignature(data, wxpayConfig.getKey());
		data.put("sign", sign);

		String result = wxPay.requestWithoutCert("/sandboxnew/pay/getsignkey", data, 10000, 10000);
		log.info(result);
	}


}
