package com.bcxin.ins.weixin.web;

import com.alibaba.fastjson.JSONObject;
import com.bcxin.ins.weixin.util.weixin.process.WechatProcess;

import com.bcxin.ins.weixin.util.weixin.service.WeiXinService;
import com.bcxin.ins.weixin.util.weixin.util.AccessToken;
import com.bcxin.ins.weixin.util.weixin.util.ConstantWeiXin;
import com.bcxin.ins.weixin.util.weixin.util.SignUtil;
import com.bcxin.ins.weixin.util.weixin.util.WeixinUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * liyongqiang
 * 微信验证模块
 * 2017-8-17
 */
@Controller
@RequestMapping("weixin/token")
public class WeiXinController {


    @Autowired
    private WeiXinService weiXinService;


    /**
     * 微信验证
     * 收/发送信息
     */
    @RequestMapping("serial")
    @ResponseBody
    public void serial(HttpServletRequest request, HttpServletResponse response) {
        // 将请求、响应的编码均设置为UTF-8（防止中文乱码）
        try {
            //微信服务器POST消息时用的是UTF-8编码，在接收时也要用同样的编码，否则中文会乱码；
            request.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //在响应消息（回复消息给用户）时，也将编码方式设置为UTF-8，原理同上；
        response.setCharacterEncoding("UTF-8");
        String signature = request.getParameter("signature");        // 随机字符串
        String echostr = request.getParameter("echostr");        // 时间戳
        String timestamp = request.getParameter("timestamp");        // 随机数
        String nonce = request.getParameter("nonce");

        // 确认请求来至微信
        if (SignUtil.checkSignature(ConstantWeiXin.TOKEN, signature, timestamp, nonce)) {
            /** 读取接收到的xml消息 */
            StringBuffer sb = new StringBuffer();
            try(InputStream is = request.getInputStream();
                InputStreamReader isr = new InputStreamReader(is, "UTF-8");) {
                PrintWriter out = response.getWriter();
                BufferedReader br = new BufferedReader(isr);
                String s = "";
                while ((s = br.readLine()) != null) {
                    sb.append(s);
                }
                //次即为接收到微信端发送过来的xml数据
                String xml = sb.toString();
                String result = "";
                /** 判断是否是微信接入激活验证，只有首次接入验证时才会收到echostr参数，此时需要把它直接返回 */
                if (echostr != null && echostr.length() > 1) {
                    result = echostr;
                } else {
                    //正常的微信处理流程
                    result = new WechatProcess().processWechatMag(xml,weiXinService);
                }
                response.setContentType("application/xml;charset=UTF-8");
                out.print(result);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @RequestMapping("wechatParam")
    @ResponseBody
    public Map<String, String> getWechatParam(String hostUrl){

//        hostUrl="http://justme070.xicp.net";
        AccessToken at = weiXinService.getAccessToken();
        String url = ConstantWeiXin.APITICKETURL.replace("ACCESS_TOKEN", at.getToken());

        JSONObject jsApiTicket = WeixinUtil.httpRequest(url, "GET", null);
        String ticket=jsApiTicket.getString("ticket");
        //生成微信权限验证的参数
        Map<String, String> wechatParam= makeWXTicket(ticket,hostUrl);
        System.out.printf(wechatParam.toString());
        return wechatParam;
        //return wechatParam;
    }


    //生成微信权限验证的参数
    public Map<String, String> makeWXTicket(String jsApiTicket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonceStr = createNonceStr();
        String timestamp = createTimestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + jsApiTicket +
                "&noncestr=" + nonceStr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());

        }catch (Exception ex){
            ex.printStackTrace();
        }
        ret.put("url", url);
        ret.put("jsapi_ticket", jsApiTicket);
        ret.put("nonceStr", nonceStr);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appid", ConstantWeiXin.CORPID);
        return ret;
    }


    //字节数组转换为十六进制字符串
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
    //生成随机字符串
    private static String createNonceStr() {
        return UUID.randomUUID().toString();
    }
    //生成时间戳
    private static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }








}
