package com.gyee.frame.service.export;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.gyee.frame.common.conf.ExportConfig;
import com.gyee.frame.common.domain.AjaxResult;
import com.gyee.frame.mapper.auto.AlarmsnapMapper;
import com.gyee.frame.mapper.auto.EarlywarningAnalysisPushMapper;
import com.gyee.frame.mapper.auto.MaintenanceAdviceMapper;
import com.gyee.frame.model.auto.*;
import com.gyee.frame.model.excel.AlarmStat;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class EarlywarnAnalysisPushService {

    @Autowired
    private ExportConfig exportConfig;
    @Resource
    private EarlywarningAnalysisPushMapper earlywarningAnalysisPushMapper;
    @Resource
    private AlarmsnapMapper alarmsnapMapper;
    @Resource
    private MaintenanceAdviceMapper maintenanceAdviceMapper;

    private List<Alarmsnap> alarmsnaps;

    private SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");

    private List<MaintenanceAdvice> maintenanceAdvice;
    private Map<String, MaintenanceAdvice> maintenanceAdviceMap;

    public List<MaintenanceAdvice> getMaintenanceAdvice() {
        if(maintenanceAdvice==null){
            MaintenanceAdviceExample example = new MaintenanceAdviceExample();
            maintenanceAdvice=maintenanceAdviceMapper.selectByExample(example);
        }
        return maintenanceAdvice;
    }

    public List<Alarmsnap> getAlarmsnaps() {
        if(alarmsnaps==null){
            AlarmsnapExample alarmsnapExample = new AlarmsnapExample();
            alarmsnaps = alarmsnapMapper.selectByExample(alarmsnapExample);
        }
        return alarmsnaps;
    }

    private static int jgts=7;

    public static void setJgts(int jgts) {
        EarlywarnAnalysisPushService.jgts = jgts;
    }

    public AjaxResult getEarlywarnanalysispush(String startdate, AjaxResult earlyWarning) {
        if(earlyWarning==null) return AjaxResult.error("查询出错！");
        String s = JSON.toJSONString(earlyWarning.get("data"));

        Type type = new TypeReference<List<Map<String,List<AlarmStat>>>>() {}.getType();
        List<Map<String,List<AlarmStat>>> list = JSON.parseObject(s, type);
        List<AlarmStat> alarmstats = new ArrayList<>();

        for (Map<String, List<AlarmStat>> stringListMap : list) {
            for (List<AlarmStat> value : stringListMap.values()) {
                alarmstats.addAll(value);
            }
        }

        EarlywarningAnalysisPushExample example = new EarlywarningAnalysisPushExample();
        example.createCriteria().andCountdayEqualTo(startdate).andStationidEqualTo(alarmstats.get(0).getStationId());
        List<EarlywarningAnalysisPush> ewaspGet = earlywarningAnalysisPushMapper.selectByExample(example);

        if(ewaspGet==null||ewaspGet.size()==0){
            //获取推送的报警
            List<AlarmStat> pushAlarmstats = getPushAlarmstat(startdate,alarmstats);
            for (AlarmStat pushAlarmstat : pushAlarmstats) {
                EarlywarningAnalysisPush ewaspCreate = createEarlywarningAnalysisPush(startdate, pushAlarmstat);
                //加入检修建议ID
                ewaspCreate.setMaintenanceadviceid(getMaintenanceAdviceMap().get(ewaspCreate.getWarnname()).getId());
                ewaspGet.add(ewaspCreate);
                earlywarningAnalysisPushMapper.insert(ewaspCreate);
            }
            createExcel(ewaspGet);
        }else {
            createExcel(ewaspGet);
        }

        return AjaxResult.successData(200,"http:\\\\10.155.32.4:8070\\zhfx\\excel\\"+ewaspGet.get(0).getStationid()+"预警分析推荐.xlsx");
    }

    private void createExcel(List<EarlywarningAnalysisPush> ewaps) {
        SXSSFWorkbook workbook = new SXSSFWorkbook(9000);
        SXSSFSheet sheet = workbook.createSheet("Sheet1");
        SXSSFRow row = sheet.createRow(0);
        row.createCell(0).setCellValue("日期");
        row.createCell(1).setCellValue("场站");
        row.createCell(2).setCellValue("风机");
        row.createCell(3).setCellValue("预警等级");
        row.createCell(4).setCellValue("预警名称");
        row.createCell(5).setCellValue("预警次数");
        row.createCell(6).setCellValue("持续时间");
        row.createCell(7).setCellValue("部件名称");
        row.createCell(8).setCellValue("问题原因");
        row.createCell(9).setCellValue("消缺工艺");
        row.createCell(10).setCellValue("遗留问题");
        for (int i = 0; i < ewaps.size(); i++) {
            SXSSFRow row1 = sheet.createRow(i + 1);
            row1.createCell(0).setCellValue(ewaps.get(i).getCountday());
            row1.createCell(1).setCellValue(ewaps.get(i).getStationid());
            row1.createCell(2).setCellValue(ewaps.get(i).getWindturbineid());
            row1.createCell(3).setCellValue(ewaps.get(i).getWarngrad());
            row1.createCell(4).setCellValue(ewaps.get(i).getWarnname());
            row1.createCell(5).setCellValue(ewaps.get(i).getWarncount());
            row1.createCell(6).setCellValue(ewaps.get(i).getWarnminute());
            row1.createCell(7).setCellValue(ewaps.get(i).getRelatepartstext());
            row1.createCell(8).setCellValue(ewaps.get(i).getReasonsproblem());
            row1.createCell(9).setCellValue(ewaps.get(i).getBehebungcraft());
            row1.createCell(10).setCellValue(ewaps.get(i).getLeftoverproblem());
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(exportConfig.getExportpath()+ewaps.get(0).getStationid()+"\\预警分析推荐.xlsx");
            //out = new FileOutputStream("D:\\预警分析推荐.xlsx");
            workbook.write(out);
            out.flush();
            out.close();
            workbook.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成推送信息
     * @param startdate
     * @param alarmStat
     * @return
     */
    private EarlywarningAnalysisPush createEarlywarningAnalysisPush(String startdate, AlarmStat alarmStat) {
        EarlywarningAnalysisPush eap = new EarlywarningAnalysisPush();
        eap.setCountday(startdate);
        eap.setStationid(alarmStat.getStationId());
        eap.setWindturbineid(alarmStat.getWindturbineId());
        eap.setWarnname(alarmStat.getAlertText());
        eap.setWarncount(alarmStat.getCount());
        eap.setWarnminute(alarmStat.getTime());
        eap.setRelateparts(alarmStat.getRelateParts());
        eap.setRelatepartstext(alarmStat.getRelatePartsText());
        eap.setSnapid(alarmStat.getSnapId());
        eap.setCounttime(getDate(startdate));
        eap.setWarngrad(alarmStat.getRank());
        return eap;
    }

    /**
     * 预警分析推送
     *
     * @param startdate
     * @param ass
     * @return
     */
    private List<AlarmStat> getPushAlarmstat(String startdate, List<AlarmStat> ass) {
        EarlywarningAnalysisPushExample example = new EarlywarningAnalysisPushExample();

        Calendar instance1 = Calendar.getInstance();
        Calendar instance2 = Calendar.getInstance();

        Date date = getDate(startdate);

        instance1.setTime(date);
        instance1.add(Calendar.DATE,1);

        instance2.setTime(date);
        instance2.add(Calendar.DATE,-1*jgts);

        example.createCriteria().andCounttimeBetween(instance2.getTime(), instance1.getTime());
        List<EarlywarningAnalysisPush> ewaspGet = earlywarningAnalysisPushMapper.selectByExample(example);
        List<Long> collectSnapid = ewaspGet.stream().map(eap -> eap.getSnapid()).collect(Collectors.toList());
        //过滤SnapId不为空的、alertrule2配置有的、已经推荐过的
        ass=ass.stream().filter(alarmStat -> alarmStat.getSnapId()!=null &&
                        getMaintenanceAdviceMap().containsKey(alarmStat.getAlertText()) &&
                !collectSnapid.contains(alarmStat.getSnapId())).collect(Collectors.toList());
        //alarmsnap
        Map<Long, Alarmsnap> alarmsnapMap = getAlarmsnaps().stream().collect(Collectors.toMap(Alarmsnap::getId, Function.identity()));
        //加入等级
        List<AlarmStat> alarmStatRemoves = new ArrayList<>();
        for (AlarmStat alarmStat : ass) {
            Alarmsnap alarmsnap = alarmsnapMap.get(alarmStat.getSnapId());
            if (alarmsnap==null){
                alarmStatRemoves.add(alarmStat);
            }else if(alarmsnap.getRank()==null){
                alarmStatRemoves.add(alarmStat);
            }else {
                alarmStat.setRank(alarmsnap.getRank());
            }
        }
        //移除alarmsnap里面没有的snapid
        ass.removeAll(alarmStatRemoves);
        //排序 等级、次数、时间
        List<AlarmStat> collect = ass.stream().sorted(
                Comparator.comparing(AlarmStat::getRank,Comparator.reverseOrder())
                        .thenComparing(AlarmStat::getCount,Comparator.reverseOrder())
                        .thenComparing(AlarmStat::getTime,Comparator.reverseOrder())
                ).collect(Collectors.toList());
        List<AlarmStat> collect1 = collect.stream().filter(alarmStat -> alarmStat.getRank().equals("6")).limit(2).collect(Collectors.toList());
        List<AlarmStat> collect2 = collect.stream().filter(alarmStat -> alarmStat.getRank().equals("4")).limit(2).collect(Collectors.toList());
        List<AlarmStat> collect3 = collect.stream().filter(alarmStat -> alarmStat.getRank().equals("3")).limit(2).collect(Collectors.toList());

        List<AlarmStat> alarmStats = new ArrayList<>();
        alarmStats.addAll(collect1);
        alarmStats.addAll(collect2);
        alarmStats.addAll(collect3);
        return alarmStats;
    }

    /**
     *
     * @return 检修建议报警名称、检修建议
     */
    private Map<String, MaintenanceAdvice> getMaintenanceAdviceMap() {
        if(maintenanceAdviceMap==null){
            maintenanceAdviceMap = getMaintenanceAdvice().stream().collect(Collectors.toMap(MaintenanceAdvice::getAlerttext, Function.identity()));
        }
        return maintenanceAdviceMap;
    }

    private Date getDate(String d){
        Date parse = new Date();
        try {
            parse = simpleDateFormat.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    public List<EarlywarningAnalysisPush> getEarlywarnanalysis(String stationid, String startdate, String enddate) {
        EarlywarningAnalysisPushExample example = new EarlywarningAnalysisPushExample();

        Date dates = new Date();
        Date datee = new Date();
        try {
            dates=simpleDateFormat.parse(startdate);
            datee=simpleDateFormat.parse(enddate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        if(stationid==null||stationid.isEmpty()){
            example.createCriteria().andCounttimeBetween(dates,datee);
        }else {
            example.createCriteria().andStationidEqualTo(stationid).andCounttimeBetween(dates,datee);
        }
        return earlywarningAnalysisPushMapper.selectByExample(example);
    }

    public int saveEarlywarnanalysis(List<EarlywarningAnalysisPush> analysisPushes) {
        int c = 0;
        for (EarlywarningAnalysisPush analysisPush : analysisPushes) {
            EarlywarningAnalysisPush earlywarningAnalysisPush = new EarlywarningAnalysisPush();
            earlywarningAnalysisPush.setReasonsproblem(analysisPush.getReasonsproblem());
            earlywarningAnalysisPush.setBehebungcraft(analysisPush.getBehebungcraft());
            earlywarningAnalysisPush.setLeftoverproblem(analysisPush.getLeftoverproblem());

            EarlywarningAnalysisPushExample example = new EarlywarningAnalysisPushExample();
            example.createCriteria().andIdEqualTo(analysisPush.getId());
            c+=earlywarningAnalysisPushMapper.updateByExampleSelective(earlywarningAnalysisPush,example);
        }
        return c;
    }
}
