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

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeejoin.amos.boot.module.common.api.constant.TZSCommonConstant;
import com.yeejoin.amos.boot.module.common.api.enums.IssueMainBodyEnum;
import com.yeejoin.amos.boot.module.common.api.enums.IssueTypeEnum;
import com.yeejoin.amos.boot.module.common.api.enums.ReginStepEnum;
import com.yeejoin.amos.boot.module.cylinder.api.dto.KeyValueDto;
import com.yeejoin.amos.boot.module.cylinder.api.dto.TzBaseEnterpriseInfoDto;
import com.yeejoin.amos.boot.module.cylinder.api.entity.ESCylinderFillingRecordDto;
import com.yeejoin.amos.boot.module.cylinder.api.mapper.DPStatisticsMapper;
import com.yeejoin.amos.boot.module.cylinder.api.service.ITzBaseEnterpriseInfoService;
import com.yeejoin.amos.boot.module.cylinder.biz.dao.ESCylinderFillingRecordRepository;
import com.yeejoin.amos.boot.module.cylinder.flc.api.dto.CityCylinderInfoDto;
import com.yeejoin.amos.boot.module.cylinder.flc.api.dto.CylinderAreaDataDto;
import com.yeejoin.amos.boot.module.cylinder.flc.api.entity.CylinderAreaData;
import com.yeejoin.amos.boot.module.cylinder.flc.api.mapper.CylinderAreaDataMapper;
import com.yeejoin.amos.boot.module.cylinder.flc.api.service.ICylinderAreaDataService;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.RegionModel;
import joptsimple.internal.Strings;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 气瓶区域统计表服务实现类
 *
 * @author system_generator
 * @date 2022-03-08
 */
@Service
public class CylinderAreaDataServiceImpl extends BaseService<CylinderAreaDataDto, CylinderAreaData, CylinderAreaDataMapper> implements ICylinderAreaDataService {

    public final static String LICENSE_IS_OK = "正常";

    public final static String NO_DATA_STR = "--";

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Autowired
    ESCylinderFillingRecordRepository esCylinderFillingRecordRepository;

    @Autowired
    ITzBaseEnterpriseInfoService iTzBaseEnterpriseInfoService;

    private static Map<String, String> regionCodeOrgCodeMap = new ConcurrentHashMap<>();

    @Resource
    private DPStatisticsMapper statisticsMapper;

    /**
     * 分页查询
     */
    public Page<CylinderAreaDataDto> queryForCylinderAreaDataPage(Page<CylinderAreaDataDto> page) {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<CylinderAreaDataDto> queryForCylinderAreaDataList() {
        return this.queryForList("", false);
    }

    public List<CityCylinderInfoDto> getCityCylinderData(String level) {
        return this.queryForList("", false, level).stream()
                .map(v -> CityCylinderInfoDto.builder()
                        .regionName(v.getAreaName())
                        .regionCode(v.getRegionCode())
                        .longitude(v.getLongitude())
                        .latitude(v.getLatitude())
                        .isAlarm(v.getOutOfDateNum() != 0)
                        .cylindersCount(v.getCylinderNum())
                        .stationCount(v.getUnitNum())
                        .build())
                .collect(Collectors.toList());
    }

    public Page<Map<String, Object>> getEarlyWarningStatistics(String regionCode, String appId) {
        Page<Map<String, Object>> page = new Page<>();
        // 是否有充装企业在指定区域下
        Boolean isHavingUnitInRegion = true;
        List<Map<String, Object>> list = Lists.newArrayList();
        Map<String, Object> result1 = Maps.newHashMap();
        Map<String, Object> result2 = Maps.newHashMap();
        // 1.许可有效率
        if (!ValidationUtil.isEmpty(appId)) {
            result1.put("name", "许可有效期");
            result1.put("value", this.getBaseMapper().queryLicenseEfficiencyOneCompany(appId).getStrValue());
        } else if (!ValidationUtil.isEmpty(regionCode)) {
            result1.put("name", "许可有效率(%)");
            result1.put("value", this.getLicenseEfficiencyByRegion(regionCode));
            isHavingUnitInRegion = this.setNoUnitDataStaticInfo(list, result1.get("value").toString());
        }
        if (!ValidationUtil.isEmpty(regionCode) && !isHavingUnitInRegion) {
            return page.setRecords(list);
        }
        // 2.使用登记办理率
        if (!ValidationUtil.isEmpty(appId)) {
            result2.put("name", "使用登记");
            result2.put("value", "已办理");
        } else {
            result2.put("name", "使用登记办理率(%)");
            result2.put("value", "100");
        }
        // 3.检验超期率
        Map<String, Object> result3 = Maps.newHashMap();
        result3.put("name", "检验超期率(%)");
        result3.put("value", this.getBaseMapper().getInspectionExpiredRate(regionCode, appId).get("expiredRate").toString());
        // 4.检验合格率
        Map<String, Object> result4 = Maps.newHashMap();
        result4.put("name", "检验合格率(%)");
        result4.put("value", this.getBaseMapper().getInspectionResultRate(regionCode, appId).get("resultRate").toString());
        // 5.充装检查率
        Map<String, Object> result5 = Maps.newHashMap();
        long totalAll = searchEsCount(false, false, regionCode, appId);
        long totalCheck = searchEsCount(true, false, regionCode, appId);
        long totalResult = searchEsCount(false, true, regionCode, appId);
        result5.put("name", "充装检查率(%)");
        if (totalAll != 0) {
            result5.put("value", new DecimalFormat("#.00").format(((double) totalCheck / totalAll) * 100));
        } else {
            result5.put("value", 0);
        }
        // 6.充装检查合格率
        Map<String, Object> result6 = Maps.newHashMap();
        result6.put("name", "充装检查合格率(%)");
        if (totalAll != 0) {
            result6.put("value", new DecimalFormat("#.00").format(((double) totalResult / totalAll) * 100));
        } else {
            result6.put("value", 0);
        }

        // list中按以下固定顺序返回给前端
        list.add(result1);
        list.add(result3);
        list.add(result5);
        list.add(result2);
        list.add(result4);
        list.add(result6);
        page.setRecords(list);
        return page;
    }

    private Boolean setNoUnitDataStaticInfo(List<Map<String, Object>> list, String value) {
        if (NO_DATA_STR.equals(value)) {
            Map<String, Object> result2 = Maps.newHashMap();
            result2.put("name", "使用登记办理率(%)");
            result2.put("value", NO_DATA_STR);
            Map<String, Object> result3 = Maps.newHashMap();
            result3.put("name", "检验超期率(%)");
            result3.put("value", NO_DATA_STR);
            Map<String, Object> result4 = Maps.newHashMap();
            result4.put("name", "检验合格率(%)");
            result4.put("value", NO_DATA_STR);
            Map<String, Object> result5 = Maps.newHashMap();
            result5.put("name", "充装检查率(%)");
            result5.put("value", NO_DATA_STR);
            Map<String, Object> result6 = Maps.newHashMap();
            result6.put("name", "充装检查合格率(%)");
            result6.put("value", NO_DATA_STR);
            list.add(result2);
            list.add(result3);
            list.add(result5);
            list.add(result4);
            list.add(result6);
            return false;
        }
        return true;
    }

    private String getLicenseEfficiencyByRegion(String regionCode) {
        List<KeyValueDto> keyValueDtos = this.getBaseMapper().queryLicenseEfficiencyOfRegion(regionCode);
        int totalUnitNumber = keyValueDtos.stream().mapToInt(KeyValueDto::getIValue).sum();
        int okUnitNumberNumber = keyValueDtos.stream().filter(k -> k.getStrKey().equals(LICENSE_IS_OK)).mapToInt(KeyValueDto::getIValue).sum();
        if (totalUnitNumber == 0) {
            return NO_DATA_STR;
        }
        BigDecimal bigTotalUnitNumber = new BigDecimal(String.valueOf(totalUnitNumber));
        BigDecimal bigOkUnitNumberNumber = new BigDecimal(String.valueOf(okUnitNumberNumber));
        BigDecimal result = bigOkUnitNumberNumber.divide(bigTotalUnitNumber, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2);
        return result.toPlainString();
    }

    private long searchEsCount(Boolean checkOk, Boolean resultOk, String regionCode, String appId) {
        CountRequest countRequest = new CountRequest("cylinder_filling");
//        countRequest.indices("cylinder_filling");
        BoolQueryBuilder boolMust = QueryBuilders.boolQuery();
        if (checkOk) {
            //匹配充装前检查和充装后检查都有数据
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.existsQuery("inspectionDateMs"));
            meBuilder.must(QueryBuilders.existsQuery("inspectionDateAfterMS"));
            boolMust.must(meBuilder);
        }
        if (resultOk) {
            //匹配充装前检查和充装后检查都有数据
            BoolQueryBuilder meBuilder = QueryBuilders.boolQuery();
            meBuilder.must(QueryBuilders.termQuery("fillingResult.keyword", "合格"));
            meBuilder.must(QueryBuilders.termQuery("checkResult.keyword", "合格"));
            boolMust.must(meBuilder);
        }

        //匹配行政区划
        if (!ObjectUtils.isEmpty(regionCode)) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.wildcardQuery("regionCode", "*" + regionCode + "*"));
            boolMust.must(query);
        }
        //匹配appId
        if (!ObjectUtils.isEmpty(appId)) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.matchQuery("appId", appId));
            boolMust.must(query);
        }

        countRequest.query(boolMust);
        try {
            CountResponse countResponse = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
            return countResponse.getCount();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public String testSaveCylinderFillingRecord2ES() {
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("cylinder_filling");
        List<ESCylinderFillingRecordDto> dtoList = Lists.newArrayList();
        ESCylinderFillingRecordDto esCylinderFillingRecordDto = new ESCylinderFillingRecordDto();
        esCylinderFillingRecordDto.setAppId("1");
        esCylinderFillingRecordDto.setCreditCode("1");
        esCylinderFillingRecordDto.setCheckResult("合格");
        esCylinderFillingRecordDto.setFillingResult("合格");
        esCylinderFillingRecordDto.setUnitName("1test1");
        dtoList.add(esCylinderFillingRecordDto);
        ESCylinderFillingRecordDto esCylinderFillingRecordDto1 = new ESCylinderFillingRecordDto();
        esCylinderFillingRecordDto1.setAppId("1");
        esCylinderFillingRecordDto1.setCreditCode("1");
        esCylinderFillingRecordDto1.setCheckResult("合格");
        esCylinderFillingRecordDto1.setFillingResult("合格");
        esCylinderFillingRecordDto1.setUnitName("1test1");
        dtoList.add(esCylinderFillingRecordDto1);
        esCylinderFillingRecordRepository.saveAll(dtoList);
        return "success";
    }



    public List<Map<String, Object>> getCylinderStatisticsData(String regionCode) throws IOException {
        // 构建搜索请求
        CompanyModel result = Privilege.companyClient.queryByCompanyCode(regionCode).getResult();
        String orgCode = result.getOrgCode();
        SearchRequest searchRequest = new SearchRequest("idx_biz_view_jg_all"); // 替换为你的索引名
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建查询条件
        searchSourceBuilder.query(
                QueryBuilders.boolQuery()
                        .must(QueryBuilders.termQuery("EQU_CATEGORY_CODE", "2300"))
                        .must(QueryBuilders.matchPhraseQuery("ORG_BRANCH_CODE", orgCode)) // 假设你只匹配以50开头的ORG_BRANCH_CODE
        );

        TermsAggregationBuilder aggregation = AggregationBuilders.terms("USE_UNIT_CREDIT_CODE").field("USE_UNIT_CREDIT_CODE.keyword").size(10); // 注意：.keyword后缀可能根据你的字段映射而有所不同

        searchSourceBuilder.aggregation(aggregation);
        searchRequest.source(searchSourceBuilder);

        // 执行搜索并获取响应
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // 处理聚合结果
        // 这里只是打印出聚合的名称和桶的数量，你需要根据自己的需求来处理这些数据
        Terms terms = searchResponse.getAggregations().get("USE_UNIT_CREDIT_CODE");
        List<Map<String, Object>> dataList = new ArrayList<>();
        List<String> keys = new ArrayList<>();
        for (Terms.Bucket bucket : terms.getBuckets()) {
            Map<String, Object> item = new HashMap<>();
            item.put("count", bucket.getDocCount());
            item.put("key", bucket.getKeyAsString());
            dataList.add(item);
            keys.add(bucket.getKeyAsString());
        }

        List<TzBaseEnterpriseInfoDto> tzBaseEnterpriseInfoDtos = iTzBaseEnterpriseInfoService.queryByUseCode(keys);
        Map<String, TzBaseEnterpriseInfoDto> collect = tzBaseEnterpriseInfoDtos.stream().collect(Collectors.toMap(TzBaseEnterpriseInfoDto::getUseCode, f -> f));
        for (Map<String, Object> item : dataList) {
            Object key = item.get("key");
            if (collect.containsKey(key)) {
                item.put("name", collect.get(key).getUseUnit());
                item.put("city", collect.get(key).getCity());
                item.put("province", collect.get(key).getProvince());
                item.put("district", collect.get(key).getDistrict());
            }
        }
        return dataList;
    }

    public Map<String, Object> getChildEarlyWarning(String regionCode) throws Exception {
        List<RegionModel> regionModels = this.setRegionIfRootParent(regionCode);
        List<String> collect = regionModels.stream().map(c -> c.getRegionCode().toString()).collect(Collectors.toList());
        List<CompanyModel> companyModelList = Privilege.companyClient.queryListByCompanyCode(Strings.join(collect, ",")).getResult();
        Map<String, CompanyModel> companyMap = companyModelList.stream().collect(Collectors.toMap(CompanyModel::getCompanyCode, c -> c));

        Set<String> legendData = new HashSet<>();
        List<String> xdata = new ArrayList<>();
        List<String> xuke = new ArrayList<>();
        List<String> shiyongdengji = new ArrayList<>();
        List<String> jianyanchaoqi = new ArrayList<>();
        List<String> jianyanhege = new ArrayList<>();
        List<String> czjc = new ArrayList<>();
        List<String> czjchege = new ArrayList<>();
//        List<String> renyuan = new ArrayList<>();

        legendData.add("许可有效率");
        legendData.add("使用登记办理率");
        legendData.add("检验超期率");
        legendData.add("检验合格率");
        legendData.add("充装检查率");
        legendData.add("充装检查合格率");

        for (RegionModel region : regionModels) {

            CompanyModel companyModel = companyMap.get(region.getRegionCode().toString());
            if (ObjectUtils.isEmpty(companyModel)) {
                continue;
            }
            // 是否有充装企业在指定区域下
            Boolean isHavingUnitInRegion = true;
            String orgCode = companyModel.getOrgCode();

            xdata.add(region.getRegionName());
            // 1.许可有效率
            if (!ValidationUtil.isEmpty(companyModel)) {
                String value = this.getLicenseEfficiencyByRegion(orgCode);
                if (NO_DATA_STR.equals(value)) {
                    xuke.add("0");
                } else {
                    xuke.add(String.format("%.4f", Double.parseDouble(value) / 100.0000 ));
                }
            }
            if (!ValidationUtil.isEmpty(orgCode) && !isHavingUnitInRegion) {
                shiyongdengji.add("0");
                jianyanchaoqi.add("0");
                jianyanhege.add("0");shiyongdengji.add("0");
                czjc.add("0");
                czjchege.add("0");
                continue;
            }
            // 2.使用登记办理率
            shiyongdengji.add("1");
            // 3.检验超期率
            jianyanchaoqi.add(String.format("%.4f", Double.parseDouble(this.getBaseMapper().getInspectionExpiredRate(orgCode, null).get("expiredRate").toString()) / 100.0000));
            // 4.检验合格率
            jianyanhege.add(String.format("%.4f", Double.parseDouble(this.getBaseMapper().getInspectionResultRate(orgCode, null).get("resultRate").toString()) / 100.0000));
            // 5.充装检查率
            long totalAll = searchEsCount(false, false, orgCode, null);
            long totalCheck = searchEsCount(true, false, orgCode, null);
            long totalResult = searchEsCount(false, true, orgCode, null);
            if (totalAll != 0) {
                czjc.add(new DecimalFormat("#.0000").format(((double) totalCheck / totalAll)));
            } else {
                czjc.add("0");
            }
            // 6.充装检查合格率
            if (totalAll != 0) {
                czjchege.add(new DecimalFormat("#.0000").format(((double) totalResult / totalAll)));
            } else {
                czjchege.add("0");
            }
        }
        Map<String, Object> result = new HashMap<>();

        result.put("xdata", xdata);
        result.put("legendData", legendData);
        result.put("xuke", xuke);
        result.put("shiyongdengji", shiyongdengji);
        result.put("jianyanchaoqi", jianyanchaoqi);
        result.put("jianyanhege", jianyanhege);
        result.put("czjc", czjc);
        result.put("czjchege", czjchege);

        return result;
    }

    public Map getChildWarning(String regionCode) {
        Map<String, Object> result = Maps.newHashMap();
        // 是否有充装企业在指定区域下
        Boolean isHavingUnitInRegion = true;
        List<Map<String, Object>> list = Lists.newArrayList();
        Map<String, Object> result1 = Maps.newHashMap();
        Map<String, Object> result2 = Maps.newHashMap();

        // 1.许可有效率
        if (!ValidationUtil.isEmpty(regionCode)) {
            result1.put("name", "许可有效率(%)");
            result1.put("value", this.getLicenseEfficiencyByRegion(regionCode));
            isHavingUnitInRegion = this.setNoUnitDataStaticInfo(list, result1.get("value").toString());
        }
        if (!ValidationUtil.isEmpty(regionCode) && !isHavingUnitInRegion) {
            list.add(result1);
            result.put(regionCode, list);
            return result;
        }
        // 2.使用登记办理率
        result2.put("name", "使用登记办理率(%)");
        result2.put("value", "100");
        // 3.检验超期率
        Map<String, Object> result3 = Maps.newHashMap();
        result3.put("name", "检验超期率(%)");
        result3.put("value", this.getBaseMapper().getInspectionExpiredRate(regionCode, null).get("expiredRate").toString());
        // 4.检验合格率
        Map<String, Object> result4 = Maps.newHashMap();
        result4.put("name", "检验合格率(%)");
        result4.put("value", this.getBaseMapper().getInspectionResultRate(regionCode, null).get("resultRate").toString());
        // 5.充装检查率
        Map<String, Object> result5 = Maps.newHashMap();
        long totalAll = searchEsCount(false, false, regionCode, null);
        long totalCheck = searchEsCount(true, false, regionCode, null);
        long totalResult = searchEsCount(false, true, regionCode, null);
        result5.put("name", "充装检查率(%)");
        if (totalAll != 0) {
            result5.put("value", new DecimalFormat("#.00").format(((double) totalCheck / totalAll) * 100));
        } else {
            result5.put("value", 0);
        }
        // 6.充装检查合格率
        Map<String, Object> result6 = Maps.newHashMap();
        result6.put("name", "充装检查合格率(%)");
        if (totalAll != 0) {
            result6.put("value", new DecimalFormat("#.00").format(((double) totalResult / totalAll) * 100));
        } else {
            result6.put("value", 0);
        }

        // list中按以下固定顺序返回给前端
        list.add(result1);
        list.add(result3);
        list.add(result5);
        list.add(result2);
        list.add(result4);
        list.add(result6);

        result.put(regionCode, list);
        return result;
    }

    public Map<String, Object> getCylinderStatisticsDataByCity(String regionCode) throws Exception {
        // 构建搜索请求
        List<RegionModel> regionList = this.setRegionIfRootParent(regionCode);
        List<String> companyCode = regionList.stream().map(r -> r.getRegionCode().toString()).collect(Collectors.toList());
        List<CompanyModel> companyList = Privilege.companyClient.queryListByCompanyCode(String.join(",", companyCode)).getResult();
        Map<String, RegionModel> regionMap = regionList.stream().collect(Collectors.toMap(r ->r.getRegionCode().toString(), r -> r));
        List<Map<String, Object>> legendData = new ArrayList<>();
        List<String>  xdata = new ArrayList<>();
        List<String>  qiping = new ArrayList<>();
        List<String>  qizhan = new ArrayList<>();

        long maxValue = 0;

        for (CompanyModel comapany : companyList) {
            String orgCode = comapany.getOrgCode();
            xdata.add(regionMap.get(comapany.getCompanyCode()).getRegionName());
            SearchRequest searchRequest = new SearchRequest("idx_biz_view_jg_all"); // 替换为你的索引名
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

            // 构建查询条件
            searchSourceBuilder.query(
                    QueryBuilders.boolQuery()
                            .must(QueryBuilders.termQuery("EQU_CATEGORY_CODE", "2300"))
                            .must(QueryBuilders.matchPhraseQuery("ORG_BRANCH_CODE", orgCode)) // 假设你只匹配以50开头的ORG_BRANCH_CODE
            );

            TermsAggregationBuilder aggregation = AggregationBuilders.terms("ORG_BRANCH_CODE").field("ORG_BRANCH_CODE.keyword").size(10); // 注意：.keyword后缀可能根据你的字段映射而有所不同

            searchSourceBuilder.aggregation(aggregation);
            searchRequest.source(searchSourceBuilder);

            // 执行搜索并获取响应
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            // 处理聚合结果
            // 这里只是打印出聚合的名称和桶的数量，你需要根据自己的需求来处理这些数据
            Terms terms = searchResponse.getAggregations().get("ORG_BRANCH_CODE");
            if (!ObjectUtils.isEmpty(terms.getBuckets())) {
                if (terms.getBuckets().get(0).getDocCount() > maxValue) {
                    maxValue = terms.getBuckets().get(0).getDocCount();
                }
                qiping.add( terms.getBuckets().get(0).getDocCount() + "");
            } else {
                qiping.add( "0");
            }
        }

        if (maxValue > 100000) {
            for (int i = 0; i < qiping.size(); i++) {
                qiping.set(i, String.format("%.4f", Long.parseLong(qiping.get(i)) / 10000.0000) + "");
            }
        }

        List<String> orgCodes = companyList.stream().map(c -> c.getOrgCode()).collect(Collectors.toList());
        List<Map<String, Object>> qizhanMap = this.baseMapper.getQiZhanStatisticsDataByCity(orgCodes);
        Map<Object, Object> collect = qizhanMap.stream().collect(Collectors.toMap(m -> ((Map) m).get("orgCode"), m -> ((Map) m).get("unitCount")));
        for (CompanyModel comapany : companyList) {
            String orgCode = comapany.getOrgCode();
            if (collect.containsKey(orgCode)) {
                qizhan.add(collect.get(orgCode).toString());
            } else {
                qizhan.add("0");
            }
        }

        Map<String, Object> qiLegend = new HashMap<>();
        if (maxValue > 100000) {
            qiLegend.put("value", "气瓶数量(万)");
            qiLegend.put("dataKey", "qiping");
        } else {
            qiLegend.put("value", "气瓶数量");
            qiLegend.put("dataKey", "qiping");
        }

        Map<String, Object> zhanLegend = new HashMap<>();
        zhanLegend.put("value", "气站数量");
        zhanLegend.put("dataKey", "qizhan");

        legendData.add(qiLegend);
        legendData.add(zhanLegend);

        Map<String, Object> result = new HashMap<>();
        result.put("qizhan", qizhan);
        result.put("qiping", qiping);
        result.put("xdata", xdata);
        result.put("legendData", legendData);
        return result;
    }

    private List<RegionModel> setRegionIfRootParent(String regionCode) throws Exception {
        List<RegionModel> regionList = Systemctl.regionClient.queryByParentRegionCode(Integer.parseInt(regionCode)).getResult();
        // 陕西省时需要在地图返回独立的地级市:韩城、杨凌、西咸
        if (regionCode.equals(TZSCommonConstant.SHAN_XI_REGION_CODE)) {
            List<RegionModel> independentRegions = ReginStepEnum.enum2RegionList("map");
            regionList.addAll(independentRegions);
        }
        return regionList;
    }

    public Map<String, Object> getCylinderStatisticsDataByCityForTotal(String regionCode) throws IOException {
        // 构建搜索请求
        CompanyModel comapany = Privilege.companyClient.queryByCompanyCode(regionCode).getResult();
        String orgCode = comapany.getOrgCode();
        SearchRequest searchRequest = new SearchRequest("idx_biz_view_jg_all"); // 替换为你的索引名
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        long qiping = 0;
        // 构建查询条件
        searchSourceBuilder.query(
                QueryBuilders.boolQuery()
                        .must(QueryBuilders.termQuery("EQU_CATEGORY_CODE", "2300"))
                        .must(QueryBuilders.matchPhraseQuery("ORG_BRANCH_CODE", orgCode)) // 假设你只匹配以50开头的ORG_BRANCH_CODE
        );

        TermsAggregationBuilder aggregation = AggregationBuilders.terms("ORG_BRANCH_CODE").field("ORG_BRANCH_CODE.keyword").size(10); // 注意：.keyword后缀可能根据你的字段映射而有所不同

        searchSourceBuilder.aggregation(aggregation);
        searchRequest.source(searchSourceBuilder);

        // 执行搜索并获取响应
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 处理聚合结果
        // 这里只是打印出聚合的名称和桶的数量，你需要根据自己的需求来处理这些数据
        Terms terms = searchResponse.getAggregations().get("ORG_BRANCH_CODE");
        if (!ObjectUtils.isEmpty(terms.getBuckets())) {
            qiping = terms.getBuckets().get(0).getDocCount() ;
        } else {
            qiping = 0;
        }

        List<String> orgCodes = new ArrayList<>();
        orgCodes.add(orgCode);
        List<Map<String, Object>> qizhanMap = this.baseMapper.getQiZhanStatisticsDataByCity(orgCodes);
        String unitNumber = "0";
        if (!ObjectUtils.isEmpty(qizhanMap)) {
            unitNumber = qizhanMap.get(0).get("unitCount").toString();
        }

        Map<String, Object> result = new HashMap<>();
        result.put("cylindersCount", qiping);
        result.put("stationCount", unitNumber);
        result.put("operatorCount", this.baseMapper.getOpertorStatisticsDataByCity(orgCodes));
        return result;
    }

    public List<Map<String, Object>> getCylinderStatisticsDataByCityForMap(String regionCode) throws Exception {
        // 构建搜索请求
        List<RegionModel> regionList = this.setRegionIfRootParent(regionCode);
        List<String> companyCode = regionList.stream().map(r -> r.getRegionCode().toString()).collect(Collectors.toList());
        List<CompanyModel> companyList = Privilege.companyClient.queryListByCompanyCode(String.join(",", companyCode)).getResult();
        Map<String, RegionModel> regionMap = regionList.stream().collect(Collectors.toMap(r ->r.getRegionCode().toString(), r -> r));
        List<Map<String, Object>> list = new ArrayList<>();
        if (ObjectUtils.isEmpty(companyList)) {
            return new ArrayList<>();
        }
        List<String> orgCodes = companyList.stream().map(CompanyModel::getOrgCode).collect(Collectors.toList());
        List<Map<String, Object>> qizhanMap = this.baseMapper.getQiZhanStatisticsDataByCity(orgCodes);
        Map<Object, Object> collect = qizhanMap.stream().collect(Collectors.toMap(m -> ((Map) m).get("orgCode"), m -> ((Map) m).get("unitCount")));

        for (CompanyModel company : companyList) {
            String orgCode = company.getOrgCode();
            SearchRequest searchRequest = new SearchRequest("idx_biz_view_jg_all"); // 替换为你的索引名
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            long qiping = 0;
            // 构建查询条件
            searchSourceBuilder.query(
                    QueryBuilders.boolQuery()
                            .must(QueryBuilders.termQuery("EQU_CATEGORY_CODE", "2300"))
                            .must(QueryBuilders.matchPhraseQuery("ORG_BRANCH_CODE", orgCode)) // 假设你只匹配以50开头的ORG_BRANCH_CODE
            );

            TermsAggregationBuilder aggregation = AggregationBuilders.terms("ORG_BRANCH_CODE").field("ORG_BRANCH_CODE.keyword").size(10); // 注意：.keyword后缀可能根据你的字段映射而有所不同

            searchSourceBuilder.aggregation(aggregation);
            searchRequest.source(searchSourceBuilder);

            // 执行搜索并获取响应
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            // 处理聚合结果
            // 这里只是打印出聚合的名称和桶的数量，你需要根据自己的需求来处理这些数据
            Terms terms = searchResponse.getAggregations().get("ORG_BRANCH_CODE");
            if (!ObjectUtils.isEmpty(terms.getBuckets())) {
                qiping = terms.getBuckets().get(0).getDocCount() ;
            } else {
                qiping = 0;
            }

            String unitNumber = "0";
            if (!ObjectUtils.isEmpty(collect) && collect.containsKey("orgCode")) {
                unitNumber = collect.get("orgCode").toString();
            }

            Map<String, Object> result = new HashMap<>();

            RegionModel region = regionMap.get(company.getCompanyCode());
            result.put("regionAddress", company.getAddress());
            result.put("regionCode", company.getCompanyCode());
            result.put("regionName", region.getRegionName());
            result.put("longitude", company.getLongitude());
            result.put("latitude", company.getLatitude());
            result.put("stationCount", unitNumber);
            result.put("cylindersCount", qiping);
            result.put("operatorCount", 0);

            list.add(result);
        }

        return list;
    }


    public Map<String, Object> getsecurityIndex(String regionCode) throws Exception {
        List<RegionModel> regionModels = this.setRegionIfRootParent(regionCode);
        List<String> collect = regionModels.stream().map(c -> c.getRegionCode().toString()).collect(Collectors.toList());
        List<CompanyModel> companyModelList = Privilege.companyClient.queryListByCompanyCode(Strings.join(collect, ",")).getResult();
        Map<String, CompanyModel> companyMap = companyModelList.stream().collect(Collectors.toMap(CompanyModel::getCompanyCode, c -> c));

        List<String> xdata = new ArrayList<>();
        List<String> xuke = new ArrayList<>();
        List<String> shiyongdengji = new ArrayList<>();
        List<String> jianyanchaoqi = new ArrayList<>();
        List<String> jianyanhege = new ArrayList<>();
        List<String> czjc = new ArrayList<>();
        List<String> czjchege = new ArrayList<>();

        for (RegionModel region : regionModels) {

            CompanyModel companyModel = companyMap.get(region.getRegionCode().toString());
            if (ObjectUtils.isEmpty(companyModel)) {
                continue;
            }
            // 是否有充装企业在指定区域下
            Boolean isHavingUnitInRegion = true;
            String orgCode = companyModel.getOrgCode();

            xdata.add(region.getRegionName());
            // 1.许可有效率
            if (!ValidationUtil.isEmpty(companyModel)) {
                String value = this.getLicenseEfficiencyByRegion(orgCode);
                if (NO_DATA_STR.equals(value)) {
                    value = "0";
                    xuke.add(value);
                } else {
                    xuke.add(value);
                }
            }
            if (!ValidationUtil.isEmpty(orgCode) && !isHavingUnitInRegion) {
                shiyongdengji.add("0");
                jianyanchaoqi.add("0");
                jianyanhege.add("0");shiyongdengji.add("0");
                czjc.add("0");
                czjchege.add("0");
                continue;
            }
            // 2.使用登记办理率
            shiyongdengji.add("100");
            // 3.检验超期率
            jianyanchaoqi.add(this.getBaseMapper().getInspectionExpiredRate(orgCode, null).get("expiredRate").toString());
            // 4.检验合格率
            jianyanhege.add(this.getBaseMapper().getInspectionResultRate(orgCode, null).get("resultRate").toString());
            // 5.充装检查率
            long totalAll = searchEsCount(false, false, orgCode, null);
            long totalCheck = searchEsCount(true, false, orgCode, null);
            long totalResult = searchEsCount(false, true, orgCode, null);
            if (totalAll != 0) {
                czjc.add(new DecimalFormat("#.00").format(((double) totalCheck / totalAll) * 100));
            } else {
                czjc.add("0");
            }
            // 6.充装检查合格率
            if (totalAll != 0) {
                czjchege.add(new DecimalFormat("#.00").format(((double) totalResult / totalAll) * 100));
            } else {
                czjchege.add("0");
            }
        }
        Map<String, Object> result = new HashMap<>();

        List<Map<String, String>> data = new ArrayList<>();

//        List<String> ydata = new ArrayList<>();
        for (int i = 0; i < xdata.size(); i++) {
            Map<String, String> item = new HashMap<>();
            item.put("name", xdata.get(i));

            // 计算xuke的加权值
            double xukeWeighted = Double.parseDouble(xuke.get(i)) * 0.10; // 10%

            // 剩余权重平均分配给四个因素，每个因素大约22.5%（但为了简化，我们这里用25%的剩余权重）
            double remainingWeightPerFactor = 0.90 / 4; // 简化为每个因素25%的剩余权重

            // 计算其他四个因素的加权值
            double jianyanchaoqiWeighted = Double.parseDouble(jianyanchaoqi.get(i))  * remainingWeightPerFactor;
            double jianyanhegeWeighted = Double.parseDouble(jianyanhege.get(i))  * remainingWeightPerFactor;
            double czjcWeighted = Double.parseDouble(czjc.get(i))  * remainingWeightPerFactor;
            double czjchegeWeighted = Double.parseDouble(czjchege.get(i))  * remainingWeightPerFactor;

            // 计算总指数
            double totalIndex = xukeWeighted + jianyanchaoqiWeighted + jianyanhegeWeighted + czjcWeighted + czjchegeWeighted;
            item.put("value",String.format("%.2f", totalIndex));
            data.add(item);
//            ydata.add(String.format("%.2f", totalIndex));
        }

        data = data.stream()
                .filter(map -> map.containsKey("value")) // 确保每个Map都包含指定的键
                .sorted(Comparator.comparingDouble(map -> {
                    // 检查并解析值，如果失败则返回Double.MIN_VALUE（或根据需要处理）
                    try {
                        return Double.parseDouble(map.get("value"));
                    } catch (NumberFormatException e) {
                        // 处理无法解析为double的情况，这里返回Double.MIN_VALUE表示最小
                        // 或者可以抛出自定义异常，记录日志等
                        return Double.MIN_VALUE;
                    }
                }))
                .collect(Collectors.toList());
        List<String> name = data.stream().map(map -> map.get("name")).collect(Collectors.toList());
        Collections.reverse(name);
        result.put("xdata", name);
        List<String> value = data.stream().map(map -> map.get("value")).collect(Collectors.toList());
        Collections.reverse(value);
        result.put("ydata", value);

        return result;
    }

    public Map<String, Object> mainBodyCount(String cityCode) {
        Map<String,Object> resultMap = new HashMap<>();
        Map<String,Object> dataMap = new HashMap<>();
        String startDate = LocalDate.now().minusDays(100).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<String> mainBodyNameList = IssueMainBodyEnum.getEnumNameList();
        String orgCode = getAndSetOrgCode(cityCode);
        List<Map<String, Object>> list = statisticsMapper.selectByOrgAndMainBody(orgCode, mainBodyNameList, startDate,null);
        List<Object> legendDataList = new ArrayList<>();
        for(int i = 0; i < 2; i++){
            Map<String, Object> map = new HashMap<>();
            if(0 == i) {
                map.put("dataKey", "problemCount");
                map.put("value","问题数量");
            }else if(1 == i){
                map.put("dataKey", "problemRate");
                map.put("value","问题闭环率");
            }
            legendDataList.add(map);
        }
        resultMap.put("legendData",legendDataList);
        List<String> xdata = new ArrayList<>();
        List<Object> problemCount = new ArrayList<>();
        List<Object> problemRate = new ArrayList<>();
        list.stream().forEach(t->{
            dataMap.put(t.get("sourceType").toString(),t.get("count").toString());
        });
        for(int i = 0; i < mainBodyNameList.size(); i++){
            if(null != dataMap.get(mainBodyNameList.get(i))){
                problemCount.add(dataMap.get(mainBodyNameList.get(i)));
                List<String> list1 = new ArrayList<>();
                list1.add(mainBodyNameList.get(i));
                List<Map<String, Object>> maps = statisticsMapper.selectByOrgAndMainBody(orgCode, list1, startDate, "1");
                if(maps.size() > 0){
                    problemRate.add(new DecimalFormat("0.00").format( Double.parseDouble(maps.get(0).get("count").toString()) / Double.parseDouble(dataMap.get(mainBodyNameList.get(i)).toString())));
                }else{
                    problemRate.add("0");
                }
            }else{
                problemCount.add("0");
                problemRate.add("0");
            }
            xdata.add(mainBodyNameList.get(i));
        }
        resultMap.put("xdata",xdata);
        resultMap.put("problemCount",problemCount);
        resultMap.put("problemRate",problemRate);

        return resultMap;
    }

    private String getAndSetOrgCode(String cityCode) {
        String orgCode = regionCodeOrgCodeMap.get(cityCode);
        if (orgCode == null) {
            orgCode = statisticsMapper.getOrgCodeByCompanyCode(cityCode);
            if (orgCode != null) {
                regionCodeOrgCodeMap.put(cityCode, orgCode);
            }
        }
        return orgCode;
    }

    public Map<String, Object> equipmentCount(String cityCode) {
        Map<String,Object> resultMap = new HashMap<>();
        Map<String,Object> dataMap = new HashMap<>();
        List<Object> xdata = new ArrayList<>();
        List<Object> ydata = new ArrayList<>();
        String orgCode = getAndSetOrgCode(cityCode);
        List<String> enumNameList = IssueTypeEnum.getEnumNameListByMainBody("3");
        String startDate = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<Map<String,Object>> list = statisticsMapper.selectByOrgAndProblemType(orgCode, enumNameList, startDate,IssueMainBodyEnum.EQUIPMENT.getName(),null);
        list.stream().forEach(t->{
            dataMap.put(t.get("problemType").toString(),t.get("count").toString());
        });
        for(int i = 0; i < enumNameList.size(); i++){
            xdata.add(enumNameList.get(i));
            ydata.add(dataMap.getOrDefault(enumNameList.get(i),"0"));
        }
        resultMap.put("xdata",xdata);
        resultMap.put("ydata",ydata);
        return resultMap;
    }

    public List<Map<String, Object>> companyCount(String cityCode) {
        List<Map<String,Object>> resultList = new ArrayList<>();
        Map<String,Object> dataMap = new HashMap<>();
        String orgCode = getAndSetOrgCode(cityCode);
        List<String> enumNameList = IssueTypeEnum.getEnumNameListByMainBody("2");
        String startDate = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<Map<String,Object>> list = statisticsMapper.selectByOrgAndProblemType(orgCode, enumNameList, startDate,IssueMainBodyEnum.COMPANY.getName(),null);
        list.stream().forEach(t->{
            dataMap.put(t.get("problemType").toString(),t.get("count").toString());
        });
        for(int i = 0; i < enumNameList.size(); i++){
            Map<String,Object> map = new HashMap<>();
            if(enumNameList.get(i).equals("许可临期")){
                map.put("key","licenseExpirationDateNumber");
                map.put("label","许可临期数");
                map.put("value",dataMap.getOrDefault(enumNameList.get(i),"0"));
            }else if(enumNameList.get(i).equals("许可超期")){
                map.put("key","licenseOverdueNumber");
                map.put("label","许可超期数");
                map.put("value",dataMap.getOrDefault(enumNameList.get(i),"0"));
            }else if(enumNameList.get(i).equals("维保备案超期")){
                map.put("key","maintenanceFilingOverdueNumber");
                map.put("label","维保备案超期数（仅电梯）");
                map.put("value",dataMap.getOrDefault(enumNameList.get(i),"0"));
            }
            resultList.add(map);
        }
        return resultList;
    }

    public Map<String, Object> personCount(String cityCode) {
        Map<String,Object> resultMap = new HashMap<>();
        Map<String,Object> dataMap = new HashMap<>();
        List<Object> xdata = new ArrayList<>();
        List<Object> ydata = new ArrayList<>();
        String orgCode = getAndSetOrgCode(cityCode);
        List<String> enumNameList = IssueTypeEnum.getEnumNameListByMainBody("1");
        String startDate = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<Map<String,Object>> list = statisticsMapper.selectByOrgAndProblemType(orgCode, enumNameList, startDate, IssueMainBodyEnum.PERSON.getName(),null);
        list.stream().forEach(t->{
            dataMap.put(t.get("problemType").toString(),t.get("count").toString());
        });
        for(int i = 0; i < enumNameList.size(); i++){
            xdata.add(enumNameList.get(i));
            ydata.add(dataMap.getOrDefault(enumNameList.get(i),"0"));
        }
        resultMap.put("xdata",xdata);
        resultMap.put("ydata",ydata);
        return resultMap;
    }

    public Map<String, Object> cylinderCount(String cityCode) {
        Map<String,Object> resultMap = new HashMap<>();
        Map<String,Object> dataMap = new HashMap<>();
        List<Object> xdata = new ArrayList<>();
        List<Object> ydata = new ArrayList<>();
        String orgCode = getAndSetOrgCode(cityCode);
        List<String> enumNameList = IssueTypeEnum.getEnumNameListByMainBody("4");
        String startDate = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<Map<String,Object>> list = statisticsMapper.selectByOrgAndProblemType(orgCode, enumNameList, startDate, IssueMainBodyEnum.EQUIPMENT.getName(),"2300");
        list.stream().forEach(t->{
            dataMap.put(t.get("problemType").toString(),t.get("count").toString());
        });
        for(int i = 0; i < enumNameList.size(); i++){
            xdata.add(enumNameList.get(i));
            ydata.add(dataMap.getOrDefault(enumNameList.get(i),"0"));
        }
        resultMap.put("xdata",xdata);
        resultMap.put("ydata",ydata);
        return resultMap;
    }

    public Map<String, Object> issueCountByMonth(String cityCode) {
        Map<String,Object> resultMap = new HashMap<>();
        List<Object> legendData = new ArrayList<>();
        for(int i = 0; i < 2; i++){
            Map<String,Object> map = new HashMap<>();
            if(i == 0){
                map.put("key","problemCount");
                map.put("value","问题数量");
            }else{
                map.put("key","processedRate");
                map.put("value","已处理");
            }
            legendData.add(map);
        }
        resultMap.put("legendData",legendData);
        String orgCode = getAndSetOrgCode(cityCode);
        int year = LocalDate.now().getYear();
        List<Map<String,Object>> allIssue = statisticsMapper.getIssueCountByMonth(orgCode,String.valueOf(year),null);
        List<Map<String,Object>> endIssue = statisticsMapper.getIssueCountByMonth(orgCode,String.valueOf(year),"1");
        Map<String,Object> allIssueMap = new HashMap<>();
        Map<String,Object> endIssueMap = new HashMap<>();
        allIssue.stream().forEach(t->{
            allIssueMap.put(t.get("time").toString(),t.get("count"));
        });
        endIssue.stream().forEach(t->{
            endIssueMap.put(t.get("time").toString(),t.get("count"));
        });
        List<Object> problemCount = new ArrayList<>();
        List<Object> processedRate = new ArrayList<>();
        List<Object> xdata = new ArrayList<>();
        for(int i = 0; i < 12; i++){
            String time = LocalDate.now().minusMonths(i).format(DateTimeFormatter.ofPattern("yyyy-MM"));
            xdata.add(time);
            if(allIssueMap.get(time) == null){
                problemCount.add("0");
                processedRate.add("0");
            }else{
                problemCount.add(allIssueMap.get(time));
                if(endIssueMap.get(time) == null){
                    processedRate.add("0");
                }else{
                    processedRate.add(new DecimalFormat("0.00").format(Double.parseDouble(endIssueMap.get(time).toString()) / Double.parseDouble(allIssueMap.get(time).toString())));
                }
            }
        }
        Collections.reverse(xdata);
        Collections.reverse(problemCount);
        Collections.reverse(processedRate);
        resultMap.put("xdata",xdata);
        resultMap.put("problemCount",problemCount);
        resultMap.put("processedRate",processedRate);
        return resultMap;
    }

    public Map<String, Object> issueCountByDay(String cityCode) {
        Map<String,Object> resultMap = new HashMap<>();
        List<Object> legendData = new ArrayList<>();
        for(int i = 0; i < 2; i++){
            Map<String,Object> map = new HashMap<>();
            if(i == 0){
                map.put("key","problemCount");
                map.put("value","问题数量");
            }else{
                map.put("key","processedRate");
                map.put("value","已处理");
            }
            legendData.add(map);
        }
        resultMap.put("legendData",legendData);
        String orgCode = getAndSetOrgCode(cityCode);
        String year = LocalDate.now().minusDays(29).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<Map<String,Object>> allIssue = statisticsMapper.getIssueCountByDate(orgCode,year,null);
        List<Map<String,Object>> endIssue = statisticsMapper.getIssueCountByDate(orgCode,year,"1");
        Map<String,Object> allIssueMap = new HashMap<>();
        Map<String,Object> endIssueMap = new HashMap<>();
        allIssue.stream().forEach(t->{
            allIssueMap.put(t.get("time").toString(),t.get("count"));
        });
        endIssue.stream().forEach(t->{
            endIssueMap.put(t.get("time").toString(),t.get("count"));
        });
        List<Object> problemCount = new ArrayList<>();
        List<Object> processedRate = new ArrayList<>();
        List<Object> xdata = new ArrayList<>();
        for(int i = 0; i < 29; i++){
            String time = LocalDate.now().minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            xdata.add(time);
            if(allIssueMap.get(time) == null){
                problemCount.add("0");
                processedRate.add("0");
            }else{
                problemCount.add(allIssueMap.get(time));
                if(endIssueMap.get(time) == null){
                    processedRate.add("0");
                }else{
                    processedRate.add(new DecimalFormat("0.00").format(Double.parseDouble(endIssueMap.get(time).toString()) / Double.parseDouble(allIssueMap.get(time).toString())));
                }
            }
        }
        Collections.reverse(xdata);
        Collections.reverse(problemCount);
        Collections.reverse(processedRate);
        resultMap.put("xdata",xdata);
        resultMap.put("problemCount",problemCount);
        resultMap.put("processedRate",processedRate);
        return resultMap;
    }

    public Map<String, Object> issueCountByCityCode(String cityCode) {
        String orgCode = getAndSetOrgCode(cityCode);
        String now = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        int count = statisticsMapper.countByOrgCode(orgCode,now);
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("issueCount",count);
        return resultMap;
    }


    public List<Map<String, Object>> issueChildrenCityCount(String cityCode) throws Exception {
        List<RegionModel> regionModels = setRegionIfRootParent(cityCode);
        List<Integer> regionCodeList = regionModels.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        List<Map<String, String>> orgCodeAndCompanyCodesByCompanyCodes = statisticsMapper.getOrgCodeAndCompanyCodesByCompanyCodes(regionCodeList);
        List<String> orgCodes = orgCodeAndCompanyCodesByCompanyCodes.stream().map(m -> m.get("orgCode")).collect(Collectors.toList());
        String now = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        Map<String,String> orgCodeAndCompanyCodesMap = new HashMap<>();
        orgCodeAndCompanyCodesByCompanyCodes.stream().forEach(t->{
            orgCodeAndCompanyCodesMap.put(t.get("companyCode"),t.get("orgCode"));
        });
        List<Map<String, Object>> list = statisticsMapper.countByOrgCodes(orgCodes,now);
        Map<String,Object> dataMap = new HashMap<>();
        list.stream().forEach(t->{
            dataMap.put(t.get("orgCode").toString(),t.get("count"));
        });

        List<Map<String,Object>> resultList = new ArrayList<>();
        for(RegionModel regionModel : regionModels){
            Map<String,Object> map = new HashMap<>();
            AtomicInteger count = new AtomicInteger();
            map.put("regionCode",regionModel.getRegionCode());
            map.put("regionName",regionModel.getRegionName());
            if(StringUtils.isNotBlank(orgCodeAndCompanyCodesMap.get(regionModel.getRegionCode()+""))){
                dataMap.forEach((k, v)->{
                    if(k.startsWith(orgCodeAndCompanyCodesMap.get(regionModel.getRegionCode()+""))){
                        if(null != v){
                            count.addAndGet(Integer.valueOf(v+""));
                        }
                    }
                });
            }
            map.put("issueCount",count);
            resultList.add(map);
        }

        return resultList;
    }

    public List<Map<String, Object>> issueMonthList(String cityCode) {
        String orgCode = getAndSetOrgCode(cityCode);
        String time = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        List<Map<String,Object>> list = statisticsMapper.issueMonthList(orgCode,time);
        return list;
    }

    public Map<String, Object> issueProblemLevelCount(String cityCode) {
        Map<String,Object> resultMap = new HashMap<>();
        String orgCode = getAndSetOrgCode(cityCode);
        String time = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy"));
        List<Map<String,Object>> list = statisticsMapper.issueProblemLevelCount(orgCode,time);
        List<Object> xdata = new ArrayList<>();
        List<Object> ydata = new ArrayList<>();
        for(int i = 0; i < list.size(); i++){
            xdata.add(list.get(i).get("problemLevel"));
            ydata.add(list.get(i).get("count"));
        }
        resultMap.put("xdata",xdata);
        resultMap.put("ydata",ydata);
        return resultMap;
    }

    public List<Map<String, Object>> issueCompanyTop(String cityCode) {
        List<Map<String,Object>> resultList = new ArrayList<>();
        String orgCode = getAndSetOrgCode(cityCode);
        String time = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy"));
        List<Map<String,Object>> list = statisticsMapper.issueCompanyTop(orgCode,time);
        for(int i = 0; i < list.size(); i++){
            Map<String,Object> map = new HashMap<>();
            map.put("sequenceNbr",(i+1)+"");
            map.put("region",list.get(i).get("governingBody"));
            map.put("company",list.get(i).get("principalUnit"));
            map.put("count",list.get(i).get("count"));
            resultList.add(map);
        }
        return resultList;
    }

    public List<Map<String, Object>> issueChildrenCityCountTop(String cityCode) throws Exception {
        List<RegionModel> regionModels = setRegionIfRootParent(cityCode);
        List<Integer> regionCodeList = regionModels.stream().map(m -> m.getRegionCode()).collect(Collectors.toList());
        List<Map<String, String>> orgCodeAndCompanyCodesByCompanyCodes = statisticsMapper.getOrgCodeAndCompanyCodesByCompanyCodes(regionCodeList);
        List<String> orgCodes = orgCodeAndCompanyCodesByCompanyCodes.stream().map(m -> m.get("orgCode")).collect(Collectors.toList());
        String now = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy"));
        Map<String,String> orgCodeAndCompanyCodesMap = new HashMap<>();
        orgCodeAndCompanyCodesByCompanyCodes.stream().forEach(t->{
            orgCodeAndCompanyCodesMap.put(t.get("companyCode"),t.get("orgCode"));
        });
        List<Map<String, Object>> allIssueCount = statisticsMapper.issueChildrenCityCountTop(orgCodes,now,null);
        List<Map<String, Object>> endIssueCount = statisticsMapper.issueChildrenCityCountTop(orgCodes,now,"1");
        Map<String,Object> allIssuedataMap = new HashMap<>();
        Map<String,Object> endIssuedataMap = new HashMap<>();
        allIssueCount.stream().forEach(t->{
            allIssuedataMap.put(t.get("orgCode").toString(),t.get("count"));
        });

        endIssueCount.stream().forEach(t->{
            endIssuedataMap.put(t.get("orgCode").toString(),t.get("count"));
        });

        List<Map<String,Object>> resultList = new ArrayList<>();
        for(RegionModel regionModel : regionModels){
            Map<String,Object> map = new HashMap<>();
            AtomicInteger allCount = new AtomicInteger();
            AtomicInteger endCount = new AtomicInteger();
            map.put("region",regionModel.getRegionName());
            if(StringUtils.isNotBlank(orgCodeAndCompanyCodesMap.get(regionModel.getRegionCode()+""))){
                allIssuedataMap.forEach((k, v)->{
                    if(k.startsWith(orgCodeAndCompanyCodesMap.get(regionModel.getRegionCode()+""))){
                        if(null != v){
                            allCount.addAndGet(Integer.valueOf(v+""));
                        }
                    }
                });
            }

            if(StringUtils.isNotBlank(orgCodeAndCompanyCodesMap.get(regionModel.getRegionCode()+""))){
                endIssuedataMap.forEach((k, v)->{
                    if(k.startsWith(orgCodeAndCompanyCodesMap.get(regionModel.getRegionCode()+""))){
                        if(null != v){
                            endCount.addAndGet(Integer.valueOf(v+""));
                        }
                    }
                });
            }
            if(allCount.get() != 0) {
                map.put("rate", new DecimalFormat("0.00").format(Double.parseDouble(endCount+"") / (Double.parseDouble(allCount.get()+""))));
            }else{
                map.put("rate", "0.00");
            }
            resultList.add(map);
        }
        resultList.sort(Comparator.comparing(m -> Double.valueOf( m.get("rate")+""), Comparator.reverseOrder()));
        for(int i = 0; i < resultList.size(); i++){
            resultList.get(i).put("sequenceNbr",(i+1)+"");
        }
        return resultList;
    }

    public List<Map<String, Object>> issueCountTopByProblemType(String cityCode) {
        String orgCode = getAndSetOrgCode(cityCode);
        List<Map<String,Object>> allList = statisticsMapper.issueCountTopByProblemType(orgCode,null);
        List<Map<String,Object>> endList = statisticsMapper.issueCountTopByProblemType(orgCode,"1");
        Map<String,Object> endIssuedataMap = new HashMap<>();
        endList.stream().forEach(t->{
            endIssuedataMap.put(t.get("problemTypeCode").toString(),t.get("count"));
        });
        List<Map<String,Object>> resultList = new ArrayList<>();
        for(int i = 0; i < allList.size(); i++){
            Map<String,Object> map = new HashMap<>();
            map.put("name",IssueTypeEnum.getNameByCode(allList.get(i).get("problemTypeCode").toString()));
            map.put("count",allList.get(i).get("count"));
            if(null != endIssuedataMap.get(allList.get(i).get("problemTypeCode").toString())){
                map.put("rate",new DecimalFormat("0.00").format(Double.parseDouble(endIssuedataMap.get(allList.get(i).get("problemTypeCode").toString())+"") / (Double.parseDouble(allList.get(i).get("count")+""))));
            }
            resultList.add(map);
        }

        return resultList;
    }
}