package com.lightinit.hsdataportal.controller;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.lightinit.hsdataportal.WXsdk.*;
import com.lightinit.hsdataportal.dictionary.DicPayResult;
import com.lightinit.hsdataportal.dictionary.DicWXPayInfo;
import com.lightinit.hsdataportal.entity.Order;
import com.lightinit.hsdataportal.model.ResultState;
import com.lightinit.hsdataportal.service.IAlipayService;
import com.lightinit.hsdataportal.service.IWXPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

import static com.google.zxing.client.j2se.MatrixToImageWriter.toBufferedImage;

@Controller
@RequestMapping("/wxpay")
public class WXPayController {

    private static Logger logger = LoggerFactory.getLogger(WXPayController.class);

    @Autowired
    private IWXPayService wxPayService ;

    @Autowired
    private IAlipayService alipayService;

    /**
     * @return 支付
     */
//    @RequestMapping(value = "wxpay.htm")
//    public ModelAndView register() {
//        ModelAndView modelAndView = new ModelAndView("pay/wxpay");
//        return  modelAndView;
//    }

    /**
     * 调用预支付并生成订单
     */
    @RequestMapping("/orderPay.action/{orderNumber}")
    @ResponseBody
    public Map orderPay(HttpServletRequest request,@PathVariable String orderNumber,HttpServletResponse response) throws Exception {
        Order order=wxPayService.queryUserOrderByOrderNumber(orderNumber);
        WXPay wxPay = new WXPay(new MyPayConfig());
        try {
            //获取预支付token
            Map<String, String> payParams = MyWXUtils.getPrepayid(orderNumber, order,MyWXUtils.getRemoteHost(request));
            Map<String, String> result = wxPay.unifiedOrder(payParams);
            logger.info("test = {}", result);
            //获取二维码URL
            String code_url = result.get("code_url");
            //根据url生成二维码
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            // 设置二维码参数
            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            BitMatrix bitMatrix = multiFormatWriter.encode(code_url, BarcodeFormat.QR_CODE, 300, 300, hints);
            BufferedImage image = toBufferedImage(bitMatrix);
            //注意此处拿到字节数据
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            byte[] bytes = os.toByteArray();
            //Base64编码
            String base64String = Base64.getEncoder().encodeToString(bytes);
            //返回二维码
//            MatrixToImageWriter.writeToStream(bitMatrix, "jpg", response.getOutputStream());
            Map<String, String> resMap = new HashMap<>();
            logger.info("test = {}", WXPayUtil.getCurrentTimestamp());
            resMap.put("code", "000000");
            resMap.put("qrcode", base64String);
            return resMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }






    /**
     * 异步修改订单支付状态
     */
    @RequestMapping("/notify.action")
    @ResponseBody
    public String updateOrderState(HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        logger.info("-------------------门户网站支付异步回调开始---------------------");
        //取出通知参数
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        Map<String, String> result = WXPayUtil.xmlToMap(sb.toString()) ;
        String orderNumber = result.get("out_trade_no");
        String sign = result.get("out_trade_no") ;
        Order order=wxPayService.queryUserOrderByOrderNumber(orderNumber);
        //验证签名
        Map<String, String> payParams = MyWXUtils.getPrepayid(orderNumber, order, MyWXUtils.getRemoteHost(request));
        payParams.put("sign",sign) ;
        Boolean falg = WXPayUtil.isSignatureValid(payParams, DicWXPayInfo.KEY, WXPayConstants.SignType.MD5);
        logger.info("falg={}", falg);
        if (falg) {
            logger.info("-----------成功修改订单状态！---------------");
            //修改数据库付款状态
            ResultState<String> resultState = alipayService.updateUserOderByOrderNumber(order.getId(),order.getOrderNumber());
            if(resultState.getStateCode()!=200){
                logger.error(resultState.getMsg());
                return DicPayResult.UPDATE_FAIL;
            }
            logger.info("-----------成功修改订单状态！---------------");
            return DicPayResult.UPDATE_SUCCESS;
        }else {
            logger.info("-----------修改订单状态时，签名验证未通过！---------------");
            return DicPayResult.UPDATE_FAIL;
        }
    }

    /**
     * 时刻查询订单状态
     */
    @RequestMapping("/selectFalgType.action/{orderNumber}")
    @ResponseBody
    public String selectFalgType(@PathVariable String orderNumber) {
        Order order=wxPayService.queryUserOrderByOrderNumber(orderNumber);
        return order.getOrderState();
    }
    @RequestMapping(value = "success.htm")
    public ModelAndView success(){
        ModelAndView modelAndView = new ModelAndView("open/pay/feedback") ;
        return modelAndView ;
    }
}
