package com.xunwang.payment.controller;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xunwang.payment.entity.InMessage;
import com.xunwang.payment.entity.OutMessage;
import com.xunwang.payment.entity.SaOpenid;
import com.xunwang.payment.entity.SendToSaMsg;
import com.xunwang.payment.service.SaOpenidService;
import com.xunwang.payment.service.SendToSaMsgService;
import com.xunwang.payment.util.MyWxUtils;
import io.swagger.annotations.Api;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

@Api("微信公众号")
@RestController
@RequestMapping("payment/wechat/publicAccount")
public class WechatPublicAccountController {

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private MyWxUtils myWxUtils;

    @Autowired
    private SaOpenidService saOpenidService;

    @Autowired
    private SendToSaMsgService sendToSaMsgService;


    // 微信页面填写的token，必须保密
    private static final String TOKEN = "1e3b5fbd4d4e4978923cd647d4509d2b";

    @GetMapping("validate")
    public String validate(String signature, String timestamp, String nonce, String echostr) {
        // 1. 将token、timestamp、nonce三个参数进行字典序排序
        String[] arr = {timestamp, nonce, TOKEN};
        Arrays.sort(arr);
        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        StringBuilder sb = new StringBuilder();
        for (String temp : arr) {
            sb.append(temp);
        }
        // 这里利用了hutool的加密工具类
        String sha1 = SecureUtil.sha1(sb.toString());
        // 3. 加密后的字符串与signature对比，如果相同则该请求来源于微信，原样返回echostr
        if (sha1.equals(signature)) {
            return echostr;
        }
        // 接入失败
        return null;
    }

    @PostMapping(value = "validate", produces = "application/xml;charset=UTF-8")
    public Object handleMessage(@RequestBody InMessage inMessage) {
        // 创建响应消息实体对象
        OutMessage outMessage = new OutMessage();
        // 把原来的接收方设置为发送方
        outMessage.setFromUserName(inMessage.getToUserName());
        // 把原来的发送方设置为接收方
        outMessage.setToUserName(inMessage.getFromUserName());
        // 设置消息类型
        outMessage.setMsgType(inMessage.getMsgType());
        // 设置消息时间
        outMessage.setCreateTime(System.currentTimeMillis() / 1000);
        // 根据接收到消息类型，响应对应的消息内容
        if ("text".equals(inMessage.getMsgType())) {
            // 根据不同的关键字回复消息
            String inContent = inMessage.getContent();
            if (inContent.contains("游戏")) {
                outMessage.setContent("仙剑");
            } else if (inContent.contains("动漫")) {
                outMessage.setContent("进击的巨人");
            } else {
                outMessage.setContent("请进入小程序，发布学员需求或认证教师发布课程");

            }
        } else if ("image".equals(inMessage.getMsgType())) {
            // 图片
            outMessage.setMediaId(new String[]{inMessage.getMediaId()});
        } else if ("event".equals(inMessage.getMsgType())){
            //获取推送的事件类型
            String event = inMessage.getEvent();
            //如果是关注事件
            if ("subscribe".equals(event)){
                outMessage.setMsgType("text");
                outMessage.setContent("感谢关注家教公众号!! 详情请进入小程序了解");
                //拿到关注用户的unionId
                String unionId = myWxUtils.getUnionId(inMessage.getFromUserName());

                SaOpenid saOpenid = new SaOpenid();
                saOpenid.setOpenid(inMessage.getFromUserName());
                saOpenid.setUnionid(unionId);
                //获取时间
                Date date = new Date();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
                saOpenid.setSubscribeTime(simpleDateFormat.format(date));
                //关注状态
                saOpenid.setSubscribe("已关注");
                //写入
                QueryWrapper<SaOpenid> wrapper = new QueryWrapper<>();
                wrapper.eq("openid", inMessage.getFromUserName());
                long count = saOpenidService.count(wrapper);
                System.out.println(count);
                if (count == 0){
                    saOpenidService.save(saOpenid);
                }else {
                    saOpenid.setUnsubscribeTime("0000-00-00 :00:00:00");
                    saOpenidService.update(saOpenid,wrapper);

                }

                System.out.println(unionId);
            }else if ("unsubscribe".equals(event)){
                SaOpenid saOpenid = new SaOpenid();
                saOpenid.setSubscribe("已取消");
                String fromUserName = inMessage.getFromUserName();
                saOpenid.setOpenid(fromUserName);

                Date date = new Date();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
                saOpenid.setUnsubscribeTime(simpleDateFormat.format(date));

                QueryWrapper<SaOpenid> wrapper = new QueryWrapper<>();
                wrapper.eq("openid", inMessage.getFromUserName());
                saOpenidService.update(saOpenid,wrapper);
            }
        }
        return outMessage;
    }

    @GetMapping("/sendMessage")
    public boolean sendMessage(@RequestParam("openid") String openid, @RequestParam("content") String content) throws WxErrorException {
        WxMpKefuMessage message=WxMpKefuMessage.TEXT().toUser(openid).content(content).build();
        wxMpService.getKefuService().sendKefuMessage(message);
        return true;
    }


    /**
     *
     * @param unionid unionid
     * @param grade 年级
     * @param subject 科目
     * @param address 地址
     * @param reward 服务费
     * @param phone 联系方式
     * @param remark 备注
     */
    @GetMapping("/pay")
    public void sendTemplateMsgPay(@RequestParam("unionid") String unionid , @RequestParam("grade") String grade , @RequestParam("subject") String subject ,
                                   @RequestParam("address") String address , @RequestParam("reward") String reward , @RequestParam("phone") String phone,
                                   @RequestParam("remark") String remark){
        //通过unionid 获取openid
        QueryWrapper<SaOpenid> wrapper = new QueryWrapper<>();
        wrapper.eq("unionid",unionid);
        SaOpenid one = saOpenidService.getOne(wrapper);
        String openid = one.getOpenid();
        //获取token
        String weiXinToken = myWxUtils.getAccessToken();
        String data = myWxUtils.payNoticeTemplate(openid,grade,subject,address,reward,phone,remark);
        //发送消息
        okhttp3.RequestBody requestBody = okhttp3.RequestBody.create(MediaType.parse("application/json"), data);
        Request request = new Request.Builder().url("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + weiXinToken).post(requestBody).build();
        OkHttpClient okHttpClient = new OkHttpClient();
        Response execute = null;

        SendToSaMsg sendToSaMsg = new SendToSaMsg();
        sendToSaMsg.setOpenid(openid);
        sendToSaMsg.setUnionid(unionid);
        sendToSaMsg.setTemplateType("支付通知");
        try {
            execute = okHttpClient.newCall(request).execute();
            String body = ((Response) execute).body().string();
            if(execute.code() == 200){
                System.out.println("模板消息发送成功==========" + body);
                sendToSaMsg.setSendStatus(body);
                sendToSaMsgService.save(sendToSaMsg);

            }else{
                System.out.println("模板消息发送失败==========" + body);
                sendToSaMsg.setSendStatus("失败");
                sendToSaMsgService.save(sendToSaMsg);

            }
        } catch (IOException e) {
            sendToSaMsg.setSendStatus("error");
            sendToSaMsgService.save(sendToSaMsg);
            e.printStackTrace();
        }
    }

    /**
     *
     * @param unionid unionid
     * @param name 预约人姓名
     * @param phone 预约人手机号
     * @param course 预约课程
     * @param remark 备注
     * @param isTeacher 判断发送给老师或是学生
     */
    @GetMapping("/order")
    public void sendTemplateMsgOrder(@RequestParam("unionid") String unionid , @RequestParam("name") String name , @RequestParam("phone") String phone ,
                                   @RequestParam("course") String course , @RequestParam("remark") String remark , @RequestParam("isTeacher") boolean isTeacher){
        //通过unionid 获取openid
        QueryWrapper<SaOpenid> wrapper = new QueryWrapper<>();
        wrapper.eq("unionid",unionid);
        SaOpenid one = saOpenidService.getOne(wrapper);
        String openid = one.getOpenid();
        //获取token
        String weiXinToken = myWxUtils.getAccessToken();
        String data = myWxUtils.orderNoticeTemplate(openid,name,phone,course,remark,isTeacher);
        //发送消息
        okhttp3.RequestBody requestBody = okhttp3.RequestBody.create(MediaType.parse("application/json"), data);
        Request request = new Request.Builder().url("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + weiXinToken).post(requestBody).build();
        OkHttpClient okHttpClient = new OkHttpClient();
        Response execute = null;

        SendToSaMsg sendToSaMsg = new SendToSaMsg();
        sendToSaMsg.setOpenid(openid);
        sendToSaMsg.setUnionid(unionid);
        String type;
        if (isTeacher == true){
            type = "预约通知(老师收)";
        }else {
            type = "预约通知(用户收)";
        }
        sendToSaMsg.setTemplateType(type);
        try {
            execute = okHttpClient.newCall(request).execute();
            String body = ((Response) execute).body().string();
            if(execute.code() == 200){
                System.out.println("模板消息发送成功==========" + body);
                sendToSaMsg.setSendStatus(body);
                sendToSaMsgService.save(sendToSaMsg);

            }else{
                System.out.println("模板消息发送失败==========" + body);
                sendToSaMsg.setSendStatus("失败");
                sendToSaMsgService.save(sendToSaMsg);

            }
        } catch (IOException e) {
            sendToSaMsg.setSendStatus("error");
            sendToSaMsgService.save(sendToSaMsg);
            e.printStackTrace();
        }
    }

}