package com.yeejoin.amos.boot.module.cylinder.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.cylinder.biz.utils.HttpUtils;
import com.yeejoin.amos.boot.module.cylinder.api.dto.WechatMessageDto;
import com.yeejoin.amos.boot.module.cylinder.api.entity.WechatRelation;
import com.yeejoin.amos.boot.module.cylinder.api.service.IWechatService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 微信公众号服务实现类
 */
@Service
public class WechatServiceImpl implements IWechatService {

    @Autowired
    RedisUtils redisUtils;

    /**
     * token 过期时间，wechat 系统为7200 ，tzs 系统小于7200 防止获取到无效token
     */
    private long time = 6000l;

    @Value("${tzs.wechat.appid}")
    private String APP_ID;

    @Value("${tzs.wechat.secret}")
    private String SECRET_KEY;

    @Value("${tzs.wechat.url}")
    private String wechatUrl;

    @Autowired
    WechatRelationServiceImpl wechatRelationService;
    @Value("${tzs.wechat.tempId.warning}")
    private String templateId_Warning;
    @Value("${tzs.wechat.tempId.supervise}")
    private String templateId_Supervise;
    @Value("${tzs.wechat.test.userId}")
    private String testUserId;

    @Override
    public String getAccessToken() {
        if(redisUtils.hasKey(RedisKey.WECHAT_TOKEN)){
            Object obj= redisUtils.get(RedisKey.WECHAT_TOKEN);
            return obj.toString();
        } else {
            String tokenAccessUrl = wechatUrl+ "/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + SECRET_KEY;
            String responseStr = HttpUtils.doGet(tokenAccessUrl);
            JSONObject response = null;
            try {
                response = JSONObject.parseObject(responseStr);
            } catch (Exception e) {
                throw  new BadRequest("获取token 出错：" + e.getMessage());
            }
            if(response.get("access_token") != null) { // 获取token 成功
                try {
                    String token = response.getString("access_token");
                    redisUtils.set(RedisKey.WECHAT_TOKEN, token,time);
                    return token;
                } catch (Exception e) {
                    throw  new BadRequest("获取token 出错：" + e.getMessage());
                }
            } else {
                throw  new BadRequest("获取token 出错：" + response);
            }
        }
    }

    @Override
    public String getOpenId(String code) {
        String openIdUrl = wechatUrl+ "/sns/oauth2/access_token?appid=" +APP_ID + "&secret=" + SECRET_KEY + "&code=" + code + "&grant_type=authorization_code";
        String responseStr = HttpUtils.doGet(openIdUrl);
        JSONObject response = null;
        try {
            response = JSONObject.parseObject(responseStr);
        } catch (Exception e) {
            throw  new BadRequest("获取openId 出错：" + e.getMessage());
        }
        if(response.get("openid") != null) { // 获取token 成功
            try {
                String openid = response.getString("openid");
                String token = response.getString("access_token");
                redisUtils.set("accessToken_" + openid, token,time); // 设置用户accessToken
                return openid;
            } catch (Exception e) {
                throw  new BadRequest("获取openId 出错：" + e.getMessage());
            }
        } else {
            throw  new BadRequest("获取openId 出错" + response);
        }
    }

    @Override
    public JSONObject getUserInfo(String openId) {
        String access_token = redisUtils.get("accessToken_" + openId) == null ? null : redisUtils.get("accessToken_" + openId).toString();
        if(access_token == null) {
            throw  new BadRequest("用户access_token过期");
        }
        String nickNameUrl = wechatUrl+ "/sns/userinfo?access_token="+access_token+"&openid="+openId+"&lang=zh_CN";
        String responseStr = HttpUtils.doGet(nickNameUrl);
        JSONObject response = null;
        try {
            response = JSONObject.parseObject(responseStr);
        } catch (Exception e) {
            throw  new BadRequest("获取nickName 出错：" + e.getMessage());
        }
        if(response.get("nickname") != null) { // 获取token 成功
            try {
                return response;
            } catch (Exception e) {
                throw  new BadRequest("获取nickname 出错：" + e.getMessage());
            }
        } else {
            throw  new BadRequest("获取nickname 出错" + response);
        }
    }

    @Override
    public JSONObject sendWechatModelMessage(String openId, WechatMessageDto wechatMessageDto) {
        String accessToken = this.getAccessToken();
        String modelMessageUrl = wechatUrl + "/cgi-bin/message/template/send?access_token=" + accessToken;
        JSONObject messageBody = new JSONObject();
        messageBody.put("touser", openId);
        messageBody.put("template_id", wechatMessageDto.getTemplateId());
        if(wechatMessageDto.getUrl() != null) {
            messageBody.put("url",wechatMessageDto.getUrl());
        }
        JSONObject data = new JSONObject();
        Map<String, String> datas = wechatMessageDto.getData();
        for(Map.Entry<String, String> temp : datas.entrySet()) {
            JSONObject tempObj = new JSONObject();
            tempObj.put("value",temp.getValue());
            data.put(temp.getKey(),tempObj);
        }
        messageBody.put("data",data);
        System.out.println(messageBody.toJSONString());
        String responseStr = HttpUtils.doPost(modelMessageUrl, messageBody.toJSONString());
        JSONObject response = null;
        try {
            response = JSONObject.parseObject(responseStr);
        } catch (Exception e) {
        	e.printStackTrace();
            throw  new BadRequest("发送模板消息出错：" + e.getMessage());
        }
        return response;
    }

    @Override
    public String getWechatPicByMediaId(String mediaId) {
        String accessToken = this.getAccessToken();
        String getPicUrl = wechatUrl + "/cgi-bin/media/get?access_token=" + accessToken + "&media_id=" + mediaId;
        Map<String, Object> result = HttpUtils.doGetDownload(getPicUrl);
        if(result.get("bytes") == null) {
            throw  new BadRequest("获取附件失败");
        }
        byte[] bytes = (byte[]) result.get("bytes");
        String fileName = (String) result.get("filename");
        String urlString="";
        MultipartFile file = new MockMultipartFile(fileName,fileName,"application/octet-stream" ,bytes);
        FeignClientResult<Map<String, String>> date = Systemctl.fileStorageClient.updateCommonFile(file);
        if (date != null) {
            Map<String, String> map = date.getResult();
            Iterator<String> it = map.keySet().iterator();
            while (it.hasNext()) {
                urlString=it.next();
            }
        }
        return urlString;
    }

    @Override
    public Boolean sendTestTemplateMsgWarning() {
        List<WechatRelation> wechatRelationList =
                wechatRelationService.list(new LambdaQueryWrapper<WechatRelation>().in(WechatRelation::getUserId,
                        Arrays.asList(testUserId.split(","))));
        wechatRelationList.forEach(i -> {
            WechatMessageDto wechatMessageDto1 = new WechatMessageDto();
            wechatMessageDto1.setTemplateId(templateId_Warning);
            Map<String, String> data1 = Maps.newHashMap();
            data1.put("first", "【陕西省特种设备安全监察局】监督检查提醒");
            data1.put("keyword1", "西安市碑林区市场监督管理局，系统发现您辖区内西安荣昌电梯有限公司2022年1月份应急救援时间合规率为66.96%，低于基准线90%，已自动为您制定监督检查任务，请按照要求进行监督检查后在系统进行信息登记。");
            data1.put("keyword2", DateUtils.date2LongStr(new Date()));
            wechatMessageDto1.setData(data1);
            sendWechatModelMessage(i.getOpenId(), wechatMessageDto1);

            WechatMessageDto wechatMessageDto2 = new WechatMessageDto();
            wechatMessageDto2.setTemplateId(templateId_Warning);
            Map<String, String> data2 = Maps.newHashMap();
            data2.put("first", "【陕西省特种设备安全监察局】监督检查提醒");
            data2.put("keyword1", "西安荣昌电梯有限公司，系统发现贵公司2022年1月份应急救援时间合规度为66.96%，低于基准线90%，西安市碑林区市场监督管理局将于近期进行监督检查，请做好准备。");
            data2.put("keyword2", DateUtils.date2LongStr(new Date()));
            wechatMessageDto2.setData(data2);
            sendWechatModelMessage(i.getOpenId(), wechatMessageDto2);
        });
        return true;
    }

    @Override
    public Boolean sendTestTemplateMsgSupervise() {
        List<WechatRelation> wechatRelationList =
                wechatRelationService.list(new LambdaQueryWrapper<WechatRelation>().in(WechatRelation::getUserId,
                        Arrays.asList(testUserId.split(","))));
        wechatRelationList.forEach(i -> {
            WechatMessageDto wechatMessageDto = new WechatMessageDto();
            wechatMessageDto.setTemplateId(templateId_Supervise);
            Map<String, String> data = Maps.newHashMap();
            data.put("first", "【陕西省特种设备安全监察局】西安荣昌电梯有限公司，经西安市碑林区市场监督管理局监督检查，发现以下问题，请安排人员落实整改。");
            data.put("keyword1", "西安荣昌电梯有限公司");
            data.put("keyword2", "监管问题：2022年1月份应急救援时间合规度为66.96%，低于基准线90%；现场监督检查发现：没有建立事故应急措施和救援预案，无演练记录。");
            data.put("keyword3", DateUtils.date2LongStr(new Date()));
            data.put("keyword4", "李静");

            wechatMessageDto.setData(data);
            sendWechatModelMessage(i.getOpenId(), wechatMessageDto);
        });

        return true;
    }
}