package com.ruoyi.web.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
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.IHistoryPredictService;
import com.ruoyi.ucp.service.IPointInfoService;
import com.ruoyi.ucp.service.IRealtimePredictService;
import org.springframework.beans.factory.annotation.Autowired;
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
@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;

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

    @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("/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) {
        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("/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;
    }
}
