package com.ruoyi.web.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.ucp.entity.*;
import com.ruoyi.ucp.feign.AdapterApi;
import com.ruoyi.ucp.service.*;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

//@RestController
@RestController
@RequestMapping("/predict")
public class PredictController {

    @Resource
    private IPointInfoService pointInfoService;
    @Resource
    private AdapterApi adapterApi;
    @Resource
    private JavaFunctionJobHandler task;
    @Resource
    private IRealtimePredictService realtimePredictService;
    @Resource
    private IHistoryPredictService historyPredictService;
    @Resource
    private IStationInfoMinService stationInfoMinService;
    @Resource
    private IStationInfoMin2Service stationInfoMin2Service;
    @Resource
    private IProjectInfoMin2Service projectInfoMin2Service;


    private Map<String, PointInfo> tbInfos = new ConcurrentHashMap<>();

    private Map<String, String> pj2st = null;

    @GetMapping("/stbs")
    public Map<String, List<Integer>> stbs() {
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                .in(PointInfo::getUniformCode, "AI114");
        List<PointInfo> list = pointInfoService.list(wrapper);
        return list.stream().collect(Collectors.groupingBy(pi -> pi.getStationId().replaceFirst("GJNY_SXGS_", "")
                .replaceFirst("_FDC_STA", ""), Collectors.mapping(pi -> Integer.parseInt(pi.getTurbineId()
                .replaceFirst("GJNY_SXGS_.+_F_WT_", "").replaceFirst("_EQ", "")), Collectors.toList())));
    }

    @GetMapping("/stb")
    public Map<String, List<String>> stb() {
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                .in(PointInfo::getUniformCode, "AI114");
        List<PointInfo> list = pointInfoService.list(wrapper);
        return list.stream().collect(Collectors.groupingBy(pi -> pi.getStationId(), Collectors.mapping(pi -> pi.getTurbineId(), Collectors.toList())));
    }

    @GetMapping("/projectIds")
    public Map<String, List<String>> projectIds() {
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                .in(PointInfo::getUniformCode, "AI121");
        List<PointInfo> list = pointInfoService.list(wrapper);
        if (pj2st == null) {
            pj2st = list.stream().collect(Collectors.toMap(PointInfo::getProjectId, PointInfo::getStationId, (k1, k2) -> k1));
        }
        return list.stream().collect(Collectors.groupingBy(pi -> pi.getProjectId(), Collectors.mapping(pi -> pi.getTurbineId(), Collectors.toList())));
    }

    @GetMapping("/snap")
    public Map<String, Collection<GlycSj>> haha(@RequestParam(value = "stationId", required = false) String stationId,
                                                @RequestParam(value = "beginTime", required = false) String beginTime,
                                                @RequestParam(value = "endTime", required = false) String endTime,
                                                @RequestParam(value = "interval", required = false) Integer interval) {
        //2024-10-15 00:00:00,15,2024-10-15 00:15:00
        DateTime start = DateUtil.parse(beginTime);
        DateTime end = DateUtil.parse(endTime);
        String[] names = {"AI114", "AI066", "AI060", "AI067", "AI082", "AI073", "AI004", "AI047", "AI072", "AI074"};
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                .eq(PointInfo::getStationId, stationId)
                .in(PointInfo::getUniformCode, names);
        List<PointInfo> list = pointInfoService.list(wrapper);
        Map<String, List<PointInfo>> tbPis = list.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId));
        Map<String, Collection<GlycSj>> result = new HashMap<>();
        tbPis.forEach((tbId, pis) -> {
            List<PointData> zt = task.calcTurbineSimpleZt(start, end, interval, tbId);
            Map<String, GlycSj> map = new TreeMap<>();
            for (PointInfo info : pis) {
                try {
                    List<PointData> s = adapterApi.getHistorySnap(URI.create("http://172.16.12.103:8011/ts"), info.getPointKey(),
                            start.getTime(), end.getTime(), interval);
                    long j = start.getTime();
                    String dt = null;
                    GlycSj glycSj = null;
                    //AI066	风速，AI060	发电机转速，AI065	风机状态点，AI067	风向，AI082	桨叶1角度，AI073	机舱方向/对风角度
                    //AI004	U1绕组温度，AI047	电机温度2，AI072	环境温度，AI074	机舱温度
                    switch (info.getUniformCode()) {
                        case "AI114":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setGl(s.get(i).getValue());

                                glycSj.setZt(zt.get(i) == null ? null : zt.get(i).getValue());
                                //                            glycSj.setActualTime(DateUtil.formatDateTime(DateUtil.date(s.get(i).getTs())));
                                j += interval * 1000;//GJNY_SXGS_LJS_F_WT_
                                //                                    glycSj.setTurbineId(info.getTurbineId().replaceFirst("GJNY_SXGS_","").replaceFirst("F_WT_","").replaceFirst("_EQ",""));
                                glycSj.setTurbineId(info.getTurbineId().replaceFirst("GJNY_SXGS_.+_F_WT_", "").replaceFirst("_EQ", ""));
                            }
                            break;
                        case "AI066":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setFs(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI060":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setFdjzs(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI065":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setZt(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI067":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setFx(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI082":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setJyjd(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI073":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setDfjd(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI004":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setNjwd(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI047":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setDjwd(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI072":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setHjwd(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                        case "AI074":
                            for (int i = 0; i < s.size(); i++) {
                                dt = DateUtil.formatDateTime(new Date(j));
                                glycSj = map.get(dt);
                                if (glycSj == null) {
                                    glycSj = new GlycSj();
                                    map.put(dt, glycSj);
                                }
                                glycSj.setJcwd(s.get(i).getValue());
                                j += interval * 1000;
                            }
                            break;
                    }
                    map.forEach((k, v) -> {
                        v.setTime(k);
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            result.put(tbId, map.values());
        });
        return result;
    }

    @GetMapping("/latest")
    public Map<String, GlycSj> latest(@RequestParam(value = "stationId", required = false) String stationId) {
        String[] names = {"AI114", "AI066", "AI060", "AI067", "AI082", "AI073", "AI004", "AI047", "AI072", "AI074"};
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                .eq(PointInfo::getStationId, stationId)
                .in(PointInfo::getUniformCode, names);
        List<PointInfo> list = pointInfoService.list(wrapper);
        Map<String, List<PointInfo>> tbPis = list.stream().collect(Collectors.groupingBy(PointInfo::getTurbineId));
        String keys = list.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, GlycSj> result = new HashMap<>();
        Map<String, Double> zt = task.calcRealtimeTurbineZt(stationId);
        Map<String, PointData> latest = adapterApi.getLatest(URI.create("http://172.16.12.103:8011/ts"), keys);
        tbPis.forEach((tbId, pis) -> {
            GlycSj glycSj = new GlycSj();
            for (PointInfo info : pis) {
                PointData data = latest.get(info.getPointKey());
                Double v1 = 0.0;
                if (data != null) v1 = data.getValue();
                try {
                    switch (info.getUniformCode()) {
                        case "AI114":
                            glycSj.setGl(v1);
                            glycSj.setZt(zt.get(tbId));
                            glycSj.setTurbineId(tbId.replaceFirst("GJNY_SXGS_.+_F_WT_", "").replaceFirst("_EQ", ""));
                            break;
                        case "AI066":
                            glycSj.setFs(v1);
                            break;
                        case "AI060":
                            glycSj.setFdjzs(v1);
                            break;
                        case "AI065":
                            glycSj.setZt(zt.get(tbId));
                            break;
                        case "AI067":
                            glycSj.setFx(v1);
                            break;
                        case "AI082":
                            glycSj.setJyjd(v1);
                            break;
                        case "AI073":
                            glycSj.setDfjd(v1);
                            break;
                        case "AI004":
                            glycSj.setNjwd(v1);
                            break;
                        case "AI047":
                            glycSj.setDjwd(v1);
                            break;
                        case "AI072":
                            glycSj.setHjwd(v1);
                            break;
                        case "AI074":
                            glycSj.setJcwd(v1);
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            result.put(tbId, glycSj);
        });
        return result;
    }

    @GetMapping("/snap/station/dq")
    public List<StationInfoMin> latestStationDq(@RequestParam(value = "stationId", required = false) String stationId,
                                                @RequestParam(value = "beginTime", required = false) String beginTime,
                                                @RequestParam(value = "endTime", required = false) String endTime) {

        DateTime begin = DateUtil.parse(beginTime);
        DateTime middle = DateUtil.parse("2024-11-07");
        DateTime end = DateUtil.parse(endTime);
        QueryWrapper<StationInfoMin> minWrapper = new QueryWrapper<>();
        minWrapper.lambda().eq(StationInfoMin::getStationId, stationId).between(StationInfoMin::getRecordDate, begin, middle)
                .orderByAsc(StationInfoMin::getRecordDate);
        List<StationInfoMin> list = stationInfoMinService.list(minWrapper);
//                List<StationInfoMin> min=new ArrayList<>();
        int i = 1;
        DateTime minBegin = middle, minEnd = DateUtil.offsetMinute(middle, 15);
        while (minEnd.isBefore(end)) {
            minEnd = DateUtil.offsetMinute(middle, i * 15);
            StationInfoMin day = task.calcStationSjglAgcPjfsHjwdDlMin2(minBegin, minEnd, stationId);
            System.out.println(minBegin.toString() + "," + minEnd.toString());
            i++;
            minBegin = minEnd;
            list.add(day);
        }

        return list;
    }

    @GetMapping("/snap/station")
    public List<StationInfoMin2> latestStation(@RequestParam(value = "stationId", required = false) String stationId,
                                               @RequestParam(value = "beginTime", required = false) String beginTime,
                                               @RequestParam(value = "endTime", required = false) String endTime) {
        QueryWrapper<StationInfoMin2> wrapper = new QueryWrapper<>();
        wrapper.select("max(record_date) record_date").eq("station_id", stationId);
        StationInfoMin2 one = stationInfoMin2Service.getOne(wrapper);

        DateTime begin = DateUtil.parse(beginTime);
        //DateTime middle = DateUtil.parse("2024-11-07");
        DateTime middle = DateUtil.date(one.getRecordDate());
        DateTime end = DateUtil.parse(endTime);
        QueryWrapper<StationInfoMin2> minWrapper = new QueryWrapper<>();
        minWrapper.lambda().eq(StationInfoMin2::getStationId, stationId).between(StationInfoMin2::getRecordDate, begin, middle)
                .orderByAsc(StationInfoMin2::getRecordDate);
        List<StationInfoMin2> list = stationInfoMin2Service.list(minWrapper);
//                List<StationInfoMin> min=new ArrayList<>();
        int i = 1;
        DateTime minBegin = middle, minEnd = DateUtil.offsetMinute(middle, 15);
        while (minEnd.isBefore(end)) {
            minEnd = DateUtil.offsetMinute(middle, i * 15);
            StationInfoMin2 day = task.calcStationPjfsHjwdMin2(minEnd, stationId);
            System.out.println(minBegin.toString() + "," + minEnd.toString());
            i++;
            minBegin = minEnd;
            list.add(day);
        }
        if (stationId.equals("GJNY_SXGS_CSL_FDC_STA")) {
            list.stream().peek(m2 -> m2.setYxts(0L)).collect(Collectors.toList());
        }
        return list;
    }

    @GetMapping("/snap/project")
    public List<ProjectInfoMin2> latestProject(@RequestParam(value = "projectId", required = false) String projectId,
                                               @RequestParam(value = "beginTime", required = false) String beginTime,
                                               @RequestParam(value = "endTime", required = false) String endTime) {

        QueryWrapper<ProjectInfoMin2> wrapper = new QueryWrapper<>();
        wrapper.select("max(record_date) record_date").eq("project_id", projectId);
        ProjectInfoMin2 one = projectInfoMin2Service.getOne(wrapper);
        DateTime middle = DateUtil.date(one.getRecordDate());

        DateTime begin = DateUtil.parse(beginTime);
        //DateTime middle = DateUtil.parse("2024-11-07");
        DateTime end = DateUtil.parse(endTime);
        QueryWrapper<ProjectInfoMin2> minWrapper = new QueryWrapper<>();
        minWrapper.lambda().eq(ProjectInfoMin2::getProjectId, projectId).between(ProjectInfoMin2::getRecordDate, begin, middle)
                .orderByAsc(ProjectInfoMin2::getRecordDate);
        List<ProjectInfoMin2> list = projectInfoMin2Service.list(minWrapper);
        int i = 1;
        DateTime minBegin = middle, minEnd = DateUtil.offsetMinute(middle, 15);
        while (minEnd.isBefore(end)) {
            minEnd = DateUtil.offsetMinute(middle, i * 15);
            ProjectInfoMin2 min2 = task.calcProjectPjfsHjwdMin2(minEnd, projectId);
            System.out.println(minBegin.toString() + "," + minEnd.toString());
            i++;
            minBegin = minEnd;
            list.add(min2);
        }
        return list;
    }

    @GetMapping("/latest/station/dq")
    public StationInfoMin latestStationDq(@RequestParam(value = "stationId", required = false) String stationId) {
        DateTime date = DateUtil.beginOfMinute(DateUtil.date());
        int i = Math.floorDiv(date.minute(), 15) * 15;
        date.setMinutes(i);
        DateTime minute = DateUtil.offsetMinute(date, -15);
        return task.calcStationSjglAgcPjfsHjwdDlMin2(minute, date, stationId);
    }

    @GetMapping("/latest/station")
    public StationInfoMin2 latestStation(@RequestParam(value = "stationId", required = false) String stationId) {
        DateTime date = DateUtil.beginOfMinute(DateUtil.date());
        int i = Math.floorDiv(date.minute(), 15) * 15;
        date.setMinutes(i);
        StationInfoMin2 min2 = task.calcStationPjfsHjwdMin2(date, stationId);
        if (stationId.equals("GJNY_SXGS_CSL_FDC_STA")) min2.setYxts(0L);
        return min2;
    }
    @GetMapping("/latest/project")
    public ProjectInfoMin2 latestProject(@RequestParam(value = "projectId", required = false) String projectId) {
        DateTime date = DateUtil.beginOfMinute(DateUtil.date());
        int i = Math.floorDiv(date.minute(), 15) * 15;
        date.setMinutes(i);
        ProjectInfoMin2 min2 = task.calcProjectPjfsHjwdMin2(date, projectId);
        return min2;
    }

    @GetMapping("/latest/station/dq2")
    public StationInfoMin latestStationDq2(@RequestParam(value = "stationId", required = false) String stationId) {
        DateTime date = DateUtil.beginOfMinute(DateUtil.date());
        int i = Math.floorDiv(date.minute(), 15) * 15;
        date.setMinutes(i);
        DateTime minute = DateUtil.offsetMinute(date, -15);
        //AGC
        PointInfo entityAgc = getEntity("AGC002", "booster", stationId);
        getLatestByEntity(entityAgc);
        //出线
        PointInfo entityCx = getEntity("AGC001", "booster", stationId);
        getRawDataByEntity(entityCx, minute, date);
        //风速
        List<PointInfo> entityFs = getEntitys("AI066", "turbine", stationId);
        getRawDataByEntity(entityFs, minute, date);
        //环境温度
        List<PointInfo> entityHjwd = getEntitys("AI072", "turbine", stationId);
        getLatestByEntity(entityHjwd);
        //日发电量
        PointInfo entity = getEntity("Z-ZXYG-JX", "meter", stationId);
        getSectionDataByEntity(entity, minute, date);

        StationInfoMin day = new StationInfoMin();
        day.setStationId(stationId);
        day.setRecordDate(date);
        double pjfs = entityFs.stream().mapToDouble(pi -> pi.getPointDatas().stream().mapToDouble(PointData::getValue).average().orElse(0.0)).average().orElse(0);
        day.setPjfs(pjfs);
        double cxgl = entityCx.getPointDatas().stream().mapToDouble(PointData::getValue).average().orElse(0.0);
        cxgl = cxgl * entityCx.getCoef();
        day.setPjgl(cxgl);
        double agc = entityAgc.getPointDatas().get(0).getValue() * entityAgc.getCoef();
        day.setAgc(agc);
        double rfdl = (entity.getPointDatas().get(1).getValue() - entity.getPointDatas().get(0).getValue()) * entity.getCoef();
        day.setRfdl(rfdl);
        double hjwd = entityHjwd.stream().mapToDouble(pi -> pi.getPointDatas().stream().mapToDouble(PointData::getValue).average().orElse(0.0)).average().orElse(0);
        day.setHjwd(hjwd);
        return day;
    }

    @GetMapping("/haha2")
    public Map<String, Collection<GlycSj>> haha2(@RequestParam(value = "stationId", required = false) String stationId,
                                                 @RequestParam(value = "beginTime", required = false) String beginTime,
                                                 @RequestParam(value = "endTime", required = false) String endTime,
                                                 @RequestParam(value = "interval", required = false) Integer interval) {
        String a = "[\n" +
                "  {\n" +
                "    \"turbineId\": \"0011\",\n" +
                "    \"time\": \"2024-10-14 22:22:00\",\n" +
                "    \"gl\": 1744.0,\n" +
                "    \"fs\": 6.982665061950684,\n" +
                "    \"fdjzs\": 169.0,\n" +
                "    \"zt\": 4.0,\n" +
                "    \"fx\": 0.13901925086975098,\n" +
                "    \"jyjd\": 0.0,\n" +
                "    \"dfjd\": 0.1688677817583084,\n" +
                "    \"njwd\": 61.0,\n" +
                "    \"djwd\": 32.0,\n" +
                "    \"hjwd\": 18.921875,\n" +
                "    \"jcwd\": 29.0\n" +
                "  },\n" +
                "  {\n" +
                "    \"turbineId\": \"0011\",\n" +
                "    \"time\": \"2024-10-14 22:27:00\",\n" +
                "    \"gl\": 2144.0,\n" +
                "    \"fs\": 7.244823455810547,\n" +
                "    \"fdjzs\": 176.0,\n" +
                "    \"zt\": 4.0,\n" +
                "    \"fx\": -0.04913616180419922,\n" +
                "    \"jyjd\": 0.0,\n" +
                "    \"dfjd\": -0.04758832976222038,\n" +
                "    \"njwd\": 63.0,\n" +
                "    \"djwd\": 32.0,\n" +
                "    \"hjwd\": 19.046875,\n" +
                "    \"jcwd\": 29.225000381469727\n" +
                "  },\n" +
                "  {\n" +
                "    \"turbineId\": \"0011\",\n" +
                "    \"time\": \"2024-10-14 22:32:00\",\n" +
                "    \"gl\": 1848.0,\n" +
                "    \"fs\": 7.532032012939453,\n" +
                "    \"fdjzs\": 171.0,\n" +
                "    \"zt\": 4.0,\n" +
                "    \"fx\": 0.024447917938232422,\n" +
                "    \"jyjd\": 0.0,\n" +
                "    \"dfjd\": 0.0644155889749527,\n" +
                "    \"njwd\": 65.0,\n" +
                "    \"djwd\": 33.0,\n" +
                "    \"hjwd\": 19.15625,\n" +
                "    \"jcwd\": 29.225000381469727\n" +
                "  },\n" +
                "  {\n" +
                "    \"turbineId\": \"0011\",\n" +
                "    \"time\": \"2024-10-14 22:37:00\",\n" +
                "    \"gl\": 1528.0,\n" +
                "    \"fs\": 6.8463616371154785,\n" +
                "    \"fdjzs\": 159.0,\n" +
                "    \"zt\": 4.0,\n" +
                "    \"fx\": 0.11313247680664062,\n" +
                "    \"jyjd\": 0.0,\n" +
                "    \"dfjd\": 0.11275594681501389,\n" +
                "    \"njwd\": 64.5,\n" +
                "    \"djwd\": 33.0,\n" +
                "    \"hjwd\": 19.125,\n" +
                "    \"jcwd\": 29.149999618530273\n" +
                "  },\n" +
                "  {\n" +
                "    \"turbineId\": \"0011\",\n" +
                "    \"time\": \"2024-10-14 22:42:00\",\n" +
                "    \"gl\": 1280.0,\n" +
                "    \"fs\": 6.929559230804443,\n" +
                "    \"fdjzs\": 152.0,\n" +
                "    \"zt\": 4.0,\n" +
                "    \"fx\": 0.03271770477294922,\n" +
                "    \"jyjd\": 0.0,\n" +
                "    \"dfjd\": 0.031964123249053955,\n" +
                "    \"njwd\": 63.0,\n" +
                "    \"djwd\": 33.0,\n" +
                "    \"hjwd\": 19.078125,\n" +
                "    \"jcwd\": 29.39999961853027\n" +
                "  }\n" +
                "]";
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                .eq(PointInfo::getStationId, stationId);
        List<PointInfo> list = pointInfoService.list(wrapper);
        Map<String, Collection<GlycSj>> result = new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        List<GlycSj> glycSjList = null;
        try {
            glycSjList = objectMapper.readValue(a, objectMapper.getTypeFactory().constructCollectionType(List.class, GlycSj.class));
            // 现在你可以使用glycSjList了
        } catch (IOException e) {
            e.printStackTrace();
            // 处理异常，比如记录日志或抛出运行时异常
        }
        result.put(list.get(0).getTurbineId(), glycSjList);
        return result;
    }

    @GetMapping("/haha")
    public Map<String, GlycSj> haha(@RequestParam(value = "stationId", required = false) String stationId) {
        String a = "  {\n" +
                "    \"turbineId\": \"0011\",\n" +
                "    \"time\": \"2024-10-14 22:22:00\",\n" +
                "    \"gl\": 1744.0,\n" +
                "    \"fs\": 6.982665061950684,\n" +
                "    \"fdjzs\": 169.0,\n" +
                "    \"zt\": 4.0,\n" +
                "    \"fx\": 0.13901925086975098,\n" +
                "    \"jyjd\": 0.0,\n" +
                "    \"dfjd\": 0.1688677817583084,\n" +
                "    \"njwd\": 61.0,\n" +
                "    \"djwd\": 32.0,\n" +
                "    \"hjwd\": 18.921875,\n" +
                "    \"jcwd\": 29.0\n" +
                "  }";
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                .eq(PointInfo::getStationId, stationId);
        List<PointInfo> list = pointInfoService.list(wrapper);
        Map<String, GlycSj> result = new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        GlycSj glycSjList = null;
        try {
            glycSjList = objectMapper.readValue(a, GlycSj.class);
            // 现在你可以使用glycSjList了
        } catch (IOException e) {
            e.printStackTrace();
            // 处理异常，比如记录日志或抛出运行时异常
        }
        result.put(list.get(0).getTurbineId(), glycSjList);
        return result;
    }

    @PostMapping("/write")
    public boolean write(@RequestBody Map<String, List<GlycSj2>> data) {
        try {
            DateTime date = DateUtil.beginOfMinute(DateUtil.date());
            int i = Math.floorDiv(date.minute(), 15) * 15;
            date.setMinutes(i);
            if (CollUtil.isEmpty(tbInfos)) {
                QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
                wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                        .in(PointInfo::getUniformCode, "AI121");
                List<PointInfo> list = pointInfoService.list(wrapper);
                tbInfos = list.stream().collect(Collectors.toMap(PointInfo::getTurbineId, Function.identity()));
            }
            List<RealtimePredict> rpList = new ArrayList<>();
            List<HistoryPredict> hpList = new ArrayList<>();
            List<String> ids = new ArrayList<>();
            data.forEach((tbId, glycsjs) -> {
                PointInfo info = tbInfos.get(tbId);
                for (GlycSj2 glycsj : glycsjs) {
                    RealtimePredict rp = new RealtimePredict();
                    rp.setId(tbId + glycsj.getTime());
                    ids.add(rp.getId());
                    rp.setModelId("1");
                    rp.setPredictType("CDQ");
                    rp.setDeviceType("turbine");
                    rp.setTime(DateUtil.parseDateTime(glycsj.getTime()));
                    rp.setSiteId(info.getStationId());
                    rp.setPeriodId(info.getProjectId());
                    rp.setLineId(info.getLineId());
                    rp.setTurbineId(tbId);
                    rp.setPredictPower(glycsj.getPower());
                    rp.setPredictEnergy(glycsj.getPower() / 4);
                    rpList.add(rp);
                    HistoryPredict hp = new HistoryPredict();
                    hp.setModelId("1");
                    hp.setPredictType("CDQ");
                    hp.setDeviceType("turbine");
                    hp.setDataTime(date);
                    hp.setPredictTime(DateUtil.parseDateTime(glycsj.getTime()));
                    hp.setSiteId(info.getStationId());
                    hp.setPeriodId(info.getProjectId());
                    hp.setLineId(info.getLineId());
                    hp.setTurbineId(tbId);
                    hp.setPredictPower(glycsj.getPower());
                    hp.setPredictEnergy(glycsj.getPower() / 4);
                    hpList.add(hp);
                }
            });
            realtimePredictService.removeBatchByIds(ids);
            realtimePredictService.saveBatch(rpList);
            historyPredictService.saveBatch(hpList);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @PostMapping("/write/station/{type}")
    public boolean writeStation(@PathVariable String type, @RequestBody Map<String, List<GlycSj2>> data) {
        try {
            DateTime date = DateUtil.beginOfMinute(DateUtil.date());
            int i = Math.floorDiv(date.minute(), 15) * 15;
            date.setMinutes(i);
            List<RealtimePredict> rpList = new ArrayList<>();
            List<HistoryPredict> hpList = new ArrayList<>();
            List<String> ids = new ArrayList<>();
            String modelId = "1";
            String predictType = type.toUpperCase();
            String deviceType = "station";
            data.forEach((stId, glycsjs) -> {
                //yyyy-MM-dd HH:mm:ss
                //GJNY_SXGS_JSL_FDC_STA
                //2024-10-23 15:00:00
                String sstId = stId.replaceFirst("GJNY_SXGS_", "").replaceFirst("STA", "");
                for (GlycSj2 glycsj : glycsjs) {
                    DateTime ycTime = DateUtil.parseDateTime(glycsj.getTime());
                    String t = StrUtil.removeSuffix(glycsj.getTime(), ":00").replaceFirst(" ", "_").replaceFirst(":", "-");
                    RealtimePredict rp = new RealtimePredict();
                    rp.setId(predictType + "_" + modelId + "_" + sstId + t);
                    ids.add(rp.getId());
                    rp.setModelId(modelId);
                    rp.setPredictType(predictType);
                    rp.setDeviceType(deviceType);
                    rp.setTime(ycTime);
                    rp.setSiteId(stId);
                    rp.setPredictPower(glycsj.getPower());
                    rp.setPredictEnergy(glycsj.getEnergy());
                    rpList.add(rp);
                    if (predictType.equals("ZCQ")) continue;
                    HistoryPredict hp = new HistoryPredict();
                    hp.setModelId(modelId);
                    hp.setPredictType(predictType);
                    hp.setDeviceType(deviceType);
                    hp.setDataTime(date);
                    hp.setPredictTime(ycTime);
                    hp.setSiteId(stId);
                    hp.setPredictPower(glycsj.getPower());
                    hp.setPredictEnergy(glycsj.getEnergy());
                    hpList.add(hp);
                }
            });
            realtimePredictService.removeBatchByIds(ids);
            realtimePredictService.saveBatch(rpList);
            historyPredictService.saveBatch(hpList);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    @PostMapping("/replete/station/{type}")
    public boolean repleteStation(@PathVariable String type, @RequestBody Map<String, List<GlycSj2>> data) {
        try {
            List<RealtimePredict> rpList = new ArrayList<>();
            List<String> ids = new ArrayList<>();
            String modelId = "1";
            String predictType = type.toUpperCase();
            String deviceType = "station";
            data.forEach((stId, glycsjs) -> {
                String sstId = stId.replaceFirst("GJNY_SXGS_", "").replaceFirst("STA", "");
                for (GlycSj2 glycsj : glycsjs) {
                    DateTime ycTime = DateUtil.parseDateTime(glycsj.getTime());
                    String t = StrUtil.removeSuffix(glycsj.getTime(), ":00").replaceFirst(" ", "_").replaceFirst(":", "-");
                    RealtimePredict rp = new RealtimePredict();
                    rp.setId(predictType + "_" + modelId + "_" + sstId + t);
                    ids.add(rp.getId());
                    rp.setModelId(modelId);
                    rp.setPredictType(predictType);
                    rp.setDeviceType(deviceType);
                    rp.setTime(ycTime);
                    rp.setSiteId(stId);
                    rp.setPredictPower(glycsj.getPower());
                    rp.setPredictEnergy(glycsj.getEnergy());
                    rpList.add(rp);
                }
            });
            realtimePredictService.removeBatchByIds(ids);
            realtimePredictService.saveBatch(rpList);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    @PostMapping("/replete/station/history/cdq")
    public boolean repleteStationHistory(@RequestBody Map<String, List<GlycSj2>> data) {
        try {
            List<HistoryPredict> rpList = new ArrayList<>();
            List<HistoryPredict> scList = new ArrayList<>();
            String modelId = "1";
            String predictType = "CDQ";
            String deviceType = "station";
            data.forEach((stId, glycsjs) -> {
                DateTime dataTime = DateUtil.offsetMinute(DateUtil.parseDateTime(glycsjs.get(0).getTime()), -15);
                QueryWrapper<HistoryPredict> wrapper = new QueryWrapper<>();
                wrapper.lambda().eq(HistoryPredict::getPredictType, predictType).eq(HistoryPredict::getDeviceType, deviceType)
                        .eq(HistoryPredict::getSiteId, stId).eq(HistoryPredict::getDataTime, dataTime);
                List<HistoryPredict> list = historyPredictService.list(wrapper);
                scList.addAll(list);
                for (GlycSj2 glycsj : glycsjs) {
                    DateTime ycTime = DateUtil.parseDateTime(glycsj.getTime());
                    HistoryPredict hp = new HistoryPredict();
                    hp.setModelId(modelId);
                    hp.setPredictType(predictType);
                    hp.setDeviceType(deviceType);
                    hp.setDataTime(dataTime);
                    hp.setPredictTime(ycTime);
                    hp.setSiteId(stId);
                    hp.setPredictPower(glycsj.getPower());
                    hp.setPredictEnergy(glycsj.getEnergy());
                    rpList.add(hp);
                }
            });
            List<Integer> scIds = scList.stream().map(HistoryPredict::getId).collect(Collectors.toList());
            historyPredictService.removeBatchByIds(scIds);
            historyPredictService.saveBatch(rpList);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @PostMapping("/write/project/{type}")
    public boolean writeProject(@PathVariable String type, @RequestBody Map<String, List<GlycSj2>> data) {
        try {
            if (pj2st == null) {
                projectIds();
            }
            DateTime date = DateUtil.beginOfMinute(DateUtil.date());
            int i = Math.floorDiv(date.minute(), 15) * 15;
            date.setMinutes(i);
            List<RealtimePredict> rpList = new ArrayList<>();
            List<String> ids = new ArrayList<>();
            String modelId = "1";
            String predictType = type.toUpperCase();
            String deviceType = "project";
            data.forEach((pjId, glycsjs) -> {
                //yyyy-MM-dd HH:mm:ss
                //GJNY_SXGS_CSLF01_EG
                //2024-10-23 15:00:00
                String sstId = pjId.replaceFirst("GJNY_SXGS_", "").replaceFirst("EG", "");
                for (GlycSj2 glycsj : glycsjs) {
                    DateTime ycTime = DateUtil.parseDateTime(glycsj.getTime());
                    String t = StrUtil.removeSuffix(glycsj.getTime(), ":00").replaceFirst(" ", "_").replaceFirst(":", "-");
                    RealtimePredict rp = new RealtimePredict();
                    rp.setId(predictType + "_" + modelId + "_" + sstId + t);
                    ids.add(rp.getId());
                    rp.setModelId(modelId);
                    rp.setPredictType(predictType);
                    rp.setDeviceType(deviceType);
                    rp.setTime(ycTime);
                    rp.setSiteId(pj2st.get(pjId));
                    rp.setPeriodId(pjId);
                    rp.setPredictPower(glycsj.getEnergy() * 4);
                    rp.setPredictEnergy(glycsj.getEnergy());
                    rpList.add(rp);
                }
            });
            realtimePredictService.removeBatchByIds(ids);
            realtimePredictService.saveBatch(rpList);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    //2024-11-2 00:00:00   ---2024-11-2 00:15:00，2024-11-2 00:30:00，2024-11-2 00:45:00
    //2024-11-2 00:15:00   ---2024-11-2 00:30:00，2024-11-2 00:45:00，2024-11-2 01:00:00
    //2024-11-2 00:30:00   ---2024-11-2 00:45:00，2024-11-2 01:00:00，2024-11-2 01:15:00

    public StationInfoMin getStationinfoByMin(Date date, String stId) {
        QueryWrapper<StationInfoMin> wrapper = new QueryWrapper<>();
        wrapper.eq("record_date", date).eq("station_id", stId);
        List<StationInfoMin> list = stationInfoMinService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            StationInfoMin day = new StationInfoMin();
            day.setStationId(stId);
            day.setRecordDate(date);
            list.add(day);
        }
        return list.get(0);
    }

    public PointInfo getEntity(String uniformCode, String institutionType, String stId) {
        PointInfo pi = new PointInfo();
        pi.setUniformCode(uniformCode);
        pi.setInstitutionType(institutionType);
        pi.setStationId(stId);
        List<PointInfo> byEntity = pointInfoService.getByEntity(pi);
        return byEntity.get(0);
    }

    public void getRawDataByEntity(List<PointInfo> entity, Date start, Date end) {
        for (PointInfo info : entity) {
            List<PointData> snap = adapterApi.getHistoryRaw(goldenUri(), info.getPointKey(), start.getTime(), end.getTime());
            info.setPointDatas(snap);
        }
    }

    public void getRawDataByEntity(PointInfo entity, Date start, Date end) {
        List<PointData> snap = adapterApi.getHistoryRaw(goldenUri(), entity.getPointKey(), start.getTime(), end.getTime());
        entity.setPointDatas(snap);
    }

    public List<PointInfo> getEntitys(String uniformCode, String institutionType, String stId) {
        PointInfo pi = new PointInfo();
        pi.setUniformCode(uniformCode);
        pi.setInstitutionType(institutionType);
        pi.setStationId(stId);
        return pointInfoService.getByEntity(pi);
    }

    public void getSectionDataByEntity(PointInfo entity, Date end) {
        Map<String, PointData> section = adapterApi.getHistorySection(goldenUri(), entity.getPointKey(), end.getTime());
        section.forEach((k, v) -> {
            entity.setPointDatas(Collections.singletonList(v));
        });
    }

    public URI goldenUri() {
        return URI.create("http://172.16.12.103:8011/ts");
    }

    public void getLatestByEntity(PointInfo entity) {
        Map<String, PointData> latest = adapterApi.getLatest(goldenUri(), entity.getPointKey());
        latest.forEach((k, v) -> {
            entity.setPointDatas(Collections.singletonList(v));
        });
    }

    public void getSectionDataByEntity(List<PointInfo> entitys, Date start, Date end) {
        String collect = entitys.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> section0 = adapterApi.getHistorySection(goldenUri(), collect, start.getTime());
        Map<String, PointData> section1 = adapterApi.getHistorySection(goldenUri(), collect, end.getTime());
        for (PointInfo entity : entitys) {
            entity.setPointDatas(new ArrayList<>());
            entity.getPointDatas().add(section0.get(entity.getPointKey()));
            entity.getPointDatas().add(section1.get(entity.getPointKey()));
        }
    }

    public void getSectionDataByEntity(PointInfo entity, Date start, Date end) {
        Map<String, PointData> section0 = adapterApi.getHistorySection(goldenUri(), entity.getPointKey(), start.getTime());
        Map<String, PointData> section1 = adapterApi.getHistorySection(goldenUri(), entity.getPointKey(), end.getTime());
        entity.setPointDatas(new ArrayList<>());
        entity.getPointDatas().add(section0.get(entity.getPointKey()));
        entity.getPointDatas().add(section1.get(entity.getPointKey()));
    }

    public void getLatestByEntity(List<PointInfo> entity) {
        String collect = entity.stream().map(PointInfo::getPointKey).collect(Collectors.joining(","));
        Map<String, PointData> latest = adapterApi.getLatest(goldenUri(), collect);
        entity.forEach(e -> {
            e.setPointDatas(Collections.singletonList(latest.get(e.getPointKey())));
        });
    }
}
