package com.ruoyi;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.text.csv.CsvWriter;
import cn.hutool.core.thread.ExecutorBuilder;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.CharsetUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.ucp.entity.*;
import com.ruoyi.ucp.feign.AdapterApi;
import com.ruoyi.ucp.service.IPointInfoService;
import com.ruoyi.ucp.service.IProjectInfoMin2Service;
import com.ruoyi.ucp.service.IStationInfoMin2Service;
import com.ruoyi.ucp.service.IStationInfoMinService;
import com.ruoyi.web.controller.JavaFunctionJobHandler;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.net.URI;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;

@SpringBootTest
@RunWith(SpringRunner.class)
public class GetDataTest {

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

    @Test
    public void test2() {
//        DateTime begin = DateUtil.parse("2023-03-21");
        DateTime begin = DateUtil.parse("2024-11-08 17:30:00");
//        DateTime begin = DateUtil.parse("2024-08-19 11:00:00");
//        DateTime end = DateUtil.parse("2024-08-08 14:00:00");
        DateTime end = DateUtil.parse("2024-11-09 11:21:00");
//        DateTime end = DateUtil.parse("2024-08-19 11:30:00");
//        DateTime end = DateUtil.parse("2024-08-08 13:45:00");
        //LJS,FSG,JSL,ZZ,XZ,CSL
        int i = 1;
        DateTime minBegin = begin, minEnd = DateUtil.offsetMinute(begin, 15);
        while (minEnd.isBefore(end)) {
            minEnd = DateUtil.offsetMinute(begin, i * 15);
//            task.calcStationSjglAgcPjfsHjwdDlMin(minBegin, minEnd, "GJNY_SXGS_CSL_FDC_STA");
//            task.calcTurbinePjfsPjglKyglLlglMin(minEnd, 15);
            task.calcStationSjglAgcPjfsHjwdDlMin(minEnd);
            System.out.println(minBegin.toString() + "," + minEnd.toString());
            i++;
            minBegin = minEnd;
        }
    }
    @Test
    public void test9() {
        DateTime begin = DateUtil.parse("2023-04-18");
//        DateTime begin = DateUtil.parse("2023-04-22 14:30:00");
        DateTime end = DateUtil.parse("2024-11-07");
        String stId = "GJNY_SXGS_XZ_FDC_STA";
        QueryWrapper<StationInfoMin> wrapper=new QueryWrapper<>();
        wrapper.lambda().eq(StationInfoMin::getStationId,stId).between(StationInfoMin::getRecordDate,begin,end);
        List<StationInfoMin> list = stationInfoMinService.list(wrapper);
        Map<String, StationInfoMin> collect = list.stream().collect(Collectors.toMap(im -> DateUtil.date(im.getRecordDate()).toString(), Function.identity()));
        //LJS,FSG,JSL,ZZ,XZ,CSL
        int i = 1;
        DateTime minBegin = begin, minEnd = DateUtil.offsetMinute(begin, 15);
        while (minEnd.isBefore(end)) {
            minEnd = DateUtil.offsetMinute(begin, i * 15);
            task.calcStationPjfsHjwdMin(minBegin, minEnd, stId,collect.get(DateUtil.date(minEnd).toString()));
            System.out.println(minBegin.toString() + "," + minEnd.toString());
            i++;
            minBegin = minEnd;
        }
    }
    @Test
    public void test10() {
        DateTime begin = DateUtil.parse("2023-04-18");
//        DateTime begin = DateUtil.parse("2023-05-24 21:15:00");
        DateTime end = DateUtil.parse("2024-11-07");
//        DateTime end = DateUtil.parse("2023-04-19");
        String stId = "GJNY_SXGS_CSL_FDC_STA";
        QueryWrapper<StationInfoMin2> wrapper=new QueryWrapper<>();
        wrapper.lambda().eq(StationInfoMin2::getStationId,stId).between(StationInfoMin2::getRecordDate,begin,end);
        List<StationInfoMin2> list = stationInfoMin2Service.list(wrapper);
        Map<String, StationInfoMin2> collect = list.stream().collect(Collectors.toMap(im -> DateUtil.date(im.getRecordDate()).toString(), Function.identity()));
        //LJS,FSG,JSL,ZZ,XZ,CSL
        int i = 1;
        DateTime minBegin = begin, minEnd = DateUtil.offsetMinute(begin, 15);
        while (minEnd.isBefore(end)) {
            minEnd = DateUtil.offsetMinute(begin, i * 15);
            task.calcProjectPjfsHjwdMin2(minBegin, minEnd, stId,collect.get(DateUtil.date(minEnd).toString()));
            System.out.println(minBegin.toString() + "," + minEnd.toString());
            i++;
            minBegin = minEnd;
        }
    }
    @Test
    public void test5() {
        task.getPoint();
    }
    @Test
    public void test6() {
        DateTime begin = DateUtil.parse("2023-04-18");
        DateTime end = DateUtil.parse("2024-11-03");
        //LJS,FSG,JSL
        int i = 1;
        DateTime minBegin = begin, minEnd = DateUtil.offsetMinute(begin, 15);
        while (minEnd.isBefore(end)) {
            minEnd = DateUtil.offsetMinute(begin, i * 15);
//            task.calcStationMinZtts(minEnd, "GJNY_SXGS_JSL_FDC_STA");
            System.out.println(minBegin.toString() + "," + minEnd.toString());
            i++;
            minBegin = minEnd;
        }
    }
    @Test
    public void test3() {
//        DateTime start = DateUtil.parse("2024-11-06");
//        DateTime end = DateUtil.parse("2024-11-06");
//        DateRange range = DateUtil.range(start, end, DateField.DAY_OF_YEAR);
//        for (DateTime date : range) {
//            task.calcPredictExamin(date);
//        }
        DateTime date = DateUtil.date();
        task.calcPredictExamin2(date);
    }

    @Test
    public void test() {
        DateTime start = DateUtil.parse("2023-03-20");
        DateTime end = DateUtil.parse("2024-10-16");
        //        DateTime start = DateUtil.offsetMonth(end, -30);
        //        String[] names = {"AI004", "AI005", "AI006", "AI007", "AI008", "AI009", "AI073", "AI037", "AI039", "AI038", "AI047", "AI048", "AI056", "AI057", "AI060", "DI022", "AI066", "AI067", "AI069", "AI072", "AI074", "DI025", "DI080", "AI082", "AI084", "AI083", "AI065","AI114"};
        String[] names = {"AI114", "AI066", "AI060", "AI067", "AI082", "AI073", "AI004", "AI047", "AI072", "AI074"};
        //        String[] names = {"AI067"};
        QueryWrapper<PointInfo> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PointInfo::getInstitutionType, "turbine")
                //                .eq(PointInfo::getTurbineId, "GJNY_SXGS_LJS_F_WT_0011_EQ")
                .in(PointInfo::getUniformCode, names);
        List<PointInfo> list = pointInfoService.list(wrapper);
        //        String a = "GJNY_SXGS_ZZ_F_WT_0005_EQGJNY_SXGS_ZZ_F_WT_0028_EQGJNY_SXGS_ZZ_F_WT_0022_EQGJNY_SXGS_ZZ_F_WT_0045_EQGJNY_SXGS_ZZ_F_WT_0038_EQGJNY_SXGS_ZZ_F_WT_0035_EQGJNY_SXGS_ZZ_F_WT_0050_EQGJNY_SXGS_ZZ_F_WT_0019_EQGJNY_SXGS_ZZ_F_WT_0012_EQGJNY_SXGS_ZZ_F_WT_0002_EQGJNY_SXGS_ZZ_F_WT_0031_EQ";
        //        String a = "GJNY_SXGS_FSG_FDC_STA";
        String a = "GJNY_SXGS_FSG_F_WT_0022_EQ\n" +
                "GJNY_SXGS_FSG_F_WT_0064_EQ\n";
        //        list=list.stream().filter(pi->a.equals(pi.getStationId())).collect(Collectors.toList());
        list = list.stream().filter(pi -> a.contains(pi.getTurbineId())).collect(Collectors.toList());
        //        list = list.stream().filter(pi -> "GJNY_SXGS_LJS_F_WT_0007_EQ".equals(pi.getTurbineId())).collect(Collectors.toList());
        Map<String, Map<String, List<PointInfo>>> collect = list.stream().collect(Collectors.groupingBy(PointInfo::getStationId, Collectors.groupingBy(PointInfo::getTurbineId)));

        ExecutorService executor = ExecutorBuilder.create()
                .setCorePoolSize(3)
                .setMaxPoolSize(3)
                .build();
        Vector<Future<String>> fts = new Vector<>();
        Vector<Future<String>> ftfs = new Vector<>();
        collect.forEach((stId, tbPiMap) -> {
            tbPiMap.forEach((tbId, Pis) -> {
                Future<String> future = executor.submit(() -> {
                    List<PointData> zt = task.calcTurbineSimpleZt(start, end, 60 * 5, tbId);
                    Map<String, GlycSj> map = new TreeMap<>();
                    for (PointInfo info : Pis) {
                        try {
                            long j = start.getTime();
                            List<PointData> s = adapterApi.getHistorySnap(URI.create("http://172.16.12.103:8017/ts"), info.getPointKey(),
                                    j, end.getTime(), 60 * 5);
                            String dt = null;
                            GlycSj glycSj = null;
                            //AI066	风速，AI060	发电机转速，AI065	风机状态点，AI067	风向，AI082	桨叶1角度，AI073	机舱方向/对风角度
                            //AI004	U1绕组温度，AI047	电机温度2，AI072	环境温度，AI074	机舱温度
                            if (s == null || s.isEmpty()) {
                                System.out.println(tbId + "," + info.getUniformCode());
                            }
                            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(zt.get(i)==null?0L:zt.get(i).getTs())));
                                        j += 60 * 1000 * 5;//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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    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 += 60 * 1000 * 5;
                                    }
                                    break;
                            }
                            map.forEach((k, v) -> {
                                v.setTime(k);
                            });
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    Future<String> b = ThreadUtil.execAsync(() -> {
                        writerData(map.values(), stId, tbId);
                        return "ok";
                    });
                    ftfs.add(b);
                    return "ok";
                });
                fts.add(future);
            });
        });
        for (Future<String> ft : fts) {
            try {
                ft.get();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        for (Future<String> ft : ftfs) {
            try {
                ft.get();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
        //按行写出
        //        writer.write(new String[]{"时间", "时间戳", "对齐时间戳", "值"});
        /*writer.write(new String[]{"时间", "时间戳", "对齐时间戳", "值"});
        for (PointInfo pi : list) {
            if (pi.getPointKey().equals("INITIAL")) {
                //指定路径和编码
                writer = CsvUtil.getWriter("D:/数据/" + pi.getTurbineId() + "/" + pi.getName() + "无测点" +
                        ".csv", CharsetUtil.CHARSET_GBK);
                continue;
            }
            List<PointData> s = null;
            try {
                s = adapterApi.getHistorySnap(URI.create("http://172.16.12.103:8011/ts"), pi.getPointKey(),
                        start.getTime(), end.getTime(), 60*5);
            } catch (Exception e) {
                e.printStackTrace();
                //指定路径和编码
                writer = CsvUtil.getWriter("D:/数据/" + pi.getTurbineId() + "/" + pi.getName() + "获取数据出错" +
                        ".csv", CharsetUtil.CHARSET_GBK);
                continue;
            }
            //指定路径和编码
            writer = CsvUtil.getWriter("D:/数据/" + pi.getTurbineId() + "/" + pi.getName() +
                    ".csv", CharsetUtil.CHARSET_GBK);
            long j = start.getTime();
            for (int i = 0; i < s.size(); i++) {
                String[] r = new String[4];
                r[0] = DateUtil.formatDateTime(new Date(j));
                r[1] = Long.toString(s.get(i).getTs());
                r[2] = Long.toString(j);
                r[3] = Double.toString(s.get(i).getValue());
                writer.write(r);
                j += 60 * 1000 * 5;
            }
        }*/
    }

    //    @Async
    void writerData(Collection<GlycSj> values, String stId, String tbId) {
        CsvWriter writer = CsvUtil.getWriter("D:/数据/" + stId + "/" + tbId + ".csv", CharsetUtil.CHARSET_UTF_8);
        writer.writeBeans(values);
        writer.flush();
    }
}
