package com.gyee.alarm.service;


import com.gyee.alarm.controller.feigns.IAlarmService;
import com.gyee.alarm.model.vo.AlarmSimpleVo;
import com.gyee.alarm.model.vo.AlarmSuperTalbeType;
import com.gyee.alarm.model.vo.AlarmTag;
import com.gyee.alarm.model.vo.AlarmTypeValue;
import com.gyee.alarm.service.auto.IAlarmTsService;
import com.gyee.alarm.task.thread.AlarmThread;
import com.gyee.alarm.util.StringUtils;
import com.gyee.alarm.util.realtimesource.IEdosUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;


@Service
@Slf4j
public class AlarmScannerAsyncService {

    @Value("${task-count}")
    private Integer taskCount;

    @Value("${interval}")
    private Integer interval;

    @Value("${alarmType}")
    private String alarmType;
    @Value("${read-rows}")
    private Integer readRows;
    @Resource
    private IEdosUtil edosUtil;
    @Resource
    private IAlarmService alarmService;
    @Resource
    private  IAlarmTsService alarmTsService;
    private List<AlarmTag>  alarmTags=new CopyOnWriteArrayList<>();

    private List<AlarmTag>  alarmInTags=new CopyOnWriteArrayList<>();
    @Resource
    private AsyncService asyncService;
    @Value("${runWindpowerstation}")
    private String runWindpowerstation;


    private Map<String, Integer> historymap;
    /**
     * 初始化
     */
    public void init() {
//#WT("wt_alarms", "设备报警超级表"),
//#BT("bt_alarms", "升压站报警超级表"),
//#IN("in_alarms", "逆变器报警超级表"),
        switch (alarmType){
            case "wt_alarms":
                alarmTags =alarmService.findTagsByWt(runWindpowerstation);
                history(alarmTags);
                break;
            case "bt_alarms":
                List<AlarmTag>  templs =alarmService.findTagsByBt();

                if(!templs.isEmpty())
                {
                    for(AlarmTag tag:templs)
                    {
                        if(StringUtils.notEmp(tag.getTagId()) )
                        {
                            if(tag.getTagId().startsWith("GF"))
                            {
//                                tag.setVal(-10000.0);
//                                tag.setOval(-10000.0);
                                alarmInTags.add(tag);
                            }else
                            {
                                alarmTags.add(tag);
                            }
                        }
                    }
                }
                history(templs);
                break;
            case "in_alarms":
                alarmTags =alarmService.findTagsByIn();
                history(alarmTags);
                break;
        }
    }

    public void history(List<AlarmTag> tags) {

        StringBuilder sb = new StringBuilder();


        List<AlarmSimpleVo> alarmvols = new CopyOnWriteArrayList<>();
        int times = 0;
        for (AlarmTag alarm : tags) {

            sb.append("'").append(alarm.getId().toLowerCase()).append("',");
            times++;
            if (times  == 1000) {
                String ids = sb.substring(0, sb.length() - 1);
                List<AlarmSimpleVo> templs = new CopyOnWriteArrayList<>();
                if (alarm.getAlarmType().equals(AlarmTypeValue.BT.getCode())) {
                    templs = alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.BT.getCode(), ids);
                } else if (alarm.getAlarmType().equals(AlarmTypeValue.WT.getCode())) {
                    templs = alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.WT.getCode(), ids);
                } else if (alarm.getAlarmType().equals(AlarmTypeValue.IN.getCode())) {
                    templs = alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.WT.getCode(), ids);
                }
                alarmvols.addAll(templs);
                sb.setLength(0);
                times=0;
            }
        }

        if (sb.length() > 0) {

            String ids = sb.substring(0, sb.length() - 1);
            List<AlarmSimpleVo> templs = new CopyOnWriteArrayList<>();
            if (alarmTags.get(0).getAlarmType().equals(AlarmTypeValue.BT.getCode())) {
                templs = alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.BT.getCode(), ids);
            } else if (alarmTags.get(0).getAlarmType().equals(AlarmTypeValue.WT.getCode())) {
                templs = alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.WT.getCode(), ids);
            } else if (alarmTags.get(0).getAlarmType().equals(AlarmTypeValue.IN.getCode())) {
                templs = alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.WT.getCode(), ids);
            }
            alarmvols.addAll(templs);
        }

       historymap= new ConcurrentHashMap<>();


        if (!alarmvols.isEmpty()) {
            for (AlarmSimpleVo vo : alarmvols) {
                if(StringUtils.empty(vo.getEndts()))
                {
                    historymap.put(vo.getTbName().toLowerCase(), 0);
                }else
                {
                    historymap.put(vo.getTbName().toLowerCase(), 1);
                }

            }
        }
    }
    /**
     * 分配任务
     */
    public  void taskJobs(boolean start) throws Exception {


        while (start) {

            if (alarmType.equals("bt_alarms")) {

                List<CompletableFuture<String>> futures = new ArrayList<>();

                futures.add(  asyncService.asyncService(alarmTags,readRows,edosUtil, historymap,
                        alarmType,  alarmService,1));

                futures.add(  asyncService.asyncService(alarmInTags,readRows,edosUtil, historymap,
                        alarmType,  alarmService,2));

                // 等待所有任务完成
                CompletableFuture[] futuresArray = futures.toArray(new CompletableFuture[0]);
                CompletableFuture.allOf(futuresArray).join();


            } else {

                List<CompletableFuture<String>> futures = new ArrayList<>();
                int len = 1;

                List<AlarmTag> alarmls = new ArrayList<>();

                int listNumber = alarmTags.size() / taskCount;
                int number = 0;
                if (alarmTags.size() % taskCount != 0) {
                    listNumber = listNumber + 1;
                }


                StringBuilder str = new StringBuilder();
                str.append("总数：").append(alarmTags.size()).append("，线程数：").append(listNumber).append("，分块大小：").append(taskCount);
                log.info(String.valueOf(str));
                for (int i = 0; i < alarmTags.size(); i++) {
                    alarmls.add(alarmTags.get(i));
                    if (i != 0 && (i) % taskCount == 0) {

                        futures.add(asyncService.asyncService(alarmls,readRows,edosUtil, historymap,
                                alarmType,  alarmService,len));
                        alarmls = new ArrayList<>();
                        len++;
                    }
                }

                if (!alarmls.isEmpty()) {

                    futures.add(  asyncService.asyncService(alarmls,readRows,edosUtil, historymap,
                            alarmType,  alarmService,len));
                }


                // 等待所有任务完成
                CompletableFuture[] futuresArray = futures.toArray(new CompletableFuture[0]);
                CompletableFuture.allOf(futuresArray).join();

            }



            log.info("报警排查完成！");


        }
    }


}
