package com.prolog.rdc.tms.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.framework.core.exception.BizException;
import com.prolog.rdc.tms.model.dto.e6.EquipInfoDTO;
import com.prolog.rdc.tms.model.dto.e6.EquipInfoHistoryDTO;
import com.prolog.rdc.tms.model.dto.e6.TrackDetailDTO;
import com.prolog.rdc.tms.model.dto.e6.VehicleInfoDTO;
import com.prolog.rdc.tms.model.dto.e6.VehicleTemperatureInfoDTO;
import com.prolog.rdc.tms.model.dto.e6.VehiclesAllAlarmInfoDTO;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author hongbo.pan
 * @date 2023/3/21
 */
@Slf4j
public class E6GpsUtil {

    /**
     * TOPIC
     */
    private static final String TOPIC = E6GpsUtil.class.getSimpleName();

    /**
     * 公钥
     */
    private static final String APPKEY = "2C205CCC-9FA3-4D56-A9C9-B5A61A394B10";

    /**
     * 私钥
     */
    private static final String APPSECRET = "79B6D2DC-E641-4F2F-94F3-91802476C32F";

    /**
     * 返回格式
     */
    private static final String FORMAT_JSON = "json";

    /**
     * 易流接口地址
     */
    public static final String INTERFACE_URL = "https://api.e6yun.com/public/v3/Inface/Call";

    /**
     * 易流接口地址
     */
    public static final String REPORT_URL = "https://api.e6yun.com/public/v3/StatisticsReport/Call";

    /**
     * 易流接口地址
     */
    public static final String BASIC_URL = "https://api.e6yun.com/public/v4/BASIC/api";

    /**
     * 成功
     */
    private static final String SUCCESS = "1";

    /**
     * 参数都正确，没有数据
     */
    private static final String NO_DATA = "5";

    /**
     * 超时时间
     */
    private static final int TIMEOUT = 10 * 60 * 1000;

    /**
     * 签名
     * @param map
     * @return
     */
    private static String sign(Map<String, Object> map) {
        String signData = map.keySet().stream().sorted().map(key -> {
            if (map.get(key) != null) {
                return key + map.get(key);
            } else {
                return StrUtil.EMPTY;
            }
        }).collect(Collectors.joining());
        log.info("topic={}，签名数据={}", TOPIC, signData);
        signData = APPSECRET + signData + APPSECRET;
        String md5Str = MD5Util.str2MD5(signData).toUpperCase();
        log.info("topic={}，签名={}", TOPIC, md5Str);
        return md5Str;
    }

    private static Map<String, Object> paramMap(String url, Map<String, Object> map) {
        Map<String, Object> paramMap = Maps.newHashMap();
        if (MapUtil.isNotEmpty(map)) {
            paramMap.putAll(map);
        }
        paramMap.put("timestamp", DateUtil.now());
        paramMap.put("format", FORMAT_JSON);
        paramMap.put("appkey", APPKEY);
//        paramMap.put("sessionid", "");
        String sign = sign(paramMap);
        paramMap.put("sign", sign);
        log.info("topic={}，请求url={}，入参={}", TOPIC, url, JSON.toJSONString(paramMap));
        return paramMap;
    }

    /**
     * 发送post
     * @param url
     * @param map
     * @return
     */
    public static String post(String url, Map<String, Object> map) {
        String result;
        try {
            result = HttpUtil.post(url, paramMap(url, map), TIMEOUT);
        } catch (Exception e) {
            log.error("topic={}，title={}，请求失败", TOPIC, "post", e);
            throw new BizException(e.getMessage());
        }
        log.info("topic={}，title={}，返回结果={}", TOPIC, "post", result);
        if (StrUtil.isBlank(result)) {
            throw new BizException("返回结果为空");
        }
        JSONObject jsonObject = JSON.parseObject(result);
        JSONObject resultJson = jsonObject.getJSONObject("result");
        String code = resultJson.getString("code");
        if (!SUCCESS.equals(code)) {
            if (NO_DATA.equals(code)) {
                return JSON.toJSONString(Lists.newArrayList());
            }
            throw new BizException(resultJson.getString("message"));
        }
        String data = resultJson.getString("data");
        if (StrUtil.isBlank(data)) {
            throw new BizException("返回数据为空");
        }
        return data;
    }

    /**
     * 发送post
     * @param url
     * @param map
     * @return
     */
    public static String post2(String url, Map<String, Object> map) {
        String result;
        try {
            result = HttpUtil.post(url, paramMap(url, map), TIMEOUT);
        } catch (Exception e) {
            log.error("topic={}，title={}，请求失败", TOPIC, "post2", e);
            throw new BizException(e.getMessage());
        }
        log.info("topic={}，title={}，返回结果={}", TOPIC, "post2", result);
        if (StrUtil.isBlank(result)) {
            throw new BizException("返回结果为空");
        }
        JSONObject jsonObject = JSON.parseObject(result);
        String code = jsonObject.getString("code");
        if (!SUCCESS.equals(code)) {
            if (NO_DATA.equals(code)) {
                return JSON.toJSONString(Lists.newArrayList());
            }
            throw new BizException(jsonObject.getString("message"));
        }
        String data = jsonObject.getString("result");
        if (StrUtil.isBlank(data)) {
            throw new BizException("返回数据为空");
        }
        return data;
    }

    /**
     * 格式化时间
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        if (ObjectUtil.isNull(date)) {
            return DateUtil.now();
        } else {
            return DateUtil.format(date, DatePattern.NORM_DATETIME_FORMAT);
        }
    }

//    public static void main(String[] args) {
//        Map<String, Object> map = Maps.newHashMap();
////        String vehicle = "鄂AAR746";
////        String vehicle = "鄂AZF288";
////        map.put("method", "GetVehcileInfo");
////        map.put("vehicle", vehicle);
////        String data = post(INTERFACE_URL, map);
//
////        List<VehicleInfoDTO> vehicleInfoDTOList = JSON.parseArray(data, VehicleInfoDTO.class);
////        System.out.println(JSON.toJSONString(vehicleInfoDTOList));
//
////        map.put("method", "GetTrackDetail");
////        map.put("vehicle", vehicle);
////        map.put("btime", formatDate(DateUtil.offsetDay(new Date(), -1)));
////        map.put("etime", DateUtil.now());
////        String data = E6GpsUtil.post(E6GpsUtil.REPORT_URL, map);
////        List<TrackDetailDTO> trackDetailDTOList = JSON.parseArray(data, TrackDetailDTO.class);
////        System.out.println(JSON.toJSONString(trackDetailDTOList));
//
////        map.put("method", "GetVehicleTemperatureInfo");
////        map.put("vehicle", vehicle);
////        map.put("btime", formatDate(DateUtil.offsetDay(new Date(), -1)));
////        map.put("etime", DateUtil.now());
////        String data = E6GpsUtil.post(E6GpsUtil.REPORT_URL, map);
////        List<VehicleTemperatureInfoDTO> vehicleTemperatureInfoDTOList = JSON.parseArray(data, VehicleTemperatureInfoDTO.class);
////        System.out.println(JSON.toJSONString(vehicleTemperatureInfoDTOList));
//
////        map.put("method", "GetVechilesAllAlarmInfo");
////        map.put("vehicles", vehicle);
////        map.put("btime", formatDate(DateUtil.offsetDay(new Date(), -40)));
////        map.put("etime", DateUtil.now());
////        String data = E6GpsUtil.post(E6GpsUtil.REPORT_URL, map);
////        List<VehiclesAllAlarmInfoDTO> vehiclesAllAlarmInfoDTOList = JSON.parseArray(data, VehiclesAllAlarmInfoDTO.class);
////        System.out.println(JSON.toJSONString(vehiclesAllAlarmInfoDTOList));
//
//        map.put("equipcode", "HR220308105798,HR220308105803");
//        map.put("isoffsetlonlat", "1");
//        String data = E6GpsUtil.post2(E6GpsUtil.BASIC_URL + "/getEquipInfoReal", map);
//        List<EquipInfoDTO> equipInfoDTOList = JSON.parseArray(data, EquipInfoDTO.class);
//        System.out.println(JSON.toJSONString(equipInfoDTOList));
//
////        map.put("equipcode", "HR220308105798");
////        map.put("isoffsetlonlat", "1");
////        map.put("hasPlace", "1");
////        map.put("btime", formatDate(DateUtil.offsetDay(new Date(), -1)));
////        map.put("etime", DateUtil.now());
////        map.put("second", 0);
////        String data = E6GpsUtil.post2(E6GpsUtil.BASIC_URL + "/getEquipInfoHistory", map);
////        List<EquipInfoHistoryDTO> equipInfoHistoryDTOList = JSON.parseArray(data, EquipInfoHistoryDTO.class);
////        System.out.println(JSON.toJSONString(equipInfoHistoryDTOList));
//    }


}
