package com.ningdatech.carapi.irs.service.impl;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.basic.util.NdDateUtils;
import com.ningdatech.cache.model.cache.CacheKey;
import com.ningdatech.cache.repository.CachePlusOps;
import com.ningdatech.carapi.car.position.entity.VehiclePositionInfo;
import com.ningdatech.carapi.car.position.service.IVehiclePositionInfoService;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfo;
import com.ningdatech.carapi.car.vehicle.service.IVehicleBaseInfoService;
import com.ningdatech.carapi.irs.model.entity.VehicleAccidentIrsData;
import com.ningdatech.carapi.irs.service.AccidentService;
import com.ningdatech.carapi.irs.service.IVehicleAccidentIrsDataService;
import com.ningdatech.carapi.irs.service.RefreshKeyService;
import com.ningdatech.carapi.irs.utils.Md5Utils;
import com.ningdatech.carapi.safe.constant.AccidentTypeEnum;
import com.ningdatech.carapi.safe.constant.VehicleAccidentReportStatusEnum;
import com.ningdatech.carapi.safe.entity.NdVehicleAccident;
import com.ningdatech.carapi.safe.entity.NdVehicleAccidentDead;
import com.ningdatech.carapi.safe.service.INdVehicleAccidentDeadService;
import com.ningdatech.carapi.safe.service.INdVehicleAccidentService;
import com.ningdatech.carapi.scheduler.contants.TaskContant;
import com.ningdatech.carapi.sys.entity.Company;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.sys.service.CompanyService;
import com.ningdatech.file.utils.StrPool;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @Classname AccidentServieImpl
 * @Description
 * @Date 2023/3/1 16:58
 * @Author PoffyZhang
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AccidentServieImpl implements AccidentService {

    private final RestTemplate restTemplate;
    private final RefreshKeyService refreshKeyService;
    private final INdVehicleAccidentService vehicleAccidentService;
    private final INdVehicleAccidentDeadService vehicleAccidentDeadService;
    private final CachePlusOps cachePlusOps;
    private final IVehicleAccidentIrsDataService accidentIrsDataService;
    private final IVehicleBaseInfoService vehicleBaseInfoService;
    private final CompanyService companyService;
    private final RegionsCacheHelper regionsCacheHelper;
    private final IVehiclePositionInfoService iVehiclePositionInfoService;

    @Override
    public List<String> getAccident() {
        // 应用appKey
        String appKey = "A330000100000202105003941";
        // app密钥
        String appSecret = "e07fd4471e92410d9860282d939b1217";

        // 刷新秘钥
        String requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret);
        log.info("requestSecret : {}",requestSecret);

        // 请求签名
        Long requestTime  = System.currentTimeMillis();
        String sign = Md5Utils.hash(appKey + requestSecret + requestTime);
        String url = "https://interface.zjzwfw.gov.cn/gateway/api/001003007/certificate/4c7ECl4H7xX309J8.htm";

        // 事故编号
        String sgbh1 = "330783120230000035";

        List<String> sgbhList = Lists.newArrayList();
        sgbhList.add(sgbh1);

        List<String> resList = Lists.newArrayList();
        for (String sgbh : sgbhList) {

            MultiValueMap<String, Object> map = new LinkedMultiValueMap();
            String projectId = "9000001120230507162550676";
            map.add("appKey", appKey);
            map.add("requestTime", requestTime);
            map.add("projectId", projectId);
            map.add("sgbh", sgbh);
            map.add("sign", sign);
             map.add("additional", "{}");
             map.add("Organization", "测试部门");
             map.add("Organization_ID", "123123");
             map.add("powerMatters", "12131212");
             map.add("subPowerMatters", "123");
             map.add("User_ID", "11111");
             map.add("User_Name", "sasasa");
            ResponseEntity<String> responseEntity = null;
            String res = null;

            try {
                log.info("请求参数 :{}", JSON.toJSONString(map));
                res = restTemplate.postForObject(url, map, String.class);
                log.info("[RestTemplateTest-事故责任认定书] http request :{}", res);
            } catch (Exception e) {
                log.error("[RestTemplateTest-事故责任认定书] http request error:" + e);
            }
            resList.add(res);
        }
        return resList;
    }

    @Override
    public List<String> accidentQuery() {

        // 应用appKey
        String appKey = "A330000100000202105003941";
        String appSecret = "e07fd4471e92410d9860282d939b1217";
        String innerAppKey = "210a2657177f478c808381deb13a4dac";

        // 刷新秘钥
        //String requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret);

        String url = "https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003007/dataSharing/YT9d9lbynbdwae2a.htm";
        // 获取车牌号的所有事故信息
        Map<String, List<VehicleAccidentIrsData>> accidentIrsDataMap = accidentIrsDataService.list().stream()
                .collect(Collectors.groupingBy(VehicleAccidentIrsData::getCarPlate));
        // 车牌号
        //List<String> hphmList = Lists.newArrayList("浙FQ0350", "浙FQ9133", "浙A5W918", "皖CE7498", "浙A08C01", "浙A10B67",
        //        "浙A2X587", "浙A32C01", "浙A58D51", "浙A5W612", "浙A6T266", "浙A7T769", "浙A87A99", "浙A8V378",
        //        "浙A8X675", "浙A9W395", "浙C10503", "浙C18690", "浙C29834", "浙C31707", "浙C50774", "浙C52266",
        //        "浙C60570", "浙CB1067", "浙CD7156", "浙CD9307", "浙CM0185", "浙CM0530", "浙D06281", "浙D21710",
        //        "浙DE6628", "浙DK8334", "浙DR7626", "浙DS4531", "浙DT9961", "浙DW0280", "浙E22736", "浙E26621",
        //        "浙E35787", "浙E36017", "浙E61296", "浙E65230", "浙E66392", "浙E68952", "浙E69691", "浙FDJ589",
        //        "浙FDS332", "浙FG1096", "浙FL9735", "浙FN0693", "浙FN3161", "浙FP2719", "浙FV1233", "浙G26527",
        //        "浙G56057", "浙G57250", "浙G57322", "浙G59700", "浙G59773", "浙G71275", "浙G72831", "浙G72953",
        //        "浙G80298", "浙G97198", "浙H22426", "浙JB0993", "浙JB9232", "浙KK3520", "浙KK9576", "浙KM1560",
        //        "浙A5U783", "浙DJ3611", "浙A6Y375", "浙A6U922", "浙A6W577", "浙E28698", "浙EA7598", "浙E26285",
        //        "浙FH5719", "浙FQ0535", "浙G95837", "浙G88336", "浙G83080", "浙G83221", "浙KK9580", "浙KF2283",
        //        "浙J53439", "浙J96011", "浙J36206", "浙JB7869", "浙J21786", "浙JA6561", "浙J02703", "浙CD0103",
        //        "浙CH9707", "浙CM9758", "浙CL3917", "浙L17121", "浙D05980", "浙J17217", "浙H38803", "浙JA5611",
        //        "浙DH3577", "浙A32C01", "浙D18098", "浙A3Z386", "浙FAG361", "浙A8V905", "浙A98A65", "浙DV2412",
        //        "浙D16351", "浙H26806", "浙CL1381", "浙KK7680", "浙J00625", "浙G82887", "浙CJ3879", "浙L26560",
        //        "浙J36737", "浙A83C69", "浙L23611", "浙A10B22", "浙B0M838", "浙BX9108");

        //List<String> hphmList = Lists.newArrayList("浙E69638", "浙FN3726", "浙E67275", "浙DJ9937", "浙G27718");
        //List<String> hphmList = Lists.newArrayList("浙A7V557", "浙A37B22", "浙G50189", "浙CH6355",
        //        "浙A03E89", "浙DS6620");
        List<String> hphmList = Lists.newArrayList("浙A6P887", "浙G63797", "浙J01696", "浙C37222");


        // 号牌种类
        String hpzl = "01";
        int cnt = 0;
        List<String> resList = Lists.newArrayList();
        String[] carPlates = hphmList.stream().toArray(String[]::new);
        for (int i = 0; i < carPlates.length; i++) {
            String carPlate = carPlates[i];
            String dataJsonStr;
            dataJsonStr = accidentQuery(carPlate,i);
            log.info("此次访问的事故车牌号为 {}", carPlate);
            JSONObject object = JSON.parseObject(dataJsonStr, JSONObject.class);
            String data = object.getString("datas");
            List<String> array = JSON.parseArray(data, String.class);
            if (CollUtil.isEmpty(array)) {
                log.info("该车牌号没有事故信息!");
                continue;
            }
            cnt = i + 1;
            log.info("已访问事故查询IRS接口 {} 次", cnt);
            for (String datas : array) {
                if (StrUtil.isNotBlank(datas)) {
                    List<JSONObject> accidentArray = JSON.parseArray(datas, JSONObject.class);
                    if (CollUtil.isEmpty(accidentArray)) {
                        log.info("该车牌号没有事故信息!");
                        continue;
                    }

                    for (JSONObject jsonObject : accidentArray) {
                        VehicleAccidentIrsData accidentIrsData = new VehicleAccidentIrsData();
                        accidentIrsData.setCarPlate(carPlate);
                        String jsonString = jsonObject.toJSONString();
                        accidentIrsData.setJsonStrData(jsonString);
                        // 获取事故日期
                        Timestamp sgfssj = jsonObject.getTimestamp("SGFSSJ");
                        LocalDateTime accidentTime = LocalDateTimeUtil.of(sgfssj);
                        if (accidentIrsDataMap.containsKey(carPlate)) {
                            List<VehicleAccidentIrsData> dataList = accidentIrsDataMap.get(carPlate);
                            Map<LocalDateTime, VehicleAccidentIrsData> dataMap = dataList.stream()
                                    .collect(Collectors.toMap(VehicleAccidentIrsData::getAccidentTime, v -> v));
                            if (dataMap.containsKey(accidentTime)) {
                                VehicleAccidentIrsData irsData = dataMap.get(accidentTime);
                                // 数据已经存在
                                accidentIrsData.setId(irsData.getId());
                            }
                        }
                        accidentIrsData.setAccidentTime(accidentTime);
                        accidentIrsData.setCreateOn(LocalDateTime.now());
                        accidentIrsData.setUpdateOn(LocalDateTime.now());
                        accidentIrsDataService.saveOrUpdate(accidentIrsData);
                    }
                }
            }
            resList.add(dataJsonStr);
        }

        //for (String hphm : hphmList) {
        //
        //    // 请求秘钥
        //    CacheKey requestKey = new CacheKey(TaskContant.RedisKey.IRS_ACCIDENT_QUERY_REQUEST_SECRET_TEST);
        //    // 刷新密钥
        //    CacheKey refreshKey = new CacheKey(TaskContant.RedisKey.IRS_ACCIDENT_QUERY_REFRESH_SECRET_TEST);
        //    // 根据key获取缓存中的请求秘钥和刷新密钥
        //    String requestSecret = cachePlusOps.get(requestKey);
        //    String refreshSecret = cachePlusOps.get(refreshKey);
        //
        //    // 任务第一次调用接口，获取刷新秘钥和请求秘钥,并保存到redis中
        //    try {
        //        if (Objects.nonNull(refreshSecret)) {
        //            requestSecret = refreshKeyService.refreshRequestSecret(appKey, requestKey, refreshKey, refreshSecret);
        //            if (requestSecret == null) {
        //                requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
        //            }
        //        } else {
        //            requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
        //        }
        //    } catch (Exception e) {
        //        log.error("获取刷新密钥失败:{},此次事故查询车牌号为{}", e.getMessage(), hphm);
        //        return null;
        //    }
        //    if (Objects.isNull(refreshSecret)) {
        //        try {
        //            requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
        //            if (requestSecret == null) {
        //                return null;
        //            }
        //        } catch (Exception e) {
        //            log.error("获取刷新密钥失败:{},此次事故查询车牌号为{}", e.getMessage(), hphm);
        //            return null;
        //        }
        //    }
        //    // 不是第一次调用,看请求秘钥是否过期
        //    // 刷新密钥有效期两天，而定时任务每天都会执行一次，每次任务执行又会更新刷新密钥，所以刷新密钥不会过期
        //    // 只需判断请求秘钥是否过期
        //    else if (Objects.isNull(requestSecret)) {
        //        try {
        //            // 调用IRS刷新秘钥接口，更新刷新密钥和请求秘钥
        //            requestSecret = refreshKeyService.refreshRequestSecret(appKey, requestKey, refreshKey, refreshSecret);
        //            if (requestSecret == null) {
        //                requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
        //            }
        //        } catch (Exception e) {
        //            log.error("刷新请求密钥失败:{},此次事故查询车牌号为{}", e.getMessage(), hphm);
        //            return null;
        //        }
        //    }
        //
        //    // 请求签名
        //    Long requestTime  = System.currentTimeMillis();
        //    String sign = Md5Utils.hash(appKey + requestSecret + requestTime);
        //
        //    MultiValueMap<String, Object> map = new LinkedMultiValueMap();
        //    // 附加信息
        //    map.add("additional","{\"powerMatters\":\"许可-0000-00\",\"subPowerMatters\":\"许可-0000-0101\",\"accesscardId\":\"33071918111111784523\"}");
        //    map.add("appKey",appKey);
        //    map.add("requestTime",requestTime);
        //    map.add("sign",sign);
        //    map.add("hpzl",hpzl);
        //    map.add("hphm",hphm);
        //    String res = null;
        //    try {
        //        HttpHeaders headers = new HttpHeaders();
        //        headers.add("innerAppKey",innerAppKey);
        //        HttpEntity<Object> httpEntity = new HttpEntity<>(map,headers);
        //        log.info("请求参数 :{}", JSON.toJSONString(map));
        //        res = restTemplate.postForObject(url, httpEntity ,String.class);
        //        log.info("[RestTemplateTest-事故查询] http request :{}", res);
        //    } catch (Exception e) {
        //        log.error("[RestTemplateTest-事故查询] http request error", e);
        //    }
        //    resList.add(res);
        //}

        // 更新事故数据
        updateAccidentData();
        log.info("更新事故数据完成!");
        String s = resList.toString();
        log.info("查询结果为：" + s);

        return resList;
    }

    @Override
    public String accidentQuery(String hphm) {
        // 应用appKey
        String appKey = "A330000100000202105003941";
        String appSecret = "e07fd4471e92410d9860282d939b1217";
        String innerAppKey = "210a2657177f478c808381deb13a4dac";
        String hpzl = "01";

        // 刷新秘钥
        String requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret);

        // 请求签名
        Long requestTime  = System.currentTimeMillis();
        String sign = Md5Utils.hash(appKey + requestSecret + requestTime);
        String url = "https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003007/dataSharing/YT9d9lbynbdwae2a.htm";

        MultiValueMap<String, Object> map = new LinkedMultiValueMap();
        // 附加信息
        map.add("additional","{\"powerMatters\":\"许可-0000-00\",\"subPowerMatters\":\"许可-0000-0101\",\"accesscardId\":\"33071918111111784523\"}");
        map.add("appKey",appKey);
        map.add("requestTime",requestTime);
        map.add("sign",sign);
        map.add("hpzl",hpzl);
        map.add("hphm",hphm);
        String res = null;
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.add("innerAppKey",innerAppKey);
            HttpEntity<Object> httpEntity = new HttpEntity<>(map,headers);
            log.info("请求参数 :{}", JSON.toJSONString(map));
            res = restTemplate.postForObject(url, httpEntity ,String.class);
            log.info("[RestTemplateTest-事故查询] http request :{}", res);
        } catch (Exception e) {
            log.error("[RestTemplateTest-事故查询] http request error", e);
        }
        return res;
    }

    @Override
    public String accidentQuery(String hphm,Integer index) {
        // 应用appKey
        String appKey = "A330000100000202105003941";
        String appSecret = "e07fd4471e92410d9860282d939b1217";
        String innerAppKey = "210a2657177f478c808381deb13a4dac";
        String hpzl = "01";

        // 请求秘钥
        CacheKey requestKey = new CacheKey(TaskContant.RedisKey.IRS_ACCIDENT_QUERY_REQUEST_SECRET);
        // 刷新密钥
        CacheKey refreshKey = new CacheKey(TaskContant.RedisKey.IRS_ACCIDENT_QUERY_REFRESH_SECRET);
        // 根据key获取缓存中的请求秘钥和刷新密钥
        String requestSecret = cachePlusOps.get(requestKey);
        String refreshSecret = cachePlusOps.get(refreshKey);
        if (index == 0) {
            // 任务第一次调用接口，获取刷新秘钥和请求秘钥,并保存到redis中
            try {
                if (Objects.nonNull(refreshSecret)){
                    requestSecret = refreshKeyService.refreshRequestSecret(appKey, requestKey, refreshKey, refreshSecret);
                    if (requestSecret == null) {
                        requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
                    }
                }else {
                    requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
                }
            } catch (Exception e) {
                log.error("获取刷新密钥失败:{},此次事故查询车牌号为{}", e.getMessage(), hphm);
                return null;
            }
        } else if (Objects.isNull(refreshSecret)) {
            try {
                requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
                if (requestSecret == null) {
                    return null;
                }
            } catch (Exception e) {
                log.error("获取刷新密钥失败:{},此次事故查询车牌号为{}", e.getMessage(), hphm);
                return null;
            }
        }
        // 不是第一次调用,看请求秘钥是否过期
        // 刷新密钥有效期两天，而定时任务每天都会执行一次，每次任务执行又会更新刷新密钥，所以刷新密钥不会过期
        // 只需判断请求秘钥是否过期
        else if (Objects.isNull(requestSecret)) {
            try {
                // 调用IRS刷新秘钥接口，更新刷新密钥和请求秘钥
                requestSecret = refreshKeyService.refreshRequestSecret(appKey, requestKey, refreshKey, refreshSecret);
                if (requestSecret == null) {
                    requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
                }
            } catch (Exception e) {
                log.error("刷新请求密钥失败:{},此次事故查询车牌号为{}", e.getMessage(), hphm);
                return null;
            }
        }
        

        // 请求签名
        Long requestTime  = System.currentTimeMillis();
        log.info("请求参数中请求秘钥为：" + requestSecret);
        String sign = Md5Utils.hash(appKey + requestSecret + requestTime);
        String url = "https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003007/dataSharing/YT9d9lbynbdwae2a.htm";

        MultiValueMap<String, Object> map = new LinkedMultiValueMap();
        // 附加信息
        map.add("additional","{\"powerMatters\":\"许可-0000-00\",\"subPowerMatters\":\"许可-0000-0101\",\"accesscardId\":\"33071918111111784523\"}");
        map.add("appKey",appKey);
        map.add("requestTime",requestTime);
        map.add("sign",sign);
        map.add("hpzl",hpzl);
        map.add("hphm",hphm);
        HttpHeaders headers = new HttpHeaders();
        headers.add("innerAppKey", innerAppKey);
        HttpEntity<Object> httpEntity = new HttpEntity<>(map, headers);
        log.info("请求参数 :{}", JSON.toJSONString(map));
        String res = restTemplate.postForObject(url, httpEntity, String.class);
        log.info("[RestTemplateTest-事故查询] http request :{}", res);
        return res;
    }

    @Override
    public String getAccident(String sgbh) {
        // 应用appKey
        String appKey = "A330000100000202105003941";
        // app密钥
        String appSecret = "e07fd4471e92410d9860282d939b1217";

        // 请求秘钥
        CacheKey requestKey = new CacheKey(TaskContant.RedisKey.IRS_ACCIDENT_DUTY_REQUEST_SECRET);
        // 刷新密钥
        CacheKey refreshKey = new CacheKey(TaskContant.RedisKey.IRS_ACCIDENT_DUTY_REFRESH_SECRET);
        // 根据key获取缓存中的请求秘钥和刷新密钥
        String requestSecret = cachePlusOps.get(requestKey);
        String refreshSecret = cachePlusOps.get(refreshKey);

        try {
            // 不是第一次调用接口，获取刷新秘钥和请求秘钥,并保存到redis中
            if (Objects.nonNull(refreshSecret)) {
                requestSecret = refreshKeyService.refreshRequestSecret(appKey, requestKey, refreshKey, refreshSecret);
                if (requestSecret == null) {
                    requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
                }
            } else {
                // 第一次调用接口，获取刷新秘钥和请求秘钥,并保存到redis中
                requestSecret = refreshKeyService.getRequestSecret(appKey, appSecret, requestKey, refreshKey);
            }
        } catch (Exception e) {
            log.error("获取刷新密钥失败:{},此次事故责任认定书事故编号为{}", e.getMessage(), sgbh);
            return null;
        }
        
        log.info("requestSecret : {}",requestSecret);

        // 请求签名
        Long requestTime  = System.currentTimeMillis();
        String sign = Md5Utils.hash(appKey + requestSecret + requestTime);
        String url = "https://interface.zjzwfw.gov.cn/gateway/api/001003007/certificate/4c7ECl4H7xX309J8.htm";

        MultiValueMap<String, Object> map = new LinkedMultiValueMap();
        String projectId = "9000001120230507162550676";
        map.add("appKey", appKey);
        map.add("requestTime", requestTime);
        map.add("projectId", projectId);
        map.add("sgbh", sgbh);
        map.add("sign", sign);
        map.add("additional", "{}");
        map.add("Organization", "测试部门");
        map.add("Organization_ID", "123123");
        map.add("powerMatters", "12131212");
        map.add("subPowerMatters", "123");
        map.add("User_ID", "11111");
        map.add("User_Name", "sasasa");
        ResponseEntity<String> responseEntity = null;
        String res = null;

        try {
            log.info("请求参数 :{}", JSON.toJSONString(map));
            res = restTemplate.postForObject(url, map, String.class);
            log.info("[RestTemplateTest-事故责任认定书] http request :{}", res);
        } catch (Exception e) {
            log.error("[RestTemplateTest-事故责任认定书] http request error:" + e);
        }

        return res;
    }

    @Override
    public String updateAccident() {
        // 获取认定内容为空，事故编号不为空的事故数据
        List<NdVehicleAccident> accidents = vehicleAccidentService.list().stream()
                .filter(v -> Objects.nonNull(v.getAccidentNo()) && Objects.isNull(v.getFirmContent()))
                .collect(Collectors.toList());

        // 从车辆死亡事故信息表中获取事故编号
        Map<String, Long> deadAccidentNoMap = vehicleAccidentDeadService.list(Wrappers.lambdaQuery(NdVehicleAccidentDead.class)
                        .select(NdVehicleAccidentDead::getAccidentNo,NdVehicleAccidentDead::getId)).stream()
                // 筛选出事故编号不为空，但没有认定内容的死亡事故数据
                .filter(v -> Objects.nonNull(v.getAccidentNo()) && Objects.isNull(v.getFirmContent()))
                .collect(Collectors.toMap(v -> v.getAccidentNo() + StrPool.DASH + v.getCarPlate(),NdVehicleAccidentDead::getId));

        // 如果有事故编号且都已经有了认定内容，则不运行
        if (CollUtil.isEmpty(accidents)){
            log.info("此次任务数据量为空!");
            return null;
        }

        for (NdVehicleAccident accident : accidents) {
            String carPlate = accident.getCarPlate();
            String sgbh = accident.getAccidentNo();
            // 获取事故责任认定书返回结果
            String dataJsonStr = getAccident(sgbh);
            JSONObject object = JSON.parseObject(dataJsonStr, JSONObject.class);
            // 获取返回数据
            String datas = object.getString("datas");
            JSONObject jsonObject = JSON.parseObject(datas, JSONObject.class);
            // 获取结构化数据签名结果
            // 未查询到结果
            if (Objects.isNull(jsonObject)){
                log.info("事故编号{}未查询到事故责任认定书数据",sgbh);
                continue;
            }
            String elcLicenceStruct = jsonObject.getString("ELC_LICENCE_STRUCT");
            JSONObject elcLicenceStructObject = JSON.parseObject(elcLicenceStruct, JSONObject.class);
            // 未查询到结果
            if (Objects.isNull(elcLicenceStructObject)){
                log.info("事故编号{}未查询到事故责任认定书数据",sgbh);
                continue;
            }
            // 获取结构化数据
            String data = elcLicenceStructObject.getString("DATA");
            JSONObject dataObject = JSON.parseObject(data, JSONObject.class);
            // 未查询到结果
            if (Objects.isNull(dataObject)){
                log.info("事故编号{}未查询到事故责任认定书数据",sgbh);
                continue;
            }
            // 获取认定内容
            String rdnr = dataObject.getString("RDNR");
            // 更新认定内容到车辆事故信息表
            accident.setFirmContent(rdnr);
            vehicleAccidentService.updateById(accident);
            // 如果是亡人事故，更新认定内容到车辆死亡事故信息表
            String key = sgbh + StrPool.DASH + carPlate;
            if (deadAccidentNoMap.containsKey(key)){
                Long deadAccidentId = deadAccidentNoMap.get(key);
                NdVehicleAccidentDead deadAccident = vehicleAccidentDeadService.getById(deadAccidentId);
                deadAccident.setFirmContent(rdnr);
                vehicleAccidentDeadService.updateById(deadAccident);
            }
        }
        return "更新成功";
    }

    /**
     * 从IRS事故数据表中更新数据到车辆事故数据表中
     *
     * @return void
     * @author CMM
     * @since 2023/05/16 10:26
     */
    private void updateAccidentData() {

        // 从IRS事故数据表中更新数据到车辆事故数据表中
        Map<String, List<VehicleAccidentIrsData>> listMap =
                accidentIrsDataService.list().stream().collect(Collectors.groupingBy(VehicleAccidentIrsData::getCarPlate));

        // 获取车牌号
        Set<String> carPlateList =
                accidentIrsDataService.list().stream().map(VehicleAccidentIrsData::getCarPlate).collect(Collectors.toSet());

        // 获取车辆基本信息
        List<NdVehicleBaseInfo> vehicleBaseInfos = vehicleBaseInfoService
                .list(Wrappers.lambdaQuery(NdVehicleBaseInfo.class).in(NdVehicleBaseInfo::getCarPlate, carPlateList));
        Map<String, NdVehicleBaseInfo> vehicleBaseInfoMap =
                vehicleBaseInfos.stream().collect(Collectors.toMap(NdVehicleBaseInfo::getCarPlate, v -> v));

        // 获取企业信息
        Map<Long, Company> companyMap =
                companyService.list().stream().collect(Collectors.toMap(Company::getId, c -> c));

        // 获取已经存在的事故数据
        List<NdVehicleAccident> accidentTmpVas = vehicleAccidentService
                .list(Wrappers.lambdaQuery(NdVehicleAccident.class).in(NdVehicleAccident::getCarPlate, carPlateList));
        Map<String, NdVehicleAccident> accidentMap = accidentTmpVas.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(
                                Comparator.comparing(a -> a.getCarPlate() + StrPool.SEMICOLON + a.getAccidentTime()))),
                        ArrayList::new))
                .stream().collect(Collectors.toMap(d -> d.getCarPlate() + d.getAccidentTime(), d -> d));

        // 获取已经存在的死亡事故数据
        List<NdVehicleAccidentDead> deadAccidentTmpVas = vehicleAccidentDeadService.list(
                Wrappers.lambdaQuery(NdVehicleAccidentDead.class).in(NdVehicleAccidentDead::getCarPlate, carPlateList));
        Map<String, NdVehicleAccidentDead> deadAccidentMap = deadAccidentTmpVas.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(
                                Comparator.comparing(a -> a.getCarPlate() + StrPool.SEMICOLON + a.getAccidentTime()))),
                        ArrayList::new))
                .stream().collect(Collectors.toMap(d -> d.getCarPlate() + d.getAccidentTime(), d -> d));

        for (String carPlate : carPlateList) {
            NdVehicleBaseInfo vehicleBaseInfo = vehicleBaseInfoMap.get(carPlate);
            //if (Objects.isNull(vehicleBaseInfo)) {
            //    log.info("该车牌号不在系统中!");
            //    continue;
            //}
            //// 查出对应车牌号关联的责任驾驶员
            // String driverName = vehicleBaseInfo.getResponsibleDriverFirst();
            //
            // if (Objects.isNull(driverName)) {
            // log.info("该车牌号没有责任驾驶员!");
            // continue;
            // }
            Long companyId = null;
            Company company = null;
            if (Objects.nonNull(vehicleBaseInfo)) {
                companyId = vehicleBaseInfo.getCompanyId();
                company = companyMap.get(companyId);
            }

            // 获取IRS事故数据
            List<VehicleAccidentIrsData> accidentIrsDataList = listMap.get(carPlate);

            for (VehicleAccidentIrsData accidentIrsData : accidentIrsDataList) {
                // 解析获取事故时间等信息
                String jsonStrData = accidentIrsData.getJsonStrData();
                JSONObject jsonObject = JSON.parseObject(jsonStrData);

                // 获取行政区划
                String xzqh = jsonObject.getString("XZQH");
                // 获取区域信息
                Long regionId = regionsCacheHelper.getIdByCode(xzqh);
                String regionName = regionsCacheHelper.getDisplayName(regionId);
                // 获取事故地点
                String sgdd = jsonObject.getString("SGDD");
                // 获取车辆类型
                Integer vehicleType = null;
                if (Objects.nonNull(vehicleBaseInfo)) {
                    vehicleType = vehicleBaseInfo.getVehicleType();
                }
                // 获取受伤人数
                Integer ssrs = jsonObject.getInteger("SSRS");
                // 获取事故日期
                Timestamp sgfssj = jsonObject.getTimestamp("SGFSSJ");
                LocalDateTime accidentTime = LocalDateTimeUtil.of(sgfssj);
                // 获取简要案情
                String jyaq = jsonObject.getString("JYAQ");
                // 获取事故编号
                String sgbh = jsonObject.getString("SGBH");
                // 获取经纬度电子坐标
                String dzzb = jsonObject.getString("DZZB");
                String longitude = null;
                String latitude = null;
                if (StringUtils.isNotBlank(dzzb) && dzzb.contains(StrPool.COMMA)) {
                    String[] split = dzzb.split(StrPool.COMMA);
                    Double longitudeD = Double.valueOf(split[0]);
                    Double latitudeD = Double.valueOf(split[1]);
                    DecimalFormat df = new DecimalFormat("#.###");
                    longitude = df.format(longitudeD);
                    latitude = df.format(latitudeD);
                } else {
                    // 交管事故数据未上传经纬度坐标，从当天的GPS数据中根据车牌号和事故时间查询经纬度
                    LocalDateTime startTime = LocalDateTimeUtil.parse(
                            NdDateUtils.format(accidentTime, DatePattern.NORM_DATETIME_MINUTE_PATTERN),
                            DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                    LocalDateTime endTime = LocalDateTimeUtil.parse(
                            NdDateUtils.format(accidentTime.plusMinutes(1), DatePattern.NORM_DATETIME_MINUTE_PATTERN),
                            DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                    // 如果跨天了就设置相同地查询边界
                    if (!NdDateUtils.format(startTime, DatePattern.NORM_DATE_PATTERN)
                            .equals(NdDateUtils.format(endTime, DatePattern.NORM_DATE_PATTERN))) {
                        endTime = startTime;
                    }

                    List<VehiclePositionInfo> vehiclePositionInfos;
                    try {
                        vehiclePositionInfos = iVehiclePositionInfoService.dynamicGpsTableHistorySearch(carPlate,
                                accidentTime, endTime, NdDateUtils.format(startTime, "yyyy_MM_dd"));
                        if (CollUtil.isNotEmpty(vehiclePositionInfos)) {
                            VehiclePositionInfo positionInfo;
                            List<VehiclePositionInfo> positionInfoList = vehiclePositionInfos.stream()
                                    .filter(v -> v.getUpdateTime().equals(accidentTime)).collect(Collectors.toList());
                            if (CollUtil.isNotEmpty(positionInfoList)) {
                                positionInfo = positionInfoList.get(0);
                            } else {
                                // 没有时间完全一样的GPS数据，就取第一个
                                positionInfo = vehiclePositionInfos.get(0);
                            }
                            longitude = String.valueOf(positionInfo.getCarLongitude());
                            latitude = String.valueOf(positionInfo.getCarLatitude());
                        }
                    } catch (Exception e) {
                        // GPS数据中查询不到数据(GPS表可能被删除)
                        log.error(e.getMessage());
                    }
                }

                // 获取当场、24小时、3日内、7日内、30日内死亡人数
                Integer swrs = Objects.nonNull(jsonObject.getInteger("SWRS")) ? jsonObject.getInteger("SWRS") : 0;
                Integer swrs24 = Objects.nonNull(jsonObject.getInteger("SWRS24")) ? jsonObject.getInteger("SWRS24") : 0;
                Integer swrs3 = Objects.nonNull(jsonObject.getInteger("SWRS3")) ? jsonObject.getInteger("SWRS3") : 0;
                Integer swrs7 = Objects.nonNull(jsonObject.getInteger("SWRS7")) ? jsonObject.getInteger("SWRS7") : 0;
                Integer swrs30 = Objects.nonNull(jsonObject.getInteger("SWRS30")) ? jsonObject.getInteger("SWRS30") : 0;
                // 有死亡人数,再插入到死亡事故表中
                if (swrs != 0 || swrs24 != 0 || swrs3 != 0 || swrs7 != 0 || swrs30 != 0) {
                    // 插入数据到死亡事故表中
                    NdVehicleAccidentDead accidentDead = new NdVehicleAccidentDead();
                    // 判断是否已经插入过
                    if (deadAccidentMap.containsKey(carPlate + accidentTime)) {
                        NdVehicleAccidentDead dead = deadAccidentMap.get(carPlate + accidentTime);
                        accidentDead.setId(dead.getId());
                    }
                    if (swrs30 != 0) {
                        accidentDead.setDeathToll(swrs30);
                    } else if (swrs7 != 0) {
                        accidentDead.setDeathToll(swrs7);
                    } else if (swrs3 != 0) {
                        accidentDead.setDeathToll(swrs3);
                    } else if (swrs24 != 0) {
                        accidentDead.setDeathToll(swrs24);
                    } else {
                        accidentDead.setDeathToll(swrs);
                    }
                    accidentDead.setInjuries(ssrs);
                    accidentDead.setRegionId(regionId);
                    accidentDead.setRegionName(regionName);
                    // 获取事故时间
                    accidentDead.setAccidentTime(accidentTime);
                    accidentDead.setAccidentAddress(sgdd);
                    // 装配车牌号、事故驾驶员、企业名称
                    accidentDead.setCarPlate(carPlate);
                    // accidentDead.setAccidentDriver(driverName);
                    accidentDead.setCompanyId(companyId);
                    if (Objects.nonNull(company)) {
                        accidentDead.setCompanyName(company.getName());
                    }
                    // 是否上报默认为未上报
                    accidentDead.setReportStatus(VehicleAccidentReportStatusEnum.UNDER_REPORT.getCode());
                    accidentDead.setBriefCase(jyaq);
                    accidentDead.setAccidentNo(sgbh);
                    accidentDead.setLongitude(longitude);
                    accidentDead.setLatitude(latitude);
                    vehicleAccidentDeadService.saveOrUpdate(accidentDead);
                }
                // 插入到事故表中
                NdVehicleAccident accident = new NdVehicleAccident();
                // 判断事故类型
                if (swrs != 0 || swrs24 != 0 || swrs3 != 0 || swrs7 != 0 || swrs30 != 0){
                    accident.setAccidentType(AccidentTypeEnum.DEAD.getCode());
                } else if (Objects.nonNull(ssrs) && ssrs > 0) {
                    accident.setAccidentType(AccidentTypeEnum.INJURY.getCode());
                }else {
                    accident.setAccidentType(AccidentTypeEnum.OTHER.getCode());
                }
                // 获取已经存在的事故信息
                NdVehicleAccident vehicleAccident = accidentMap.get(carPlate + accidentTime);
                // 获取事故时间
                if (accidentMap.containsKey(carPlate + accidentTime)) {
                    accident.setId(vehicleAccident.getId());
                }
                accident.setInjuries(ssrs);
                if (swrs30 != 0) {
                    accident.setDeathToll(swrs30);
                } else if (swrs7 != 0) {
                    accident.setDeathToll(swrs7);
                } else if (swrs3 != 0) {
                    accident.setDeathToll(swrs3);
                } else if (swrs24 != 0) {
                    accident.setDeathToll(swrs24);
                } else {
                    accident.setDeathToll(swrs);
                }
                accident.setRegionId(regionId);
                accident.setRegionName(regionName);
                // 获取事故时间
                accident.setAccidentTime(accidentTime);
                accident.setAccidentAddress(sgdd);
                // 装配车牌号、事故驾驶员、车辆类型、企业名称
                accident.setCarPlate(carPlate);

                // accident.setAccidentDriver(driverName);
                accident.setVehicleType(vehicleType);
                accident.setCompanyId(companyId);
                if (Objects.nonNull(company)) {
                    accident.setCompanyName(company.getName());
                }
                // 是否上报默认为未上报
                accident.setReportStatus(VehicleAccidentReportStatusEnum.UNDER_REPORT.getCode());
                accident.setBriefCase(jyaq);
                accident.setAccidentNo(sgbh);
                accident.setLongitude(longitude);
                accident.setLatitude(latitude);
                vehicleAccidentService.saveOrUpdate(accident);
            }
        }
    }

}
