package com.yida.data.device.studentCard.utils;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yida.data.common.core.entity.card.EduStudentCardJimiAccount;
import com.yida.data.common.core.entity.constant.FebsConstant;
import com.yida.data.common.core.entity.constant.JimiConstant;
import com.yida.data.common.core.exception.FebsException;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ClassName JiMiUtils
 * @Description TODO
 * @Author jmw
 * @Date 2021/7/30 11:46
 * @Version 1.0
 **/
@Slf4j
@Component
public class JimiUtils {

    @Autowired
    private RedisService redisService;

    /***
     * @Author jianMingWang
     * @Description 获取token
     * @Date 13:36 2021/7/30
     * @Param [corpId, secret]
     * @return java.lang.String
     **/
    public String getAccessToken(EduStudentCardJimiAccount account) {
        try {
            String accessToken = String.valueOf(account == null
                ? redisService.get(FebsConstant.JM_ACCESS_TOKEN)
                : redisService.get(FebsConstant.JM_ACCESS_TOKEN + account.getUsername()));
            if ("null".equals(accessToken)) {
                String refreshToken = String.valueOf(account == null
                    ? redisService.get(FebsConstant.JM_REFRESH_TOKEN)
                    : redisService.get(FebsConstant.JM_REFRESH_TOKEN + account.getUsername()));
                if (!"null".equals(refreshToken)) {
                    // 刷新accesstoken
                    return refreshToken(account);
                }
                Map<String, Object> params = baseMap(JimiConstant.GET_ACCESS_TOKEN_METHOD);
                params.put("user_id", account == null ? JimiConstant.ACCOUNT : account.getUsername());
                params.put("user_pwd_md5", DigestUtil.md5Hex(account == null
                    ? JimiConstant.PASSWORD.getBytes() : account.getPassword().getBytes()));
                params.put("expires_in", "7200");
                params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));

                // 请求几米  获取access token
                String response = HttpUtil.get(JimiConstant.JIMI_URL, params);

                JSONObject jsonObject = JSONUtil.parseObj(response);
                if (!"0".equals(jsonObject.get("code").toString())) {
                    log.error("请求几米 获取 access token失败，code:{},msg:{}", jsonObject.get("code").toString(),
                        jsonObject.get("message").toString());
                    throw new FebsException("获取几米token失败");
                }
                JSONObject jsonResult = (JSONObject) jsonObject.get("result");
                accessToken = jsonResult.get("accessToken").toString();
                refreshToken = jsonResult.get("refreshToken").toString();
                // 缓存accessToken两小时
                redisService.set(account == null ? FebsConstant.JM_ACCESS_TOKEN :
                        FebsConstant.JM_ACCESS_TOKEN + account.getUsername(), accessToken
                    , 7000L);
                //保留一份accesstoken 用于 refreshToken
                redisService.set(account == null ? FebsConstant.JM_ACCESS_TOKEN_COPY :
                        FebsConstant.JM_ACCESS_TOKEN_COPY + account.getUsername(),
                    accessToken,
                    7200L);
                // 缓存refreshToken
                redisService.set(account == null ? FebsConstant.JM_REFRESH_TOKEN :
                    FebsConstant.JM_REFRESH_TOKEN + account.getUsername(), refreshToken, 7200L);
            }
            return accessToken;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /***
     * @Author jianMingWang
     * @Description //刷新token
     * @Date 15:40 2021/7/30
     * @Param []
     * @return java.lang.String
     **/
    public String refreshToken(EduStudentCardJimiAccount account) throws IOException {
        String accessToken = String.valueOf(redisService.get(account == null
            ? FebsConstant.JM_ACCESS_TOKEN_COPY
            : FebsConstant.JM_ACCESS_TOKEN_COPY + account.getUsername()));
        String refreshToken = String.valueOf(redisService.get(account == null
            ? FebsConstant.JM_REFRESH_TOKEN
            : FebsConstant.JM_REFRESH_TOKEN + account.getUsername()));
        Map<String, Object> params = baseMap(JimiConstant.REFRESH_TOKEN_METHOD);
        params.put("access_token", accessToken);
        params.put("refresh_token", refreshToken);
        params.put("expires_in", "7200");
        params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));

        // 请求几米 access token
        String response = HttpUtil.get(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("请求几米 refresh token失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // 重新请求token
            redisService.del(account == null
                ? FebsConstant.JM_ACCESS_TOKEN
                : FebsConstant.JM_ACCESS_TOKEN + account.getUsername());
            redisService.del(account == null
                ? FebsConstant.JM_ACCESS_TOKEN_COPY
                : FebsConstant.JM_ACCESS_TOKEN_COPY + account.getUsername());
            redisService.del(account == null
                ? FebsConstant.JM_REFRESH_TOKEN
                : FebsConstant.JM_REFRESH_TOKEN + account.getUsername());
            return getAccessToken(account);
        }

        JSONObject jsonResult = (JSONObject) jsonObject.get("result");
        accessToken = jsonResult.get("accessToken").toString();
        refreshToken = jsonResult.get("refreshToken").toString();

        // 缓存accessToken两小时
        redisService.set(account == null
            ? FebsConstant.JM_ACCESS_TOKEN
            : FebsConstant.JM_ACCESS_TOKEN + account.getUsername(), accessToken, 7000L);
        //保留一份accesstoken 用于 refreshToken
        redisService.set(account == null
            ? FebsConstant.JM_ACCESS_TOKEN_COPY
            : FebsConstant.JM_ACCESS_TOKEN_COPY + account.getUsername(), accessToken, 7200L);
        // 缓存refreshToken
        redisService.set(account == null
            ? FebsConstant.JM_REFRESH_TOKEN
            : FebsConstant.JM_REFRESH_TOKEN + account.getUsername(), refreshToken, 7200L);
        return accessToken;
    }

    public JSONObject getAllLocation() {
        Map<String, Object> params = baseMap(JimiConstant.ALL_LOCATION_METHOD);
        params.put("access_token", getAccessToken(null));
        params.put("target", JimiConstant.ACCOUNT);
        params.put("map_type", JimiConstant.MAPTYPE_POSITION);
        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,msg:[{}],stack:[{}]", e.getMessage(), e.getStackTrace());
            throw new FebsException("签名失败");
        }
        // 请求几米
        String response = HttpUtil.get(JimiConstant.JIMI_URL, params);
        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("请求几米获取最新定位数据失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // token过期
            if ("1004".equals(jsonObject.get("code").toString())) {
                // 缓存accessToken两小时
                redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                //保留一份accesstoken 用于 refreshToken
                redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                // 缓存refreshToken
                redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                return getAllLocation();
            }
            throw new FebsException("请求几米获取最新定位数据失败");
        }
        return jsonObject;
    }


    /***
     * @Author jianMingWang
     * @Description 获取最新定位数据
     * @Date 15:53 2021/7/30
     * @Param imeis : 设备imei号，多个中间用英文逗号隔开
     * @return java.util.Map
     **/
    public JSONObject getNowLocaltion(String imeis) {
        Map<String, Object> params = baseMap(JimiConstant.GET_LOCALTION_METHOD);
        params.put("access_token", getAccessToken(null));
        params.put("imeis", imeis);
        params.put("map_type", JimiConstant.MAPTYPE_POSITION);
        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,msg:[{}],stack:[{}]", e.getMessage(), e.getStackTrace());
            throw new FebsException("签名失败");
        }
        // 请求几米
        String response = HttpUtil.post(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("请求最新定位数据失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // token过期
            if ("1004".equals(jsonObject.get("code").toString())) {
                // 缓存accessToken两小时
                redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                //保留一份accesstoken 用于 refreshToken
                redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                // 缓存refreshToken
                redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                return getNowLocaltion(imeis);
            }
            throw new FebsException("请求最新定位数据失败");
        }
        return jsonObject;
    }

    /***
     * @Author jianMingWang
     * @Description 获取轨迹数据  允许无线设备获取三个月内，时间跨度不超过60天的轨迹数据。
     * @Date 16:07 2021/7/30
     * @Param imei 设备imei号(一次只能一个IMEI)
     * @Param beginTime 开始时间，格式为yyyy-MM-dd HH:mm:ss
     * @Param endTime 结束时间，格式为yyyy-MM-dd HH:mm:ss
     * @return cn.hutool.json.JSONObject
     **/
    public JSONObject getTrackInformation(String imei, String beginTime, String endTime) {
        //1:判断时间
        if (!isWithinThreeMonth(beginTime)) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("code", 500);
            jsonObject.set("result", "beginTime未在3个月之内");
            return jsonObject;
        }
        if (LocalDateTimeUtil.parse(endTime, "yyyy-MM-dd HH:mm:ss").isAfter(LocalDateTime.now())) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("code", 500);
            jsonObject.set("result", "endTime不应大于当前时间");
            return jsonObject;
        }

        Map<String, Object> params = baseMap(JimiConstant.GET_TRACK_METHOD);
        params.put("access_token", getAccessToken(null));
        params.put("imei", imei);
        params.put("begin_time", beginTime);
        params.put("end_time", endTime);
        params.put("map_type", JimiConstant.MAPTYPE_POSITION);
        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,msg:[{}],stack:[{}]", e.getMessage(), e.getStackTrace());
            throw new FebsException("签名失败");
        }
        // 请求几米
        String response = HttpUtil.get(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("请求几米获取轨迹数据失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // token过期
            if ("1004".equals(jsonObject.get("code").toString())) {
                // 缓存accessToken两小时
                redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                //保留一份accesstoken 用于 refreshToken
                redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                // 缓存refreshToken
                redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                return getTrackInformation(imei, beginTime, endTime);
            }
            throw new FebsException("请求几米获取轨迹数据失败");
        }
        return jsonObject;
    }


    /***
     * @Author jianMingWang
     * @Description 创建电子围栏, 平台围栏
     * @Date 16:52 2021/7/30
     * @Param imei ： 设备号
     * @Param fenceName 围栏名称
     * @Param fenceShape 围栏形状(只能为circle——圆
     * @Param status： in-进围栏，out-出围栏，all-进出都有
     * @Param lng 经度(说明：请传入与地图类型匹配的坐标系
     * @Param lat    纬度(说明：请传入与地图类型匹配的坐标系
     * @Param radius 围栏半径(200～999900；单位：米
     * @Param [imei, fenceName, fenceShape, status, lng, lat, radius]
     *
     * fenceShape ： 围栏形状(只能为circle——圆
     * map_type ： 默认百度
     *scale	： 	缩放级别(3～19) 默认先写 10
     * @return cn.hutool.json.JSONObject
     *
     * eg:
     * 1:设置亲情号码
     *
     *
     *
     **/
    public String createPlatFence(String imei, String fenceName, String status, Double lng, Double lat,
        Integer radius, EduStudentCardJimiAccount account) {
        Map<String, Object> params = baseMap(JimiConstant.CREATE_PLATT_FENCE_METHOD);
        params.put("access_token", getAccessToken(account));
        params.put("imei", imei);
        params.put("fence_name", fenceName);
        params.put("fence_shape", JimiConstant.FENCESHAPE);
        params.put("status", status);
        params.put("lng", lng);
        params.put("lat", lat);
        params.put("radius", radius);
        params.put("map_type", JimiConstant.MAPTYPE);
        params.put("scale", JimiConstant.SCALE);
        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,data:[{}],msg:[{}],stack:[{}]", params, e.getMessage(),
                e.getStackTrace());
            throw new FebsException("签名失败");
        }

        // 请求几米
        String response = HttpUtil.post(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("请求创建平台围栏失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // token过期
            if ("1004".equals(jsonObject.get("code").toString())) {
                // 缓存accessToken两小时
                redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                //保留一份accesstoken 用于 refreshToken
                redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                // 缓存refreshToken
                redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                return createPlatFence(imei, fenceName, status, lng, lat, radius, account);
            }
            throw new FebsException("请求创建平台围栏失败");
        }
        return jsonObject.getStr("result");
    }


    /**
     * 删除平台围栏
     *
     * @param jimiFenceId
     */
    public void delPlatFence(String jimiFenceId, EduStudentCardJimiAccount account) {
        try {
            Map<String, Object> params = baseMap(JimiConstant.DELETE_PLAT_FENCE_METHOD);
            params.put("access_token", getAccessToken(account));
            params.put("fence_id", jimiFenceId);
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));

            // 请求几米
            String response = HttpUtil.post(JimiConstant.JIMI_URL, params);

            JSONObject jsonObject = JSONUtil.parseObj(response);
            if (!"0".equals(jsonObject.get("code").toString())) {
                log.error("请求删除电子围栏失败，code:{},msg:{}", jsonObject.get("code").toString(),
                    jsonObject.get("message").toString());
                // token过期
                if ("1004".equals(jsonObject.get("code").toString())) {
                    // 缓存accessToken两小时
                    redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                    //保留一份accesstoken 用于 refreshToken
                    redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                    // 缓存refreshToken
                    redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                    delPlatFence(jimiFenceId, account);
                    return;
                }
                throw new FebsException("请求删除电子围栏失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建电子围栏
     *
     * @param imei
     * @param fenceName
     * @param status
     * @param lng
     * @param lat
     * @param radius
     * @return
     */
    public String createDeviceFence(String imei, String fenceName, String status, Double lng, Double lat,
        Integer radius) {
        Map<String, Object> params = baseMap(JimiConstant.CREATE_DEVICE_FENCE_METHOD);
        params.put("access_token", getAccessToken(null));
        params.put("imei", imei);
        params.put("fence_name", fenceName);
        params.put("alarm_type", status);
        params.put("report_mode", 1);
        params.put("alarm_switch", "ON");
        params.put("lng", lng);
        params.put("lat", lat);
        params.put("radius", radius);
        params.put("zoom_level", JimiConstant.SCALE);
        params.put("map_type", JimiConstant.MAPTYPE);
        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,data:[{}],msg:[{}],stack:[{}]", params, e.getMessage(),
                e.getStackTrace());
            throw new FebsException("签名失败");
        }

        // 请求几米
        log.info("params:[{}]", JSONUtil.toJsonStr(params));
        String response = HttpUtil.post(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("请求创建电子围栏失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // token过期
            if ("1004".equals(jsonObject.get("code").toString())) {
                // 缓存accessToken两小时
                redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                //保留一份accesstoken 用于 refreshToken
                redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                // 缓存refreshToken
                redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                return createDeviceFence(imei, fenceName, status, lng, lat, radius);
            }
            throw new FebsException("请求创建电子围栏失败");
        }
        return jsonObject.getStr("result");
    }


    /**
     * 删除电子围栏
     */
    public void delDeviceFence(String jimiFenceNo, String imei) {
        try {
            Map<String, Object> params = baseMap(JimiConstant.DELETE_DEVICE_FENCE_METHOD);
            params.put("access_token", getAccessToken(null));
            //params.put("access_token", "623609ebc02a401c4589d9c07d3db9b0");
            params.put("instruct_no", jimiFenceNo);
            params.put("imei", imei);
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));

            // 请求几米
            String response = HttpUtil.post(JimiConstant.JIMI_URL, params);

            JSONObject jsonObject = JSONUtil.parseObj(response);
            if (!"0".equals(jsonObject.get("code").toString())) {
                log.error("请求删除电子围栏失败，code:{},msg:{}", jsonObject.get("code").toString(),
                    jsonObject.get("message").toString());
                // token过期
                if ("1004".equals(jsonObject.get("code").toString())) {
                    // 缓存accessToken两小时
                    redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                    //保留一份accesstoken 用于 refreshToken
                    redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                    // 缓存refreshToken
                    redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                    delDeviceFence(jimiFenceNo, imei);
                    return;
                }
                throw new FebsException("请求删除电子围栏失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询电子围栏
     */
    public JSONArray getDeviceFence(String imei) {
        Map<String, Object> params = baseMap(JimiConstant.GET_DEVICE_FENCE_METHOD);
        params.put("access_token", getAccessToken(null));
        //params.put("access_token", "54c3a516ce8a68bd86e88246e9c6da7a");
        params.put("imei", imei);
        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,data:[{}],msg:[{}],stack:[{}]", params, e.getMessage(),
                e.getStackTrace());
            throw new FebsException("签名失败");
        }

        // 请求几米
        String response = HttpUtil.post(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("查询电子围栏失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // token过期
            if ("1004".equals(jsonObject.get("code").toString())) {
                // 缓存accessToken两小时
                redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                //保留一份accesstoken 用于 refreshToken
                redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                // 缓存refreshToken
                redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                return getDeviceFence(imei);
            }
            throw new FebsException("查询电子围栏失败");
        }
        return jsonObject.getJSONArray("result");
    }


    /***
     * @Author jianMingWang
     * @Description //设备发送指令
     * @Date 17:37 2021/7/30
     * @Param [imei,    设备imei号
     * @Param [instParamJson :  	指令消息json字符串
     * inst_param_json :
     * nst_id	String	是	无	指令编码
     * inst_template	String	是	无	指令模板
     * params	Array<string>	是	无	指令参数字符串数组
     *
     * @return cn.hutool.json.JSONObject
     **/
    public JSONObject sendIntruction(String imei, String instParamJson) {
        Map<String, Object> params = baseMap(JimiConstant.SEND_INSTRUCTION_METHOD);
        params.put("access_token", getAccessToken(null));
        params.put("imei", imei);
        params.put("inst_param_json", instParamJson);
        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,msg:[{}],stack:[{}]", e.getMessage(), e.getStackTrace());
            throw new FebsException("签名失败");
        }

        // 请求几米
        String response = HttpUtil.post(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        if (!"0".equals(jsonObject.get("code").toString())) {
            log.error("几米发送指令失败，code:{},msg:{}", jsonObject.get("code").toString(),
                jsonObject.get("message").toString());
            // token过期
            if ("1004".equals(jsonObject.get("code").toString())) {
                // 缓存accessToken两小时
                redisService.del(FebsConstant.JM_ACCESS_TOKEN);
                //保留一份accesstoken 用于 refreshToken
                redisService.del(FebsConstant.JM_ACCESS_TOKEN_COPY);
                // 缓存refreshToken
                redisService.del(FebsConstant.JM_REFRESH_TOKEN);
                return sendIntruction(imei, instParamJson);
            }
            throw new FebsException("几米发送指令失败");
        }
        return jsonObject;
    }


    /***
     * @Author jianMingWang
     * @Description 封装公共参数
     * @Date 16:04 2021/7/30
     * @Param [method]
     * @return java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> baseMap(String method) {
        Map<String, Object> params = new HashMap<>();
        params.put("method", method);
        params.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        params.put("app_key", JimiConstant.APPKEY);
        params.put("sign_method", "md5");
        params.put("v", "1.0");
        params.put("format", "json");
        return params;
    }


    /***
     * @Author jianMingWang
     * @Description 判断时间收在三个月之内
     * @Date 16:25 2021/7/30
     * @Param []
     * @return boolean
     **/
    public boolean isWithinThreeMonth(String beginTime) {
        LocalDate date = LocalDateTimeUtil.parse(beginTime, "yyyy-MM-dd HH:mm:ss").toLocalDate();
        LocalDate lateDate = LocalDate.now().minusMonths(3L);
        if (date.isAfter(lateDate)) {
            return true;
        }
        return false;
    }

    /**
     * @return
     * @Author ccl
     * @Description 获取指令列表
     */
    public JSONObject getOrderList(String imei) throws IOException {
        Map<String, Object> params = baseMap(JimiConstant.LIST_INSTRUCTION_METHOD);
        params.put("access_token", getAccessToken(null));
        params.put("imei", imei);

        try {
            params.put("sign", SignUtil.signTopRequest(params, JimiConstant.APPSECRET, "md5"));
        } catch (Exception e) {
            log.error("jimi sign fail,msg:[{}],stack:[{}]", e.getMessage(), e.getStackTrace());
            throw new FebsException("签名失败");
        }
        String response = HttpUtil.get(JimiConstant.JIMI_URL, params);

        JSONObject jsonObject = JSONUtil.parseObj(response);
        System.out.println(jsonObject);
        return JSONUtil.parseObj(response);
    }

    /**
     * 设置亲情号码
     *
     * @param imei
     * @param name  姓名
     * @param phone 电话
     * @return
     * @throws IOException
     */
    public JSONObject setFamilyPhone(String imei, List<String> name, List<String> phone) {
        List<String> params = new ArrayList<>();
        for (int i = 0; i < name.size(); i++) {
            params.add(name.get(i));
            params.add(phone.get(i));
        }
        JSONObject json = new JSONObject() {{
            set("inst_id", 149);
            set("inst_template", "FN&&A&&{0}&&{1}&&{2}&&{3}&&{4}&&{5}##");
            set("params", params);
            set("is_cover", true);
        }};
        return sendIntruction(imei, json.toString());
    }

    /**
     * 设置sos号码
     *
     * @param imei
     * @param phone
     * @return
     */
    public JSONObject setSos(String imei, List<String> phone) {
        JSONObject json = new JSONObject() {{
            set("inst_id", 148);
            set("inst_template", "SOS,A,{0},{1},{2}#");
            set("params", phone);
            set("is_cover", true);
        }};
        return sendIntruction(imei, json.toString());
    }

    /**
     * 删除sos号码
     *
     * @param imei
     * @param phone
     * @return
     */
    public JSONObject deleteSos(String imei, List<String> phone) {
        JSONObject json = new JSONObject() {{
            set("inst_id", 148);
            set("inst_template", "SOS,D,{0},{1},{2}#");
            set("params", phone);
            set("is_cover", true);
        }};
        return sendIntruction(imei, json.toString());
    }

    /**
     * 打开sos报警
     *
     * @param imei
     * @param status 0 仅 GPRS，1 SMS+GPRS，2 GPRS+SMS+电话；3 GPRS+电话；
     * @return
     */
    public JSONObject openSos(String imei, Integer status) {
        JSONObject json = new JSONObject() {{
            set("inst_id", 119);
            set("inst_template", "SOSALM,ON,{0}#");
            set("params", status);
            set("is_cover", true);
        }};
        return sendIntruction(imei, json.toString());
    }

    /**
     * 十分钟上传一次位置信息
     *
     * @param imei
     * @param time
     * @return
     */
    public JSONObject setTimingGps(String imei, Integer time) {
        JSONObject json = new JSONObject() {{
            set("inst_id", 111850);
            set("inst_template", "MODE,1#");
            //set("params", status);
            set("is_cover", true);
        }};
        return sendIntruction(imei, json.toString());
    }

    /**
     * 设置白名单
     *
     * @param imei
     * @param phone
     * @return
     */
    public JSONObject setWhiteList(String imei, List<String> phone) {
        while (phone.size() < 30) {
            phone.add("");
        }
        JSONObject json = new JSONObject() {{
            set("inst_id", 166);
            set("inst_template",
                "WN&&A&&{0}&&{1}&&{2}&&{3}&&{4}&&{5}&&{6}&&{7}&&{8}&&{9}&&{10}&&{11}&&{12}&&{13}&&{14}&&{15}&&{16}&&{17}&&{18}&&{19}&&{20}&&{21}&&{22}&&{23}&&{24}&&{25}&&{26}&&{27}&&{28}&&{29}##");
            set("params", phone);
            set("is_cover", true);
        }};
        JSONObject res = sendIntruction(imei, json.toString());
        return res;
    }

    /**
     * 设置隐身时间
     *
     * @param imei
     * @param time 时间段  'HH:mm-HH:mm'
     * @return
     */
    public JSONObject setStealth(String imei, List<String> time) {
        JSONObject json = new JSONObject() {{
            set("inst_id", 137);
            set("inst_template",
                "TIME|0|{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}]{9}|{10}|{11}|{12}|{13}|{14}|{15}|{16}]{17}|{18}|{19}|{20}|{21}|{22}|{23}|{24}}");
            set("params", time);
            set("is_cover", true);
        }};
        return sendIntruction(imei, json.toString());
    }

    /**
     * 立即定位
     *
     * @param imei
     * @return
     */
    public JSONObject nowGps(String imei) {
        JSONObject json = new JSONObject() {{
            set("inst_id", 111648);
            set("inst_template", "LJDW#");
            set("is_cover", true);
        }};
        return sendIntruction(imei, json.toString());
    }

    /**
     * 设置定时定位间隔
     *
     * @param time
     * @return
     */
    public JSONObject setGpsTime(Integer time) {
        return null;
    }


}
