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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.jxiop.api.Enum.StationType;
import com.yeejoin.amos.boot.module.jxiop.api.dto.BudunDayGenTrendDto;
import com.yeejoin.amos.boot.module.jxiop.api.dto.BudunMonthTrendDto;
import com.yeejoin.amos.boot.module.jxiop.api.dto.BundunCompleteDto;
import com.yeejoin.amos.boot.module.jxiop.api.entity.MapRegion;
import com.yeejoin.amos.boot.module.jxiop.api.entity.Region;
import com.yeejoin.amos.boot.module.jxiop.api.entity.StationBasic;
import com.yeejoin.amos.boot.module.jxiop.api.entity.StationPlan;
import com.yeejoin.amos.boot.module.jxiop.api.mapper.MapRegionMapper;
import com.yeejoin.amos.boot.module.jxiop.api.mapper.RegionMapper;
import com.yeejoin.amos.boot.module.jxiop.api.mapper.StationBasicMapper;
import com.yeejoin.amos.boot.module.jxiop.api.util.Constants;
import com.yeejoin.amos.boot.module.jxiop.api.util.HttpRequestUtil;
import com.yeejoin.amos.boot.module.jxiop.biz.ESDto.ESMoonPowerGeneration;
import com.yeejoin.amos.boot.module.jxiop.biz.dto.SeriesData;
import com.yeejoin.amos.boot.module.jxiop.biz.dto.StationCacheInfoDto;
import com.yeejoin.amos.boot.module.jxiop.biz.service.MonitorService;
import com.yeejoin.amos.boot.module.jxiop.biz.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.component.emq.EmqKeeper;

import java.io.PipedReader;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class MonitorServiceImpl implements MonitorService {
    private final RegionMapper regionMapper;
    private final MapRegionMapper mapRegionMapper;
    private final StationBasicMapper stationBasicMapper;
    private final EmqKeeper emqKeeper;
    private final HttpRequestUtil httpRequestUtil;

    @Override
    public IPage<Map<String, Object>> operationData(String areaCode) {
        List<StationCacheInfoDto> list = getListStationCacheInfoDto();
        if (null != areaCode) {
            list = list.stream().filter(e -> e.getAreaCode().toUpperCase(Locale.ROOT).equals(areaCode.toUpperCase(Locale.ROOT))).collect(Collectors.toList());
        }
        List<Map<String, Object>> mapList = new ArrayList<>();
        Map<String, List<StationCacheInfoDto>> listMap = list.stream().collect(Collectors.groupingBy(StationCacheInfoDto::getStationType, Collectors.toList()));
        for (StationType value : StationType.values()) {
            Map<String, Object> map = new LinkedHashMap<>();
            List<StationCacheInfoDto> dtos = listMap.get(value.getCode());
            map.put("data", dtos == null ? 0 : dtos.size());
            map.put("title", dtos == null ? 0 : dtos.stream().filter(obj -> !ObjectUtils.isEmpty(obj.getInstalledCapacity())).mapToDouble(l -> Double.parseDouble(l.getInstalledCapacity())).sum());
            mapList.add(map);
        }
        IPage<Map<String, Object>> result = new Page<>();
        result.setRecords(mapList);
        result.setCurrent(1);
        result.setTotal(mapList.size());
        return result;
    }

    @Override
    public Map<String, Object> accessSituation() {
        Map<String, Object> map = new LinkedHashMap<>();
        List<StationCacheInfoDto> list = getListStationCacheInfoDto();
        double sum = list.stream().mapToDouble(l -> Double.parseDouble(l.getInstalledCapacity())).sum();
        Map<String, List<StationCacheInfoDto>> listMap = list.stream().collect(Collectors.groupingBy(StationCacheInfoDto::getStationType, Collectors.toList()));
        for (StationType value : StationType.values()) {
            List<StationCacheInfoDto> dtos = listMap.get(value.getCode());
            map.put(value.getCode(), dtos == null ? 0 : dtos.size());
            map.put(value.getCode() + "title", dtos == null ? 0 : dtos.stream().filter(obj -> !ObjectUtils.isEmpty(obj.getInstalledCapacity())).mapToDouble(l -> Double.parseDouble(l.getInstalledCapacity())).sum());
        }
        map.put("total", list.size());
        map.put("num", sum);
        try {
            emqKeeper.getMqttClient().publish("/accessSituation/topic", JSON.toJSONString(map).getBytes(), 0, true);
        } catch (MqttException e) {

        }
        return map;
    }


    @Override
    public Map<String, Object> qyAccessSituation() {
        Map<String, Object> map = new LinkedHashMap<>();
        List<StationCacheInfoDto> list = this.getListStationCacheInfoDto();
        Map<String, List<StationCacheInfoDto>> belongAreaList = list.stream().collect(Collectors.groupingBy(StationCacheInfoDto::getAreaCode));
        for (String s : belongAreaList.keySet()) {
            double sum = belongAreaList.get(s).stream().mapToDouble(l -> Double.parseDouble(l.getInstalledCapacity())).sum();
            Map<String, List<StationCacheInfoDto>> listMap = list.stream().collect(Collectors.groupingBy(StationCacheInfoDto::getStationType, Collectors.toList()));
            for (StationType value : StationType.values()) {
                List<StationCacheInfoDto> dtos = listMap.get(value.getCode());
                map.put(value.getCode(), dtos == null ? 0 : dtos.size());
                map.put(value.getCode() + "title", dtos == null ? 0 : dtos.stream().filter(obj -> !ObjectUtils.isEmpty(obj.getInstalledCapacity())).mapToDouble(l -> Double.parseDouble(l.getInstalledCapacity())).sum());
            }
            map.put("total", list.size());
            map.put("num", sum);
            try {
                emqKeeper.getMqttClient().publish("/accessSituation/topic/" + s, JSON.toJSONString(map).getBytes(), 1, true);
            } catch (MqttException e) {

            }
        }
        return map;
    }

    /**
     * 获取场站的缓存信息，后续启动时需要将此数据从
     *
     * @return
     */
    public List<StationCacheInfoDto> getListStationCacheInfoDto() {
        List<StationCacheInfoDto> stationCacheInfoDtos = new ArrayList<>();
        List<Region> regionList = regionMapper.selectList(new QueryWrapper<Region>().eq("LEVEL", 1));
        List<MapRegion> mapRegionList = mapRegionMapper.selectList(new QueryWrapper<MapRegion>().isNotNull("name"));
        List<StationBasic> stationBasicList = stationBasicMapper.selectList(new QueryWrapper<StationBasic>().isNotNull("belong_area").isNotNull("fan_gateway_id"));
        for (int i = 0; i < stationBasicList.size(); i++) {
            StationBasic stationBasic = stationBasicList.get(i);
            StationCacheInfoDto stationCacheInfoDto = new StationCacheInfoDto();
            stationCacheInfoDto.setStationId(stationBasic.getSequenceNbr().toString());
            stationCacheInfoDto.setStationName(stationBasic.getStationName());
            stationCacheInfoDto.setStationType(stationBasic.getStationType());
            stationCacheInfoDto.setBelongProvince(regionList.stream().filter(region -> region.getRegionCode().toString().equals(stationBasic.getBelongArea().replace("[", "").split(",")[0])).map(region -> region.getRegionName()).collect(Collectors.toList()).get(0));
            stationCacheInfoDto.setBelongArea(mapRegionList.stream().filter(mapRegion -> mapRegion.getProvince().contains(stationCacheInfoDto.getBelongProvince().substring(0, 2)) || mapRegion.getProvince().contains(stationCacheInfoDto.getBelongProvince().substring(0, 3))).map(mapRegion -> mapRegion.getName()).collect(Collectors.toList()).get(0));
            Double installedCapacity = 0.0d;
            if (!ObjectUtils.isEmpty(stationBasic.getInstalledCapacity())) {
                installedCapacity = stationBasic.getInstalledCapacity();
            }
            stationCacheInfoDto.setInstalledCapacity(String.format("%.2f", installedCapacity));
            stationCacheInfoDto.setFanGatewayId(stationBasic.getFanGatewayId());
            stationCacheInfoDto.setAreaCode(mapRegionList.stream().filter(mapRegion -> mapRegion.getProvince().contains(stationCacheInfoDto.getBelongProvince().substring(0, 2)) || mapRegion.getProvince().contains(stationCacheInfoDto.getBelongProvince().substring(0, 3))).map(mapRegion -> mapRegion.getAreaCode()).collect(Collectors.toList()).get(0));
            stationCacheInfoDto.setBoosterGatewayId(stationBasic.getBoosterGatewayId());
            stationCacheInfoDto.setBoosterCoreName(stationBasic.getBoosterCoreName());
            stationCacheInfoDto.setStationCoreName(stationBasic.getStationCoreName());
            stationCacheInfoDtos.add(stationCacheInfoDto);
        }

        return stationCacheInfoDtos;
    }

    public Map<String, Object> gettimedateyfd(String areaName) {
        MapRegion mapRegion = mapRegionMapper.selectOne(new QueryWrapper<MapRegion>().eq("name", areaName));
        if (!areaName.contains(Constants.areaChinese)) {
            areaName = Constants.areaChinese;
        }

        String requestUrl = Constants.BASE_URL + "?" + Constants.get_month_generation_trend_url + "&areaName=" + areaName;
        List<String> list = new ArrayList<>();
        List<Double> listData = new ArrayList<>();
        List<BudunMonthTrendDto> budunMonthTrendDtos = httpRequestUtil.getResPonse(requestUrl, Constants.REQUEST_GET, "", Constants.resovleRule_data, BudunMonthTrendDto.class);
        budunMonthTrendDtos.forEach(budunMonthTrendDto -> {
            listData.add(budunMonthTrendDto.getGenerating_capacity());
            list.add(budunMonthTrendDto.getMonth().toString());
        });
        Map<String, Object> mapjn = new HashMap<>();
        mapjn.put("seriesData", listData);
        mapjn.put("axisData", list);
        try {
            if (!ObjectUtils.isEmpty(mapRegion) && !ObjectUtils.isEmpty(mapRegion.getAreaCode())) {
                emqKeeper.getMqttClient().publish("qyyfd/fdqs/" + mapRegion.getAreaCode(), JSON.toJSONString(mapjn).getBytes(), 0, false);
            }

        } catch (MqttException e) {
            e.printStackTrace();
        }
        return mapjn;
    }

    @Override
    public Map<String, Object> gettimedateyfdqs() {
        String requestUrl = Constants.BASE_URL + "?" + Constants.get_generated_quota_trend;
        List<BundunCompleteDto> bundunCompleteDtoList = httpRequestUtil.getResPonse(requestUrl, Constants.REQUEST_GET, "", Constants.resovleRule_data, BundunCompleteDto.class);

        Map<String, Object> mapjn = new HashMap<>();
        List<String> list = new ArrayList<>();
        List<Double> listData = new ArrayList<>();
        bundunCompleteDtoList.forEach(bundunCompleteDto -> {
            listData.add(bundunCompleteDto.getGenerating_capacity_complete());
            list.add(bundunCompleteDto.getMonth().toString());
        });
        mapjn.put("seriesData", listData);
        mapjn.put("axisData", list);
        try {
            emqKeeper.getMqttClient().publish("topic_yfdqs", JSON.toJSONString(mapjn).getBytes(), 0, false);
        } catch (MqttException e) {
            e.printStackTrace();
        }

        return mapjn;


    }

    @Override
    public Map<String, Object> gettimedateqyyfd(String areaName) {
        String requestUrl = Constants.BASE_URL + "?" + Constants.get_generated_quota_trend + "&areaName=" + areaName;
        MapRegion mapRegion = mapRegionMapper.selectOne(new QueryWrapper<MapRegion>().eq("name", areaName));
        if (!areaName.contains(Constants.areaChinese)) {
            areaName = Constants.areaChinese;
        }
        List<BundunCompleteDto> bundunCompleteDtoList = httpRequestUtil.getResPonse(requestUrl, Constants.REQUEST_GET, "", Constants.resovleRule_data, BundunCompleteDto.class);

        Map<String, Object> mapjn = new HashMap<>();
        List<String> list = new ArrayList<>();
        List<Double> listData = new ArrayList<>();
        bundunCompleteDtoList.forEach(bundunCompleteDto -> {
            listData.add(bundunCompleteDto.getGenerating_capacity_complete());
            list.add(bundunCompleteDto.getMonth().toString());
        });
        mapjn.put("seriesData", listData);
        mapjn.put("axisData", list);
        try {
            if (!ObjectUtils.isEmpty(mapRegion) && !ObjectUtils.isEmpty(mapRegion.getAreaCode())) {
                emqKeeper.getMqttClient().publish("qyyfd/fdqs/" + mapRegion.getAreaCode(), JSON.toJSONString(mapjn).getBytes(), 0, false);
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }

        return mapjn;

    }

    @Override
    public SeriesData getSeriesDataqg() {
        String requestUrl = Constants.BASE_URL + "?" + Constants.get_day_generation_trend;
        List<BudunDayGenTrendDto> budunDayGenTrendDtoList = httpRequestUtil.getResPonse(requestUrl, Constants.REQUEST_GET, "", Constants.resovleRule_data, BudunDayGenTrendDto.class);
        List<Map<String,Object>> list=new ArrayList<>();
        List<String> listdate = new ArrayList<>();
        List<Double> listjn= new ArrayList<>();
        List<Double> listqn= new ArrayList<>();
        String currentYear = LocalDate.now().getYear()+"-";
        budunDayGenTrendDtoList.forEach(bundunDayGenTrendDto -> {
         listjn.add(bundunDayGenTrendDto.getCurrent_generating_capacity());
         listqn.add(bundunDayGenTrendDto.getLast_generating_capacity());
         listdate.add(bundunDayGenTrendDto.getReporting_date().replace(currentYear,""));
        });
        Map<String, Object> mapjn = new HashMap<>();
        mapjn.put("data", listjn);
        mapjn.put("name", "当前值");
        Map<String, Object> mapqn = new HashMap<>();
        mapqn.put("data", listqn);
        mapqn.put("name", "同期值");
        list.add(mapjn);
        list.add(mapqn);
        SeriesData seriesData = new SeriesData();
        seriesData.setSeriesData(list);
        //获取日期

        seriesData.setAxisData(listdate);
        try {
            emqKeeper.getMqttClient().publish("countryFd", JSON.toJSONString(seriesData).getBytes(), 0, false);
        } catch (MqttException e) {
            e.printStackTrace();
        }

        return seriesData;
    }

    public SeriesData getSeriesDataqy( String areaCode){
        MapRegion mapRegion = mapRegionMapper.selectOne(new QueryWrapper<MapRegion>().eq("areaCode",areaCode));
        String areaName="";
        if(!ObjectUtils.isEmpty(mapRegion)&&!ObjectUtils.isEmpty(mapRegion.getName())&&!mapRegion.getName().contains(Constants.areaChinese)){
        areaName = mapRegion.getName().replace(Constants.areaChinese,"");
        }
        String requestUrl = Constants.BASE_URL + "?" + Constants.get_day_generation_trend+"&areaName="+areaName;
        List<BudunDayGenTrendDto> budunDayGenTrendDtoList = httpRequestUtil.getResPonse(requestUrl, Constants.REQUEST_GET, "", Constants.resovleRule_data, BudunDayGenTrendDto.class);
        List<Map<String,Object>> list=new ArrayList<>();
        List<String> listdate = new ArrayList<>();
        List<Double> listjn= new ArrayList<>();
        List<Double> listqn= new ArrayList<>();
        String currentYear = LocalDate.now().getYear()+"-";
        budunDayGenTrendDtoList.forEach(bundunDayGenTrendDto -> {
            listjn.add(bundunDayGenTrendDto.getCurrent_generating_capacity());
            listqn.add(bundunDayGenTrendDto.getLast_generating_capacity());
            listdate.add(bundunDayGenTrendDto.getReporting_date().replace(currentYear,""));
        });
        Map<String, Object> mapjn = new HashMap<>();
        mapjn.put("data", listjn);
        mapjn.put("name", "当前值");
        Map<String, Object> mapqn = new HashMap<>();
        mapqn.put("data", listqn);
        mapqn.put("name", "同期值");
        list.add(mapjn);
        list.add(mapqn);
        SeriesData seriesData = new SeriesData();
        seriesData.setSeriesData(list);
        seriesData.setAxisData(listdate);
        try {
            emqKeeper.getMqttClient().publish("qy/fdqs/"+areaCode, JSON.toJSONString(seriesData).getBytes(),1,true);
        } catch (MqttException e) {
            e.printStackTrace();
        }

        return seriesData;

    }
}
