package com.jiayue.ipp.idp.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiayue.ipp.common.data.entity.WindTowerStatusData;
import com.jiayue.ipp.common.data.entity.an.ParsingCftInfo;
import com.jiayue.ipp.idp.mapper.WindTowerStatusDataMapper;
import com.jiayue.ipp.idp.mapper.an.ParsingCftInfoMapper;
import com.jiayue.ipp.idp.service.WindTowerStatusDataService;
import com.jiayue.ipp.idp.service.an.ParsingCftInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 测风塔数据业务层实现类
 *
 * @author tl
 * @date 2022-05-11 18:07:03
 */
@Service
public class WindTowerStatusDataServiceImpl extends ServiceImpl<WindTowerStatusDataMapper, WindTowerStatusData> implements WindTowerStatusDataService {
//    private final TunnelGatherDataPointService tunnelGatherDataPointService;

//    private final EquipmentAttributeService equipmentAttributeService;
    @Autowired
    ParsingCftInfoMapper parsingCftInfoMapper;


    @Override
    public List<WindTowerStatusData> getByStationCodeBetweenTimeAndEquipmentId(String stationCode, Date startTime, Date endTime, String equipmentId) {
        QueryWrapper<WindTowerStatusData> wrapper = new QueryWrapper<>();
        if (stationCode != null && !stationCode.equals("")) {
            wrapper.eq("station_code", stationCode);
        }
        if (startTime != null && !startTime.equals("") && endTime != null && !endTime.equals("")) {
            wrapper.between("time", startTime, endTime);
        }
        if (equipmentId != null && !equipmentId.equals("")) {
            wrapper.eq("equipment_id", equipmentId);
        }

        return baseMapper.selectList(wrapper);
    }

    @Override
    public QueryWrapper<WindTowerStatusData> getByBetweenTimeAndEquipmentIdAndStationCode(Date startTime, Date endTime, String equipmentId, String stationCode) {
        QueryWrapper<WindTowerStatusData> wrapper = new QueryWrapper<>();
        if (stationCode != null && !stationCode.equals("")) {
            wrapper.eq("station_code", stationCode);
        }
        if (startTime != null && !startTime.equals("") && endTime != null && !endTime.equals("")) {
            wrapper.between("time", startTime, endTime);
        }
        if (equipmentId != null && !equipmentId.equals("")) {
            wrapper.eq("equipment_id", equipmentId);
        }

        return wrapper;
    }

    public Map<String, Object> queryCharts(String stationCode, Date startTime, Date endTime, String equipmentId) throws Exception {
        Map<String, Object> map = new HashMap<>();
        //所有数据
        List<WindTowerStatusData> windTowerStatusDataList = getByStationCodeBetweenTimeAndEquipmentId(stationCode, startTime, endTime, equipmentId);
        Collections.sort(windTowerStatusDataList, Comparator.comparing(WindTowerStatusData::getTime));
        //根据设备id查询该设备下的所有接入点位
        //TODO 没接入通道了 得重写
//        List<TunnelGatherDataPoint> tunnelGatherDataPointList = tunnelGatherDataPointService.getByEquipmentId(equipmentId);
//        List<String> thList = this.getTableHead(stationCode, tunnelGatherDataPointList);
        //List<String> wsList = thList.stream().filter(t -> t.contains("wsInst")).collect(Collectors.toList());
        //List<String> wdList = thList.stream().filter(t -> t.contains("wdInst")).collect(Collectors.toList());
        List<ParsingCftInfo> list = parsingCftInfoMapper.selectList(null);
        //根据场站编号过滤
        List<ParsingCftInfo> parsingCftInfoList = list.stream().filter(p -> p.getStationCode().contains(stationCode)).collect(Collectors.toList());
        //风速
        Map<String, List<BigDecimal>> wsMap = new LinkedHashMap<>();
        //风向
        Map<String, List<BigDecimal>> wdMap = new LinkedHashMap();
        if (!parsingCftInfoList.isEmpty()) {
            //据唐乐说 不会出现一个场站配置两个测风塔解析的情况
            ParsingCftInfo parsingCftInfo = parsingCftInfoList.get(0);
            Field[] field = parsingCftInfo.getClass().getDeclaredFields();
            for (Field f : field) {
                //如果是private 不设置为true读取不到
                f.setAccessible(true);
                Map jsonMap = JSON.parseObject(JSON.toJSONString(parsingCftInfo), Map.class);
                if (f.getName().contains("wsInst")) {
                    if (!jsonMap.get(f.getName()).equals("")) {
                        wsMap.put(f.getName(), new ArrayList<>());
                    }
                } else if (f.getName().contains("wdInst")) {
                    if (!jsonMap.get(f.getName()).equals("")) {
                        wdMap.put(f.getName(), new ArrayList<>());
                    }
                }
            }
        }
        List<String> times = new ArrayList<>();
        Long startTimes = startTime.getTime();
        Long endTimes = endTime.getTime();
        Long amendStartTime = startTimes;
        Long timeStep = 300000L;
        if (startTimes % timeStep != 0) {
            amendStartTime = startTimes - (startTimes % timeStep) + timeStep;
        }

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (long i = amendStartTime; i < endTimes; i = i + 1000 * 60 * 5L) {
            long filterI = i;
            times.add(formatter.format(new Date(i)));
            List<WindTowerStatusData> filterList = windTowerStatusDataList.stream().filter(t -> t.getTime().getTime()==filterI).collect(Collectors.toList());
            if (!filterList.isEmpty()) {
                WindTowerStatusData w = filterList.get(0);
                Class c = w.getClass();
                Field f;
                for (String wsKey : wsMap.keySet()) {
                    f = c.getDeclaredField(wsKey);
                    f.setAccessible(true);
                    if (new BigDecimal(-99).compareTo((BigDecimal) f.get(w)) == 0) {
                        wsMap.get(wsKey).add(null);
                    } else {
                        wsMap.get(wsKey).add((BigDecimal) f.get(w));
                    }
                }
                for (String wdKey : wdMap.keySet()) {
                    f = c.getDeclaredField(wdKey);
                    f.setAccessible(true);
                    if (new BigDecimal(-99).compareTo((BigDecimal) f.get(w)) == 0) {
                        wdMap.get(wdKey).add(null);
                    } else {
                        wdMap.get(wdKey).add((BigDecimal) f.get(w));
                    }
                }
            } else {
                for (String wsKey : wsMap.keySet()) {
                    wsMap.get(wsKey).add(null);
                }
                for (String wsKey : wdMap.keySet()) {
                    wdMap.get(wsKey).add(null);
                }
            }
        }
        Map<String, Object> wdFrequencyMap = new LinkedHashMap<>();
        for (String wdMapKey : wdMap.keySet()) {
            int[] frequency16 = new int[16];
            Float[] frequency16Rate = new Float[16];
            for (BigDecimal b : wdMap.get(wdMapKey)) {
                if (b != null) {
                    float wdfloat = b.floatValue();
                    //N 北 0 348.76-11.25
                    if ((wdfloat >= 348.76F && wdfloat <= 360F) || (wdfloat >= 0 && wdfloat <= 11.25)) {
                        frequency16[0]++;
                    }
                    //NNE 北东北 22.5 11.26-33.75
                    if (wdfloat >= 11.26F && wdfloat <= 33.75F) {
                        frequency16[15]++;
                    }
                    //NE 东北 45 33.76-56.25
                    if (wdfloat >= 33.76F && wdfloat <= 56.25F) {
                        frequency16[14]++;
                    }
                    //ENE 东东北 67.5 56.26-78.75
                    if (wdfloat >= 56.26F && wdfloat <= 78.75F) {
                        frequency16[13]++;
                    }
                    //E 东 90 78.76-101.25
                    if (wdfloat >= 78.76F && wdfloat <= 101.25F) {
                        frequency16[12]++;
                    }
                    //ESE 东东南 112.5 101.26-123.75
                    if (wdfloat >= 101.26F && wdfloat <= 123.75F) {
                        frequency16[11]++;
                    }
                    //SE 东南 135 123.76-146.25
                    if (wdfloat >= 123.76F && wdfloat <= 146.25F) {
                        frequency16[10]++;
                    }
                    //SSE 南东南 157.5 146.26-168.75
                    if (wdfloat >= 146.26F && wdfloat <= 168.75F) {
                        frequency16[9]++;
                    }
                    //S 南 180 168.76-191.25
                    if (wdfloat >= 168.76F && wdfloat <= 191.25F) {
                        frequency16[8]++;
                    }
                    //SSW 南西南 202.5 191.26-213.75
                    if (wdfloat >= 191.26F && wdfloat <= 213.75F) {
                        frequency16[7]++;
                    }
                    //SW 西南  225 213.76-236.25
                    if (wdfloat >= 213.76F && wdfloat <= 236.25F) {
                        frequency16[6]++;
                    }
                    //WSW 西西南 247.5 236.26-258.75
                    if (wdfloat >= 236.26F && wdfloat <= 258.75F) {
                        frequency16[5]++;
                    }
                    //W 西 270 258.76-281.25
                    if (wdfloat >= 258.76F && wdfloat <= 281.25F) {
                        frequency16[4]++;
                    }
                    //WNW 西西北 295.5 281.26-303.75
                    if (wdfloat >= 281.26F && wdfloat <= 303.75F) {
                        frequency16[3]++;
                    }
                    //NW 西北 315 303.76-326.25
                    if (wdfloat >= 303.76F && wdfloat <= 326.25F) {
                        frequency16[2]++;
                    }
                    //NNW 北西北 337.5 326.26-348.
                    if (wdfloat >= 326.26F && wdfloat <= 348.75F) {
                        frequency16[1]++;
                    }
                }
            }

            if (wdMapKey.equals("wdInst50") || wdMapKey.equals("wdInst70")) {
                String[] d = {"北", "北西北", "西北", "西西北", "西", "西西南", "西南", "南西南", "南", "南东南", "东南", "东东南", "东", "东北北", "东北", "北东北"};
                int result = 0;
                String dr = "无";
                for (int i = 0; i < d.length; i++) {
                    if (frequency16[i] > result) {
                        result = frequency16[i];
                        dr = d[i];
                    }
                }
                map.put(wdMapKey, dr);
            }


            BigDecimal sumToltal = new BigDecimal(0);
            for (int wdf : frequency16) {
                BigDecimal b = new BigDecimal(wdf);
                sumToltal = sumToltal.add(b);
            }

            for (int i = 0; i < frequency16.length; i++) {
                if (frequency16[i] == 0) {
                    frequency16Rate[i] = 0f;
                } else {
                    BigDecimal dividend = new BigDecimal(frequency16[i]);
                    frequency16Rate[i] = dividend.divide(sumToltal, 2, BigDecimal.ROUND_HALF_UP).floatValue();
                }
            }
            wdFrequencyMap.put(wdMapKey, frequency16Rate);
        }

        Map<String, Object> wsFrequencyMap = new LinkedHashMap<>();

        for (String wsMapKey : wsMap.keySet()) {
            int[] wsFrequency = new int[10];
            float[] wsFrequencyRate = new float[16];
            for (BigDecimal b : wsMap.get(wsMapKey)) {

                if (b != null) {
                    float wsfloat = b.floatValue();
                    //0-3米风速
                    if (wsfloat >= 0 && wsfloat <= 3) {
                        wsFrequency[0]++;
                    }
                    //3-6米风速
                    if (wsfloat > 3 && wsfloat <= 6) {
                        wsFrequency[1]++;
                    }
                    //6-9米风速
                    if (wsfloat > 6 && wsfloat <= 9) {
                        wsFrequency[2]++;
                    }
                    //9-12米风速
                    if (wsfloat > 9 && wsfloat <= 12) {
                        wsFrequency[3]++;
                    }
                    //12-15米风速
                    if (wsfloat > 12 && wsfloat <= 15) {
                        wsFrequency[4]++;
                    }
                    //15-18米风速
                    if (wsfloat > 15 && wsfloat <= 18) {
                        wsFrequency[5]++;
                    }
                    //18-21米风速
                    if (wsfloat > 18 && wsfloat <= 21) {
                        wsFrequency[6]++;
                    }
                    //21-24米风速
                    if (wsfloat > 21 && wsfloat <= 24) {
                        wsFrequency[7]++;
                    }
                    //24-27米风速
                    if (wsfloat > 24 && wsfloat <= 27) {
                        wsFrequency[8]++;
                    }
                    //27米以上风速
                    if (wsfloat > 27) {
                        wsFrequency[9]++;
                    }
                }
            }

            BigDecimal sumToltal = new BigDecimal(0);

            for (int wdf : wsFrequency) {
                BigDecimal b = new BigDecimal(wdf);
                sumToltal = sumToltal.add(b);
            }

            for (int i = 0; i < wsFrequency.length; i++) {
                if (wsFrequency[i] == 0) {
                    wsFrequencyRate[i] = 0f;
                } else {
                    BigDecimal dividend = new BigDecimal(wsFrequency[i]);
                    wsFrequencyRate[i] = dividend.divide(sumToltal, 2, BigDecimal.ROUND_HALF_UP).floatValue();
                }
            }

            wsFrequencyMap.put(wsMapKey, wsFrequencyRate);
        }



        Map<String, String> typemap = new HashMap<>();
        typemap.put("wsInst10", "10风速瞬时值");
        typemap.put("wsInst30", "30风速瞬时值");
        typemap.put("wsInst50", "50风速瞬时值");
        typemap.put("wsInst70", "70风速瞬时值");


        map.put("equipmentType", typemap);
        map.put("ws", wsMap);
        map.put("wd", wdFrequencyMap);
        map.put("wf", wsFrequencyMap);
        map.put("times", times);
//        map.put("tableHead", getTableHeader(tunnelGatherDataPointList));

//        List<Map<String, String>> mapList = new ArrayList<>();
//        Map<String, String> ws10heads = new HashMap<>();
//        ws10heads.put("prop", "wsInst10");
//        ws10heads.put("label", "10风速瞬时值");
//        mapList.add(ws10heads);
//        Map<String, String> ws30heads = new HashMap<>();
//        ws30heads.put("prop", "wsInst30");
//        ws30heads.put("label", "30风速瞬时值");
//        mapList.add(ws30heads);

        map.put("tableHead", "");
        map.put("list", windTowerStatusDataList);
        return map;
    }

//    public List<String> getTableHead(String stationCode, List<TunnelGatherDataPoint> tunnelGatherDataPointList) {
//        List<String> allAttributeName = new ArrayList<>();
//        List<EquipmentAttribute> byEquipmentType = equipmentAttributeService.getByEquipmentType("WINDTOWER");
//        for (EquipmentAttribute equipmentAttribute : byEquipmentType) {
//            allAttributeName.add(equipmentAttribute.getFieldName());
//        }
//        List<String> heads = new ArrayList<>();
//        for (TunnelGatherDataPoint t : tunnelGatherDataPointList) {
//            EquipmentAttribute equipmentAttribute = equipmentAttributeService.getById(t.getEquipmentAttributeId());
//            String ponitName = equipmentAttribute.getFieldName();
//            if (ponitName != null) {
//                for (String an : allAttributeName) {
//                    if (an.equals(ponitName)) {
//                        heads.add(an);
//                    }
//                }
//            }
//        }
//        return heads;
//    }

    /**
     * 表格表头
     *
     * @param tunnelGatherDataPointList 点表
     * @return
     */
//    public List<Map<String, String>> getTableHeader(List<TunnelGatherDataPoint> tunnelGatherDataPointList) {
//        List<String> allAttributeName = new ArrayList<>();
//        List<EquipmentAttribute> byEquipmentType = equipmentAttributeService.getByEquipmentType("WINDTOWER");
//        for (EquipmentAttribute equipmentAttribute : byEquipmentType) {
//            allAttributeName.add(equipmentAttribute.getFieldName());
//        }
//        List<Map<String, String>> mapList = new ArrayList<>();
//        for (TunnelGatherDataPoint t : tunnelGatherDataPointList) {
//            EquipmentAttribute equipmentAttribute = equipmentAttributeService.getById(t.getEquipmentAttributeId());
//            String ponitName = equipmentAttribute.getFieldName();
//            if (ponitName != null) {
//                for (String an : allAttributeName) {
//                    if (an.equals(ponitName)) {
//                        Map<String, String> heads = new HashMap<>();
//                        heads.put("prop", an);
//                        heads.put("label", equipmentAttribute.getSignificance());
//                        mapList.add(heads);
//                    }
//                }
//
//            }
//        }
//        return mapList;
//    }

}
