package com.yeejoin.precontrol.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.util.StringUtil;
import com.yeejoin.precontrol.common.dto.small.WxMssDto;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.WechatRelation;
import com.yeejoin.precontrol.common.entity.WechatSendMessage;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.service.IPersonService;
import com.yeejoin.precontrol.common.service.IWechatRelationService;
import com.yeejoin.precontrol.common.service.IWechatSendMessageService;
import com.yeejoin.precontrol.common.service.SmallProService;
import com.yeejoin.precontrol.common.utils.HttpUtils;
import com.yeejoin.precontrol.common.utils.RedisUtil;
import com.yeejoin.precontrol.common.vo.ResponeVo;
import com.yeejoin.precontrol.controller.publics.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 项目信息
 *
 * @author duanwei
 * @date 2020-06-30
 */
@RestController
@Api(tags = "小程序控制层")
@RequestMapping(value = "/small", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Slf4j
public class SmallController extends BaseController {

    /**
     * 小程序appid
     */
    @Value("${smallProgram.appid}")
    private String appId;
    /**
     * 小程序secret
     */
    @Value("${smallProgram.secret}")
    private String secret;
    /**
     * 小程序grantType
     */
    @Value("${smallProgram.grant_type}")
    private String grantType;
    /**
     * 小程序secret
     */
    @Value("${smallProgram.tutorial_id}")
    private String tutorialId;
    /**
     * 公众号appid
     */
    @Value("${smallProgram.public.appid}")
    private String publicAppId;
    /**
     * 公众号secret
     */
    @Value("${smallProgram.public.secret}")
    private String publicSecret;
    /**
     * 小程序服务类
     */
    @Autowired
    SmallProService smallProService;

    @Autowired
    IPersonService iPersonService;

    @Autowired
    private IWechatSendMessageService wechatSendMessageService;

    @Autowired
    private IWechatRelationService wechatRelationService;

    @Autowired
    RedisUtil redisUtil;

    /**
     * 获取code
     * https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
     * 获取openId
     * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
     *
     * @return
     */
    @RequestMapping(value = "/getOpenId", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "通过code换 请求openId链接", notes = "通过code换 请求openId链接")
    public Object exchangeSmallProMesssage(String code) throws IOException {
        String url = buildOpenIdUrl(appId, secret, code);
        ResponeVo responeVo = HttpUtils.get(url);
        JSONObject jsonObject = JSONObject.parseObject(responeVo.getContent());
        if (jsonObject != null) {
            int errcode = jsonObject.getIntValue("errcode");
            if (errcode == 0) {
                // session_key 会话秘钥
//                String sessionKey = jsonObject.getString("session_key");
                String unionid = jsonObject.getString("unionid");
                String openId = jsonObject.getString("openid");
                Person person = getPerson();
                if (person != null && person.getId() != null) {
                    WechatRelation wechatRelation = wechatRelationService.getOne(new LambdaQueryWrapper<WechatRelation>().eq(WechatRelation::getUnionId, unionid));
                    if (wechatRelation == null) {
                        wechatRelation = new WechatRelation();
                        wechatRelation.setSmallOpenId(openId);
                        wechatRelation.setUnionId(unionid);
                        wechatRelation.setPersonId(person.getId());
                        wechatRelation.setCreateDate(new Date());
                        wechatRelationService.save(wechatRelation);
                    } else {
                        wechatRelation.setPersonId(person.getId());
                        wechatRelation.setSmallOpenId(openId);
                        wechatRelationService.updateById(wechatRelation);
                    }
                    if (StringUtil.isEmpty(person.getOpenId()) && StringUtil.isNotEmpty(wechatRelation.getPublicOpenId())) {
                        Person newPerson = new Person();
                        newPerson.setId(person.getId());
                        // 公众号的openId
                        newPerson.setOpenId(wechatRelation.getPublicOpenId());
                        iPersonService.updateById(newPerson);
                    }
                }
                return openId;
            } else {
                throw new BaseException(jsonObject.getString("errmsg"));
            }
        } else {
            throw new BaseException("微信接口调用失败");
        }
    }

    /**
     * 小程序 消息推送
     * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
     *
     * @return
     */
    @RequestMapping(value = "/subscribeMessage", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "消息推送", notes = "消息推送")
    public Object subscribeMessage(@RequestBody WxMssDto wxMssDto)
            throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        String res = buildMessageUrlToPost(wxMssDto);
        JSONObject jsonObject = JSONObject.parseObject(res);
        int errcode = jsonObject.getIntValue("errcode");
        switch (errcode) {
            case 40003:
                throw new BaseException("touser字段openid为空或者不正确");
            case 40037:
                throw new BaseException("订阅模板id为空不正确");
            case 43101:
                throw new BaseException("用户拒绝接受消息，如果用户之前曾经订阅过，则表示用户取消了订阅关系");
            case 47003:
                throw new BaseException("模板参数不准确，可能为空或者不满足规则，errmsg会提示具体是哪个字段出错");
            case 41030:
                throw new BaseException("page路径不正确，需要保证在现网版本小程序中存在，与app.json保持一致");
            default:
                break;
        }
        return true;
    }

    /**
     * 技术库文档二维码
     *
     * @return
     */
    @RequestMapping(value = "/getQrCode", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "技术库文档二维码", notes = "技术库文档二维码")
    public void getQrCode(String scene, Long width,
                          @RequestParam(value = "fileType", required = false, defaultValue = "png") String fileType,
                          HttpServletResponse response) {
        String token = smallProService.getSmallProToken();
        String page = "view/home/infoQuery/technologyQuery/TechnologyDetail";
        smallProService.getSmallProQrCodeResponse(token, scene, page, Long.valueOf(width), null, null, null, response,
                "技术库文档", fileType);
    }

    private String buildMessageUrlToPost(WxMssDto wxMssDto)
            throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, IOException {
        String token = smallProService.getSmallProToken();
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + token;
        // 处理模板数据
        Map dataMap = JSONObject.parseObject(wxMssDto.getData());
        JSONObject param = new JSONObject();
        param.put("touser", wxMssDto.getTouser());
        param.put("template_id", wxMssDto.getTemplate_id());
        param.put("page", wxMssDto.getPage());
        param.put("data", dataMap);
        ResponeVo post = HttpUtils.post(url, param.toJSONString());
        log.info("微信数据:" + post.getContent());
        String status = "发送失败";
        String failMessage = "";
        JSONObject jsonObject = JSONObject.parseObject(post.getContent());
        int errcode = jsonObject.getIntValue("errcode");
        switch (errcode) {
            case 40003:
                failMessage = "touser字段openid为空或者不正确";
                break;
            case 40037:
                failMessage = "订阅模板id为空不正确";
                break;
            case 43101:
                failMessage = "用户拒绝接受消息，如果用户之前曾经订阅过，则表示用户取消了订阅关系";
                break;
            case 47003:
                failMessage = "模板参数不准确，可能为空或者不满足规则，errmsg会提示具体是哪个字段出错";
                break;
            case 41030:
                failMessage = "page路径不正确，需要保证在现网版本小程序中存在，与app.json保持一致";
            default:
                status = "发送成功";
                break;
        }
        WechatSendMessage wechatSendMessage = new WechatSendMessage();
        wechatSendMessage.setOpenId(wxMssDto.getTouser());
        wechatSendMessage.setMessage(param.toJSONString());
        wechatSendMessage.setStatus(status);
        wechatSendMessage.setTemplateId(wxMssDto.getTemplate_id());
        wechatSendMessage.setFailMessage(failMessage);
        wechatSendMessage.setResult(post.getContent());
        wechatSendMessage.setCreateDate(new Date());
        wechatSendMessageService.save(wechatSendMessage);
        return post.getContent();
    }

    private String buildOpenIdUrl(String appId, String secret, String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + secret + "&js_code="
                + code + "&grant_type=authorization_code";
        return url;
    }

    /**
     * 技术库文档二维码
     *
     * @return
     */
    @RequestMapping(value = "/getTutorial", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "获取使用指南文档id", notes = "获取使用指南文档id")
    public String getTutorial() {
        return tutorialId;
    }


    @RequestMapping(value = "/test/send/message", method = RequestMethod.GET)
    @ApiOperation(httpMethod = "GET", value = "测试微信消息通知", notes = "测试微信消息通知")
    public void testSendMessage(@RequestParam("messageData") String messageData) throws Exception {
        List<String> openIds = new ArrayList<>();
        if (StringUtil.isNotEmpty(messageData)) {
//            openIds.add("ocN2g4nkM4KOIKC6rdLKs-1Tt-Rc");
            openIds.add("omzjg09wxUbgL-aNFaixj4YYr45M");
            String template = "2";
            List<String> message = new ArrayList<>();
            String[] split = messageData.split("#");
            for (String s : split) {
                message.add(s);
            }
            smallProService.sendWeChatUpcomingMessage(openIds, template, message);
        }
    }
}
