package com.gree.mall.miniapp.controller.common;

import cn.hutool.json.JSONUtil;
import com.gree.mall.miniapp.annotation.ApiNotAuth;
import com.gree.mall.miniapp.logic.common.EventLogic;
import com.gree.mall.miniapp.logic.common.outside.WechatLogic;
import com.gree.mall.miniapp.utils.CommonUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

@Slf4j
@RestController
@Api(value = "事件通知", tags ={"事件通知"} )
@RequestMapping(value = "/event", produces = "application/json; charset=utf-8")
public class EventController {

    @Resource
    EventLogic eventLogic;
    @Autowired
    WechatLogic wechatLogic;

    @ApiNotAuth
    @PostMapping("/receive")
    @ApiOperation(value = "接收", notes = "接收 ", httpMethod = "POST")
    public String receive(@RequestBody String body,
                          HttpServletRequest request
    ) throws Exception {

        checkCallbackSign(request);

        Map<String, String> params = CommonUtils.doXMLParse(body);

        String event = params.get("Event");
        String appid = request.getParameter("appid");
        String toUser = params.get("ToUserName");
        String fromUserName = params.get("FromUserName");
        int createTime = Integer.parseInt(params.get("CreateTime"));

        log.info("appid:"+appid+"Post微信公众号事件消息" + JSONUtil.toJsonStr(params));

        if (event.equals("subscribe") || event.equals("SCAN")) {
            eventLogic.scanBringQrcode(params,appid);

        }
        //回复文本消息
        if(event.equals("subscribe")){
            //这里传参没返，因为是回复，所以互调了
            String returnText = eventLogic.receText(fromUserName,toUser,appid,createTime);

            log.info("【回复公众号】:{}",returnText);
            return returnText;
        }

        return "";
    }

    @ApiNotAuth
    @ApiOperation("微信公众号认证入口")
    @GetMapping(value = "/receive")
    public void receiveGet(HttpServletRequest request,
                             HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("utf-8");
        try {
            log.info("token验证");
            String echostr = request.getParameter("echostr");
            String appid = request.getParameter("appid");
            if (StringUtils.isBlank(echostr)) {
                throw new RuntimeException("无效的请求参数");
            }
            log.info("get微信公众号事件消息" + JSONUtil.toJsonStr(echostr)+",appid:"+appid);
            checkCallbackSign(request);
            out(response, echostr);

        } catch (Exception e) {
            log.error("微信公众号认证入口: ", e);
            out(response, "");
        }
    }

    private void checkCallbackSign(HttpServletRequest request)
            throws Exception {

        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        if (StringUtils.isBlank(signature) || StringUtils.isBlank(timestamp)
                || StringUtils.isBlank(nonce)) {

            throw new RuntimeException("无效的请求参数");
        }

        String checkSign = getCallbackSign(timestamp, nonce);
        if (!signature.equals(checkSign)) {
            throw new RuntimeException("无效的签名");
        }
    }

    private static String getCallbackSign(String timestamp, String nonce) {
        ArrayList<String> list = new ArrayList<String>();
        list.add(timestamp);
        list.add(nonce);
        list.add("zfiregejiang");

        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        String result = StringUtils.join(arrayToSort, "");
        result = DigestUtils.sha1Hex(result);
        return result;
    }

    private void out(HttpServletResponse response, String responseBody)
            throws IOException {

        response.setContentType("text/plain;charset=UTF-8");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        PrintWriter writer = response.getWriter();
        writer.write(responseBody);
        writer.flush();
        writer.close();
    }
}
