package com.pqs9200.serviceimpl.weeklyreport;

import cn.hutool.core.collection.CollectionUtil;
import com.njcn.mapper.advanced.RelevanceMapper;
import com.njcn.pojo.advanced.SagEvent;
import com.njcn.pojo.advanced.SagEventsQueryCondition;
import com.njcn.pojo.commons.AreaGeneralData;
import com.njcn.pojo.commons.RedisDB;
import com.njcn.pojo.commons.device.LineInfo;
import com.njcn.pojo.configuration.DicData;
import com.njcn.pojo.user.Depts;
import com.njcn.serviceimpl.commons.WaveServiceImpl;
import com.njcn.shiro.token.TokenManager;
import com.njcn.utils.PubUtils;
import com.njcn.utils.UserUtil;
import com.njcn.utils.redis.JedisManager;
import com.pqs9200.mapper.weeklyreport.GetAreaPointInfoMapper;
import com.pqs9200.mapper.weeklyreport.GetSagReasonMapper;
import com.pqs9200.mapper.weeklyreport.GetVoltageInfoMapper;
import com.pqs9200.pojo.weeklyreport.AreaPointInfo;
import com.pqs9200.pojo.weeklyreport.ResultReason;
import com.pqs9200.pojo.weeklyreport.SagRate;
import com.pqs9200.service.weeklyreport.WeeklyReportService;
import net.sf.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
public class WeeklyReportServiceImpl implements WeeklyReportService {
    private static final Logger logger = LoggerFactory.getLogger(WeeklyReportServiceImpl.class);
    @Autowired
    private GetAreaPointInfoMapper getAreaPointInfoMapper;
    @Autowired
    private UserUtil userUtil;
    @Autowired
    private GetVoltageInfoMapper getVoltageInfoMapper;
    @Autowired
    private RelevanceMapper relevanceMapper;
    @Autowired
    private WaveServiceImpl waveServiceImpl;
    @Autowired
    private GetSagReasonMapper getSagReasonMapper;

    @Autowired
    private JedisManager jedisManager;

    public static class Info {
        private String name;
        private Integer id;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }
    }

    @Override
    public List<AreaPointInfo> getPointData(Date start, Date end,Boolean statFlag) {
        List<AreaPointInfo> listPointInfo = new ArrayList<>();
        String area = userUtil.getDeptsIndex(TokenManager.getToken().getUserIndex());
        List<AreaGeneralData> deptdLists;
        if(statFlag){
            deptdLists = userUtil.getAreaDataByInfoRun(area);
        }else{
            deptdLists = userUtil.getAreaDataByStatFlagAll(area);
        }


        for (AreaGeneralData areaGeneralData : deptdLists) {
            AreaPointInfo areaPointInfo = new AreaPointInfo();
            areaPointInfo.setName(areaGeneralData.getName());
            List<Integer> listLineIndex = areaGeneralData.getLineIndexs(); // 获取监测点ID

            if (listLineIndex.size() > 0) {
                Integer onLineCount = getAreaPointInfoMapper.getOnline(listLineIndex); // 获取监测点在线个数
                areaPointInfo.setOnLine(onLineCount == null ? 0 : onLineCount.intValue());

                if (listLineIndex.size() > 0) {
                    Integer eventCount = getAreaPointInfoMapper.getEventCount(listLineIndex, start, end);
                    Integer breakCount = getAreaPointInfoMapper.getBreakCount(listLineIndex, start, end);
                    Integer upCount = getAreaPointInfoMapper.getUpCount(listLineIndex, start, end);
                    areaPointInfo.setOffLine(listLineIndex.size() - areaPointInfo.getOnLine());
                    areaPointInfo.setEventCount(eventCount == null ? 0 : eventCount.intValue());
                    areaPointInfo.setBreakCount(breakCount == null ? 0 : breakCount.intValue());
                    areaPointInfo.setUpCount(upCount == null ? 0 : upCount.intValue());
                } else {
                    areaPointInfo.setOffLine(0);
                    areaPointInfo.setEventCount(0);
                    areaPointInfo.setBreakCount(0);
                    areaPointInfo.setUpCount(0);
                }
            } else {
                areaPointInfo.setEventCount(0);
                areaPointInfo.setBreakCount(0);
                areaPointInfo.setUpCount(0);
                areaPointInfo.setOffLine(0);
                areaPointInfo.setOnLine(0);
            }

            listPointInfo.add(areaPointInfo);
        }

        return listPointInfo;
    }

    @Override
    public List<AreaPointInfo> getVoltageData(Date start, Date end,Boolean statFlag) {
        List<AreaPointInfo> list = new ArrayList<>();

        String area = userUtil.getDeptsIndex(TokenManager.getToken().getUserIndex());
        List<AreaGeneralData> deptdLists;
        if(statFlag){
            deptdLists = userUtil.getAreaDataByInfoRun(area);
        }else{
            deptdLists = userUtil.getAreaDataByStatFlagAll(area);
        }
        List<Integer> listLineIndex = new ArrayList<>();

        for (AreaGeneralData areaGeneralData : deptdLists) {
            listLineIndex.addAll(areaGeneralData.getLineIndexs());
        }

        List<DicData> list1 = getVoltageInfoMapper.getVoltageData();

        for (DicData dicData : list1) {
            AreaPointInfo areaPointInfo = new AreaPointInfo();
            areaPointInfo.setName(dicData.getDicName());
            //超过1000个点处理
            List<Integer> list2= new ArrayList<>();
            if(CollectionUtil.isNotEmpty(listLineIndex)){
                if(listLineIndex.size()>1000){
                    List<Integer> tmp =null;
                    int count = listLineIndex.size()/1000+1;
                    for(int i=0;i<count;i++){
                        if(listLineIndex.size()>1000){
                           List<Integer> tempLine = listLineIndex.subList(0,1000);
                            tmp = getVoltageInfoMapper.getLineIndex(dicData.getDicIndex(), tempLine);
                            tempLine.clear();
                        }else{
                            tmp = getVoltageInfoMapper.getLineIndex(dicData.getDicIndex(), listLineIndex);
                        }
                        if(CollectionUtil.isNotEmpty(tmp)){
                            list2.addAll(tmp);
                        }
                    }
                }else{
                    list2 = getVoltageInfoMapper.getLineIndex(dicData.getDicIndex(), listLineIndex);
                }
            }

            JSONArray jsonArray=JSONArray.fromObject(list2);
            jedisManager.saveValueByKey(RedisDB.SESSION_DB,"weeklyReportKey",jsonArray.toString(),RedisDB.SHORT_TIME);
            String weeklyReportKey = jedisManager.getValueByKey(RedisDB.SESSION_DB, "weeklyReportKey");
            JSONArray jsonArrayObject=JSONArray.fromObject(weeklyReportKey);
            jedisManager.deleteByKey(RedisDB.SESSION_DB, "weeklyReportKey");
            List<Integer> temps= (List<Integer>) JSONArray.toCollection(jsonArrayObject,Integer.class);
            if (list2.size() > 0) {
                Integer onLineCount = getVoltageInfoMapper.getOnLine(temps);// 获取监测点在线个数
                areaPointInfo.setOnLine(onLineCount == null ? 0 : onLineCount.intValue());
                Integer eventCount = getAreaPointInfoMapper.getEventCount(temps, start, end);
                Integer breakCount = getAreaPointInfoMapper.getBreakCount(temps, start, end);
                Integer upCount = getAreaPointInfoMapper.getUpCount(temps, start, end);
                areaPointInfo.setOffLine(list2.size() - areaPointInfo.getOnLine());
                areaPointInfo.setEventCount(eventCount == null ? 0 : eventCount.intValue());
                areaPointInfo.setBreakCount(breakCount == null ? 0 : breakCount.intValue());
                areaPointInfo.setUpCount(upCount == null ? 0 : upCount.intValue());
            } else {
                areaPointInfo.setOnLine(0);
                areaPointInfo.setOffLine(0);
                areaPointInfo.setEventCount(0);
                areaPointInfo.setBreakCount(0);
                areaPointInfo.setUpCount(0);
            }

            list.add(areaPointInfo);
        }

        return list;
    }

    public List<SagEvent> getSagEvent(Date start, Date end,Boolean statFlag) {
        String area = userUtil.getDeptsIndex(TokenManager.getToken().getUserIndex());
        List<AreaGeneralData> areaGeneral;
        if(statFlag){
            areaGeneral = userUtil.getAreaDataByInfoRun(area);
        }else{
            areaGeneral = userUtil.getAreaDataByStatFlagAll(area);
        }
        List<SagEvent> list = new ArrayList<>();
        List<Integer> ll = new ArrayList<>();

        for (AreaGeneralData depts : areaGeneral) {
            List<Integer> listLineIndex = depts.getLineIndexs(); // 获取监测点ID
            ll.addAll(listLineIndex);
        }

        HashSet<Integer> hashSet = new HashSet<>(ll);

        for (Integer integer : hashSet) {
            SagEventsQueryCondition sagEventsQueryCondition = new SagEventsQueryCondition(start, end, integer);
            list.addAll(relevanceMapper.querySagEvents(sagEventsQueryCondition));
        }

        for (SagEvent sagEvent : list) {
            try {
                sagEvent.setStrTime(PubUtils.date2String(sagEvent.getSagTime(), "yyyy-MM-dd HH:mm:ss") + "."
                        + PubUtils.getMs(sagEvent.getMsec()));
                sagEvent.setStrEventValue(String.format("%.2f", sagEvent.getEventValue() * 100));
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
        return list;
    }

    @Override
    public List<SagEvent> getSagData(Date start, Date end,Boolean statFlag) {
        List<SagEvent> list;
        list = getSagEvent(start, end,statFlag);
        Iterator iterator = list.iterator();

        for (; iterator.hasNext(); ) { //只考虑暂降事件
            SagEvent sagEvent = (SagEvent) iterator.next();

            if (sagEvent.getWaveType().intValue() != 1) {
                iterator.remove();
            }
        }

        // 根据暂降严重度重新排序，保留前五条数据，这里的记录数需不需要做配置?
        for (SagEvent sagEvent : list) {
            if (sagEvent.getSeverity() == null) {
                String value = waveServiceImpl.getYzd(sagEvent.getPersistTime(), sagEvent.getEventValue());
                sagEvent.setSeverity(Float.parseFloat(value));
            }

            sagEvent.setSortType(1); // 设置排序规则
        }

        // 排序，根据暂降严重度排序
        Collections.sort(list);

        if (list.size() > 20) {
            List<SagEvent> listnew = new ArrayList<>();
            listnew.addAll(list.subList(0, 20));
            return listnew;
        }

        return list;
    }

    @Override
    public List<SagRate> getSagReasonData(Date start, Date end,Boolean statFlag) {
        List<ResultReason> list = getSagReasonMapper.getReasonName();
        List<SagRate> listResult = new ArrayList<>();
        List<Integer> listLineId = new ArrayList<>();

        String area = userUtil.getDeptsIndex(TokenManager.getToken().getUserIndex());

        List<AreaGeneralData> deptdLists;
        if(statFlag){
            deptdLists = userUtil.getAreaDataByInfoRun(area);
        }else{
            deptdLists = userUtil.getAreaDataByStatFlagAll(area);
        }

        for (AreaGeneralData areaGeneralData : deptdLists) {
            if (!areaGeneralData.getLineIndexs().isEmpty()) {
                listLineId.addAll(areaGeneralData.getLineIndexs());
            }
        }

        if (listLineId.isEmpty()) {
            return null;
        }

        // 获取事件类型总数
        List<ResultReason> listTotal= new ArrayList<>();
        if(listLineId.size()>1000){
           int count = listLineId.size()/1000+1;
           for(int i=0;i<count;i++){
               List<ResultReason> temp = null;
               if(listLineId.size()>1000){
                   List<Integer> temLine = listLineId.subList(0,1000);
                   temp = getSagReasonMapper.getTotal(start, end, temLine);
                   temLine.clear();
               }else{
                   temp = getSagReasonMapper.getTotal(start, end, listLineId);
               }
               if(CollectionUtil.isNotEmpty(temp)){
                   listTotal.addAll(temp);
               }
           }
        }else{
            listTotal  = getSagReasonMapper.getTotal(start, end, listLineId);
        }


        int total = listTotal.size() > 0 ? 0 : 1;

        for (ResultReason resultReason : listTotal) {
            total += resultReason.getTotal().intValue();
        }

        for (ResultReason resultReason : list) {
            SagRate sagRate = new SagRate();
            sagRate.setName(resultReason.getName());
            sagRate.setCount(new Integer(0));

            for (ResultReason resultReason1 : listTotal) {
                if (resultReason.getDicindex().equals(resultReason1.getEventreason())) {
                    sagRate.setCount(resultReason1.getTotal());
                    break;
                }
            }

            sagRate.setRate(new Float((float) sagRate.getCount().intValue() / total * 100));
            listResult.add(sagRate);
        }

        return listResult;
    }

    @Override
    public List<SagEvent> getSagEvents(Date start, Date end,Boolean statFlag) {
        List<SagEvent> list = getSagEvent(start, end,statFlag);

        for (SagEvent sagEvent : list) {
            if (sagEvent.getWaveType() != 1) {
                sagEvent.setSagReason("/");
            }

            sagEvent.setTime(sagEvent.getSagTime().getTime() + sagEvent.getMsec());
            sagEvent.setSortType(2); // 设置排序规则
        }

        // 排序，根据暂降发生时间排序
        Collections.sort(list);

        return list;
    }

    @Override
    public List<LineInfo> getTenList(Date start, Date end, Integer wavetype,Boolean statFlag){
    	List<LineInfo> result = new ArrayList<>();
        String area = userUtil.getDeptsIndex(TokenManager.getToken().getUserIndex());

        List<AreaGeneralData> deptdLists;
        if(statFlag){
            deptdLists = userUtil.getAreaDataByInfoRun(area);
        }else{
            deptdLists = userUtil.getAreaDataByStatFlagAll(area);
        }

        List<Integer> lineList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(deptdLists)){
            for(AreaGeneralData areaGeneralData:deptdLists){
                if(CollectionUtil.isNotEmpty(areaGeneralData.getLineIndexs())){
                    lineList.addAll(areaGeneralData.getLineIndexs());
                }
            }
        }

        if(CollectionUtil.isNotEmpty(lineList)){

           if(lineList.size()>1000){
               int count = lineList.size()/1000+1;
               for(int i=0;i<count;i++){
                   List<LineInfo> resList = null;
                   if(lineList.size()>1000){
                       List<Integer> subIndexs = lineList.subList(0,1000);
                       resList  = getAreaPointInfoMapper.getTenList(start, end, wavetype,subIndexs);
                       subIndexs.clear();
                   }else{
                       resList =getAreaPointInfoMapper.getTenList(start, end, wavetype,lineList);
                   }
                   if(CollectionUtil.isNotEmpty(resList)){
                       result.addAll(resList);
                   }
               }
           }else {
               result = getAreaPointInfoMapper.getTenList(start, end, wavetype,lineList);
           }
        }

    	return result;
    }
}
