package com.izouma.dingdong.web;

import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.izouma.dingdong.exception.BusinessException;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/wx")
public class WxController {
    private WxMpService  wxMpService;
    private WxPayService wxPayService;
    private Environment  env;

    @RequestMapping("/testMp")
    public ModelAndView testPay(@RequestParam(required = false) String code, HttpServletRequest request,
                                HttpServletResponse response) throws IOException {
        try {
            WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
            WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, null);
            ModelAndView mav = new ModelAndView("WxMpTest");
            mav.addObject("user", wxMpUser);
            return mav;
        } catch (WxErrorException e) {
            String url = wxMpService.oauth2buildAuthorizationUrl(env.getProperty("general.host")
                    + request.getServletPath(), "snsapi_userinfo", null);
            log.info("微信重定向: {}", url);
            response.sendRedirect(url);
        }
        ModelAndView mav = new ModelAndView("Error");
        mav.addObject("title", "redirect");
        mav.addObject("body", "redirect");
        return mav;
    }

    @GetMapping("/testPay")
    public WxPayMpOrderResult testPayApi(@RequestParam String openId, @RequestParam Integer totalFee) {
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        request.setBody("测试微信支付");
        request.setDetail("测试微信支付");
        request.setOutTradeNo(RandomStringUtils.randomAlphanumeric(32));
        request.setTotalFee(totalFee);
        request.setSpbillCreateIp("180.102.110.170");
        request.setNotifyUrl(env.getProperty("wx.pay.notifyUrl"));
        request.setTradeType(WxPayConstants.TradeType.JSAPI);
        request.setOpenid(openId);
        request.setSignType("MD5");
        try {
            return wxPayService.createOrder(request);
        } catch (WxPayException e) {
            log.error("unifiedOrder error", e);
            throw new BusinessException(e.getMessage());
        }
    }

    @GetMapping("/greet")
    public String greetUser(@RequestParam String code) {
        try {
            WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
            WxMpUser user = wxMpService.oauth2getUserInfo(accessToken, null);
            return user.getNickname();
        } catch (WxErrorException e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }

    @GetMapping("/getCode")
    public String getCode(@RequestParam String code) {
        return code;
    }

    @GetMapping("/redirect")
    public void redirect(HttpServletResponse response, @RequestParam String redirectUrl) throws IOException {
        String url = wxMpService.oauth2buildAuthorizationUrl(redirectUrl, "snsapi_userinfo", null);
        log.info("微信重定向: {}", url);
        response.sendRedirect(url);
    }

    @PostMapping(value = "/payNotify", produces = "application/xml")
    public String wxNotify(@RequestBody String xmlData) throws WxPayException {
        log.info("微信支付回调: {}", xmlData);
        final WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
        notifyResult.checkResult(wxPayService, "MD5", true);
        JSONObject attach = JSONObject.parseObject(notifyResult.getAttach());
        String type = attach.getString("type");
        switch (type) {
        }
        return WxPayNotifyResponse.success("OK");
    }

    @PostMapping(value = "/refundNotify", produces = "application/xml")
    public String refundNotify(@RequestBody String xmlData) throws WxPayException {
        log.info("微信退款回调: {}", xmlData);
        final WxPayRefundNotifyResult notifyResult = wxPayService.parseRefundNotifyResult(xmlData);
        notifyResult.checkResult(wxPayService, "MD5", true);
        return WxPayNotifyResponse.success("OK");
    }

    @GetMapping("/jsapiSign")
    @ApiOperation(value = "jsapi签名")
    public WxJsapiSignature sign(@RequestParam String url) throws WxErrorException {
        return wxMpService.createJsapiSignature(url);
    }
}
