package com.iformall.controller.callback;

import com.alibaba.fastjson.JSON;
import com.iformall.controller.base.BaseController;
import com.iformall.domain.po.msg.FmInsideNotifyPaySuccessMsg;
import com.iformall.domain.po.msg.FmInsideNotifyRefundSuccessMsg;
import com.iformall.enums.*;
import com.iformall.exception.BizMessageException;
import com.iformall.exception.MallinkException;
import com.iformall.mq.MqBaseProducer;
import com.iformall.pay.WxPayment;
import com.iformall.service.WxPayOrderService;
import com.iformall.service.WxRefundOrderService;
import com.iformall.service.WxSubsidyService;
import com.iformall.utils.XmlUtil;
import org.apache.commons.io.IOUtils;
import org.jdom2.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

@RestController
@RequestMapping("/wxPay/notify")
public class WxPayController extends BaseController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
    private WxPayOrderService wxPayOrderService;

	@Autowired
    private WxSubsidyService wxSubsidyService;

	@Autowired
    private MqBaseProducer mqBaseProducer;
    /**
     *
     * @return 接收微信异步通知
     * @throws Exception 可能产生的任何异常
     */
    @RequestMapping(value = "/pay", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String _payNotify(HttpServletRequest request) throws IOException, JDOMException {
        logger.info("[" +getIpAddr() + "]微信支付回调");
        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);
        }
        String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8"));
        logger.info(resultxml);

        outSteam.close();
        inStream.close();

        Map<String, String> paramMap = null;

        try {
            paramMap = WxPayment.xmlToMap(resultxml);
            logger.info("微信支付回调, notify, param: " + paramMap.toString() );
            String response = wxPayOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP);
            logger.info("微信支付回调, notify success, req : " + resultxml);
            return response;
        } catch (BizMessageException e) {
            if (paramMap == null) {
                logger.error("微信支付回调, order create error, e: " + e.getMessage());
            } else {
                logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage());
            }
            SortedMap resultMap = new TreeMap<>();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (MallinkException e) {
            if (paramMap == null) {
                logger.error("微信支付回调, order create error, e: " + e.getMessage());
            } else {
                logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage());
            }
            SortedMap resultMap = new TreeMap<>();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (Exception e) {
            if (paramMap == null) {
                logger.error("微信支付回调, order create error, e: " + e.getMessage());
            } else {
                logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage());
            }
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        }
    }


    /**
     *
     * @return 接收微信退款异步通知
     * @throws Exception 可能产生的任何异常
     */
    @RequestMapping(value = "/refund")
    public String __refundNotify(HttpServletRequest request) throws Exception {
        logger.info("[" +getIpAddr() + "]微信退款回调");
        Map<String, String> paramMap = null;
        String response = "";
        String xml = "";
        try {
            xml = IOUtils.toString(request.getInputStream(),  Charset.forName("UTF-8"));
            logger.info(xml);
            paramMap = WxPayment.xmlToMap(xml);
            String jsonMsg = JSON.toJSONString(paramMap);

            FmInsideNotifyRefundSuccessMsg refundSuccessMsg = new FmInsideNotifyRefundSuccessMsg();
            refundSuccessMsg.setMsgType(EnumMsgRecordType.INSIDE_NOTIFY_REFUND_SUCCESS.getCode());
            refundSuccessMsg.setDelayTimeLevel(3);
            refundSuccessMsg.setPayWay(EnumPayWay.PAY_WAY_WEAPP.getCode());
            refundSuccessMsg.setJsonMsg(jsonMsg);

            // response = wxRefundOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP);
            mqBaseProducer.sendMessage(refundSuccessMsg, EnumMsgMqTopic.DEFAULT.getCode(), EnumMsgMqTag.DEFAULT.getCode(), EnumMsgMqKey.DEFAULT.getCode());

            logger.info("refund wxpay, notify success, req : " + xml + ", resp: " + response.toString());
            return response;
        } catch (BizMessageException e) {
            logger.error("refund wxpay, notify error, req: " + xml + ", e:" + e.getLocalizedMessage());
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (MallinkException e) {
            logger.error("refund wxpay, notify error, req: " + xml + ", e:" +e.getLocalizedMessage());
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (Exception e) {
            logger.error("refund wxpay, order create error, req: " + xml + ", e: " + e.getMessage());
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        }
    }

    /**
     *
     * @return 接收微信分账异步通知
     * @throws Exception 可能产生的任何异常
     */
    @RequestMapping(value = "/sharing")
    public String __shareNotify(HttpServletRequest request) throws Exception {
        logger.info("[" +getIpAddr() + "]微信分账回调");
        Map<String, String> paramMap = null;
        String response = "";
        String xml = "";
        try {
            xml = IOUtils.toString(request.getInputStream(),  Charset.forName("UTF-8"));
            paramMap = WxPayment.xmlToMap(xml);
            logger.info("share wxpay, notify, param: " + xml );
            response = wxPayOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP);
            logger.info("share wxpay, notify success, req : " + xml + ", resp: " + response.toString());
            return response;
        } catch (BizMessageException e) {
            logger.error("share wxpay, notify error, req: " + xml + ", e:" + e.getLocalizedMessage());
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (MallinkException e) {
            logger.error("refund wxpay, notify error, req: " + xml + ", e:" +e.getLocalizedMessage());
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (Exception e) {
            logger.error("refund wxpay, order create error, req: " + xml + ", e: " + e.getMessage());
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        }
    }

    /**
     *
     * @return 接收微信异步通知
     * @throws Exception 可能产生的任何异常
     */
    @RequestMapping(value = "/subsidyPay", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public String _subsidyPayNotify(HttpServletRequest request) throws IOException, JDOMException {
        logger.info("[" +getIpAddr() + "] 补贴微信支付回调");
        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);
        }
        String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8"));
        logger.info(resultxml);

        outSteam.close();
        inStream.close();

        Map<String, String> paramMap = null;

        try {
            paramMap = WxPayment.xmlToMap(resultxml);
            logger.info("微信支付回调, notify, param: " + paramMap.toString() );
            String response = wxSubsidyService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP);
            logger.info("微信支付回调, notify success, req : " + resultxml + ", resp: " + response.toString());
            return response;
        } catch (BizMessageException e) {
            if (paramMap == null) {
                logger.error("微信支付回调, order create error, e: " + e.getMessage());
            } else {
                logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage());
            }
            SortedMap resultMap = new TreeMap<>();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (MallinkException e) {
            if (paramMap == null) {
                logger.error("微信支付回调, order create error, e: " + e.getMessage());
            } else {
                logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage());
            }
            SortedMap resultMap = new TreeMap<>();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        } catch (Exception e) {
            if (paramMap == null) {
                logger.error("微信支付回调, order create error, e: " + e.getMessage());
            } else {
                logger.error("微信支付回调, order create error, req: " + resultxml + ", e: " + e.getMessage());
            }
            SortedMap resultMap = new TreeMap();
            resultMap.put("return_code", "FAIL");
            resultMap.put("return_msg", e.getMessage());
            return XmlUtil.getRequestXml(resultMap);
        }
    }
	
}
