package com.huiju.estateagents.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huiju.estateagents.base.BaseController;
import com.huiju.estateagents.base.ResponseBean;
import com.huiju.estateagents.common.wxpay.WXPayConstants;
import com.huiju.estateagents.common.wxpay.WXPayUtil;
import com.huiju.estateagents.entity.TaOrder;
import com.huiju.estateagents.entity.TaWxPayConfig;
import com.huiju.estateagents.service.ITaWxPayConfigService;
import com.huiju.estateagents.service.IWxPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api")
public class WxPayController extends BaseController {

    @Autowired
    private IWxPayService wxPayService;

    @Autowired
    private ITaWxPayConfigService taWxPayConfigService;

    /**
     * 微信统一下单接口
     * @param taOrder
     * @param request
     * @return
     */
    @RequestMapping(value = "/wx/unifiedOrder",method = RequestMethod.POST)
    public ResponseBean wxUnifiedOrder(@RequestBody TaOrder taOrder,
                                       HttpServletRequest request){
        ResponseBean responseBean = new ResponseBean();
        try {
            taOrder.setOrgId(getOrgId(request));
            taOrder.setPersonId(getPersonId(request));
            responseBean = wxPayService.payUnifiedOrder(taOrder,request.getRemoteAddr());
        } catch (Exception e) {
            log.error("微信统一下单失败： {}" , e.getMessage());
            return ResponseBean.error(e.getMessage(), ResponseBean.ERROR_MISSING_PARAMS);
        }
        return responseBean;
    }

    /**
     * 微信支付成功回调接口
     * @param type
     * @param request
     * @return
     */
    @RequestMapping(value = "/notify/{type}",method = RequestMethod.POST)
    public String wxNotify(@PathVariable String type, HttpServletRequest request){
        log.info("支付成功回调开始，支付类型是{}",type);
        String failResult = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[失败]]></return_msg>" + "</xml> ";
        String successResult = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
        Map<String, String> resultMap = new HashMap<>();
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }

            // 获取微信调用我们notify_url的返回信息
            String result = new String(outSteam.toByteArray(), "utf-8");
            log.info("wxnotify:微信支付----result----=" + result);

            // 关闭流
            outSteam.close();
            inStream.close();
            // xml转换为map
            resultMap = WXPayUtil.xmlToMap(result);
            //处理业务需求
            if (WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("result_code"))) {
                wxPayService.wxNotify(resultMap, type);
            }else {
                log.error("支付回调出错{}",resultMap.get("return_msg"));
                return failResult;
            }

        } catch (Exception e) {
            log.error("支付回调出错{}",e.getMessage());
            return failResult;
        }

        return successResult;
    }

    /**
     * 微信退款成功回调接口
     * @param type
     * @param request
     * @return
     */
    @RequestMapping(value = "/refund/{type}",method = RequestMethod.POST)
    public String wxRefund(@PathVariable String type, HttpServletRequest request){
        log.info("微信退款成功回调开始，退款类型是{}",type);
        String failResult = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[失败]]></return_msg>" + "</xml> ";
        String successResult = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
        Map<String, String> resultMap = new HashMap<>();
        try {
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }

            // 获取微信调用我们notify_url的返回信息
            String result = new String(outSteam.toByteArray(), "utf-8");
            log.info("wxnotify:微信退款----result----=" + result);

            // 关闭流
            outSteam.close();
            inStream.close();
            // xml转换为map
            resultMap = WXPayUtil.xmlToMap(result);
            //处理业务需求
            if (WXPayConstants.SUCCESS.equalsIgnoreCase(resultMap.get("return_code"))) {
                String mchId = resultMap.get("mch_id");
                QueryWrapper<TaWxPayConfig> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("mch_id",mchId);
                String mchKey = taWxPayConfigService.list(queryWrapper).get(0).getMchKey();
                log.info("key等于{}",mchKey);
                SecretKeySpec key = new SecretKeySpec(DigestUtils.md5Hex(mchKey).toLowerCase().getBytes(), "AES");
                Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
                cipher.init(Cipher.DECRYPT_MODE, key);
                String req_info = new String(cipher.doFinal(Base64.getDecoder().decode(resultMap.get("req_info"))), "UTF-8");
                log.info("req_info等于{}",req_info);
                Map<String, String> orderInfo = WXPayUtil.xmlToMap(req_info);
                wxPayService.houseRefund(orderInfo);
            }else {
                log.error("支付回调出错{}",resultMap.get("return_msg"));
                return failResult;
            }

        } catch (Exception e) {
            log.error("支付回调出错{}",e.getMessage());
            return failResult;
        }

        return successResult;
    }

    /**
     * 微信申请退款接口
     * @param taOrder
     * @param request
     * @return
     */
    @RequestMapping(value = "/admin/refund",method = RequestMethod.POST)
    public ResponseBean wxRefund(@RequestBody TaOrder taOrder,
                                       HttpServletRequest request){
        ResponseBean responseBean = new ResponseBean();
        try {
            wxPayService.payRefund(taOrder,getOrgId(request),getOrgId(request));
        } catch (Exception e) {
            log.error("微信批量退款失败： {}" , e.getMessage());
            return ResponseBean.error(e.getMessage(), ResponseBean.ERROR_MISSING_PARAMS);
        }
        responseBean.addSuccess(taOrder);
        return responseBean;
    }

    /**
     * 取消微信支付
     * @param taOrder
     * @param request
     * @return
     */
    @RequestMapping(value = "/wx/cancel",method = RequestMethod.POST)
    public ResponseBean wxCancel(@RequestBody TaOrder taOrder,
                                 HttpServletRequest request){
        ResponseBean responseBean = new ResponseBean();
        try {
            taOrder.setOrgId(getOrgId(request));
            taOrder.setPersonId(getPersonId(request));
            wxPayService.payCancel(taOrder);
        } catch (Exception e) {
            log.error("微信取消付款异常： {}" , e.getMessage());
            return ResponseBean.error(e.getMessage(), ResponseBean.ERROR_MISSING_PARAMS);
        }
        responseBean.addSuccess(taOrder);
        return responseBean;
    }
}
