package cn.cecep.talroad.service.impl.analysis;

import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.common.core.utils.StringUtils;
import cn.cecep.talroad.domain.EarlyWarning;
import cn.cecep.talroad.domain.PcOutlet;
import cn.cecep.talroad.domain.analysis.SRaRealTimeAnalysisRun;
import cn.cecep.talroad.domain.analysis.SRaRealTimeAnalysisStop;
import cn.cecep.talroad.mapper.analysis.SRaRealTimeAnalysisStopMapper;
import cn.cecep.talroad.service.analysis.ISRaRealTimeAnalysisStopService;
import cn.cecep.talroad.util.ExportWordUtil;
import cn.cecep.talroad.vo.EChartsVO;
import cn.cecep.talroad.vo.analysis.DeviceStatusWorkStepVO;
import cn.cecep.talroad.vo.query.analysis.SRaRealTimeAnalysisStopQuery;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 企业装备停限产分析报(DCS)Service业务层处理
 *
 * @author szhpt
 * @date 2023-03-24*/
@Service
public class SRaRealTimeAnalysisStopServiceImpl extends ServiceImpl<SRaRealTimeAnalysisStopMapper,SRaRealTimeAnalysisStop> implements ISRaRealTimeAnalysisStopService
{

    /**
     * 设备工序与word报告参数对应名称
     */
    private Map<String,String> deviceNameForWordParamMap;

    @PostConstruct
    private void init(){
        deviceNameForWordParamMap = new HashMap<>();
        deviceNameForWordParamMap.put("烧结","SJ");
        deviceNameForWordParamMap.put("球团","QT");
        deviceNameForWordParamMap.put("白灰窑","BHY");
        deviceNameForWordParamMap.put("高炉","GAOLU");
        deviceNameForWordParamMap.put("炼铁","GAOLU");
        deviceNameForWordParamMap.put("发电","FD");
        deviceNameForWordParamMap.put("熟料烧成","SLSC");
        deviceNameForWordParamMap.put("玻璃","BL");
        deviceNameForWordParamMap.put("焚烧","FS");
        deviceNameForWordParamMap.put("锅炉","GUOLU");
    }
    @Autowired
    private SRaRealTimeAnalysisStopMapper sRaRealTimeAnalysisStopMapper;

    /**
     * 查询企业装备停限产分析报(DCS)列表
     *
     * @param sRaRealTimeAnalysisStop 企业装备停限产分析报(DCS)
     * @return 企业装备停限产分析报(DCS)
     */
    @Override
    public List<SRaRealTimeAnalysisStop> selectSRaRealTimeAnalysisStopList(SRaRealTimeAnalysisStopQuery sRaRealTimeAnalysisStop)
    {
        Page<SRaRealTimeAnalysisStop> page=new Page(1,999999);
        List<SRaRealTimeAnalysisStop> list= sRaRealTimeAnalysisStopMapper.selectSRaRealTimeAnalysisStopList(page,sRaRealTimeAnalysisStop);
        List<String> stringList=new ArrayList<>();
        list.forEach(item->{
            stringList.add(item.getDeviceId());
        });
        List<SRaRealTimeAnalysisStop> listItem=sRaRealTimeAnalysisStopMapper.selectSRaRealTimeAnalysisStopListById(sRaRealTimeAnalysisStop,stringList);
        Map<String, List<SRaRealTimeAnalysisStop>> stringListMap = listItem.stream().collect(Collectors.groupingBy( SRaRealTimeAnalysisStop::getDeviceId));
        list.forEach(item->{
            if(stringListMap.containsKey(item.getDeviceId())){
                item.setRunEtc(runStatusConver(stringListMap.get(item.getDeviceId())).get("runStatus"));
                item.setGoingsOn(runStatusConver(stringListMap.get(item.getDeviceId())).get("goingsOn"));
            }
        });
        return list;
    }

    @Override
    public List<Map<String, Object>> pullWorkingProcedureOptions(String industryCategoryCode) {
        List<Map<String, Object>> map =new ArrayList<>();
        if(industryCategoryCode.equals("GT")){
            List<String> numbers = Arrays.asList("球团-SL", "高炉-GL", "烧结-SJJ","白灰窑-LY","发电-FDJZ");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item.split("-")[0]);
                objectMap.put("value",item.split("-")[1]);
                map.add(objectMap);
            });
        }
       /* if(industryCategoryCode.equals("JH")){
            List<String> numbers = Arrays.asList("焦炉");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item);
                objectMap.put("value",item);
                map.add(objectMap);
            });
        }*/
        if(industryCategoryCode.equals("SN")){
            List<String> numbers = Arrays.asList("熟料烧成-SNY");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item.split("-")[0]);
                objectMap.put("value",item.split("-")[1]);
                map.add(objectMap);
            });
        }
        if(industryCategoryCode.equals("BL")){
            List<String> numbers = Arrays.asList("玻璃-SCX");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item.split("-")[0]);
                objectMap.put("value",item.split("-")[1]);
                map.add(objectMap);
            });
        }
        if(industryCategoryCode.equals("FS")){
            List<String> numbers = Arrays.asList("焚烧-FSL");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item.split("-")[0]);
                objectMap.put("value",item.split("-")[1]);
                map.add(objectMap);
            });
        }
        if(industryCategoryCode.equals("DL")){
            List<String> numbers = Arrays.asList("锅炉-GUL");
            numbers.forEach(item->{
                Map<String, Object> objectMap=new HashMap<>();
                objectMap.put("label",item.split("-")[0]);
                objectMap.put("value",item.split("-")[1]);
                map.add(objectMap);
            });
        }
        return map;
    }

    @Override
    public IPage<SRaRealTimeAnalysisStop> selectSRaRealTimeAnalysisStopListPage(SRaRealTimeAnalysisStopQuery sRaRealTimeAnalysisStop) {
        Page<SRaRealTimeAnalysisStop> iPage=new Page<SRaRealTimeAnalysisStop>(sRaRealTimeAnalysisStop.getPageNum(),sRaRealTimeAnalysisStop.getPageSize());
        List<SRaRealTimeAnalysisStop> list=sRaRealTimeAnalysisStopMapper.selectSRaRealTimeAnalysisStopListPage(iPage,sRaRealTimeAnalysisStop);
        List<String> stringList=new ArrayList<>();
        list.forEach(item->{
            stringList.add(item.getDeviceId());
        });
        List<SRaRealTimeAnalysisStop> listItem=sRaRealTimeAnalysisStopMapper.selectSRaRealTimeAnalysisStopListById(sRaRealTimeAnalysisStop,stringList);
        Map<String, List<SRaRealTimeAnalysisStop>> stringListMap = listItem.stream().collect(Collectors.groupingBy( SRaRealTimeAnalysisStop::getDeviceId));
        list.forEach(item->{
            if(stringListMap.containsKey(item.getDeviceId())){
                item.setRunEtc(runStatusConver(stringListMap.get(item.getDeviceId())).get("runStatus"));
                item.setGoingsOn(runStatusConver(stringListMap.get(item.getDeviceId())).get("goingsOn"));
            }
        });
        iPage.setRecords(list);
        return iPage;
    }
    public Map<String,String> runStatusConver(List<SRaRealTimeAnalysisStop> list){
        Map<String,String> map=new HashMap<>();
        String finalValue="";
        String start="";
        String end="";
        String goingsOn="";
        TreeSet<String> chilePollutant = new TreeSet<>();
        TreeSet<String> goingsOnArr = new TreeSet<>();
        if(CollectionUtil.isNotEmpty(list)){
            finalValue= list.get(0).getOperationStatus();
            start=DateUtil.format(list.get(0).getUpdateTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
            if(StringUtils.isNotEmpty(list.get(0).getGoingsOn())){
                goingsOn=list.get(0).getGoingsOn();
            }
        }
        for (SRaRealTimeAnalysisStop runStatus : list) {
            if(finalValue.equals(runStatus.getOperationStatus())){
                end=DateUtil.format(runStatus.getUpdateTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
            }else {
                chilePollutant.add(String.format("%s至%s%s",start,end,operationStatus(finalValue)));
                if(StringUtils.isNotEmpty(goingsOn)) {
                    goingsOnArr.add(goingsOn);
                }
                start=DateUtil.format(runStatus.getUpdateTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
                end=DateUtil.format(runStatus.getUpdateTime(),DatePattern.NORM_DATETIME_MINUTE_PATTERN);
                finalValue=runStatus.getOperationStatus();
                if(StringUtils.isNotEmpty(runStatus.getGoingsOn())){
                    goingsOn=runStatus.getGoingsOn();
                }
            }
        }
        chilePollutant.add(String.format("%s至%s%s",start,end,operationStatus(finalValue)));
        if(StringUtils.isNotEmpty(goingsOn)) {
            goingsOnArr.add(goingsOn);
        }
        map.put("runStatus",String.join("，", chilePollutant));
        map.put("goingsOn",String.join("，", goingsOnArr));
        return map;
    }
    public String operationStatus(String status){
        String str="";
        if(status.equals("1")){
            str="运行";
        }
        if(status.equals("2")){
            str="停运";
        }
        if(status.equals("3")){
            str="启停";
        }
        if(status.equals("4")){
            str="停启";
        }
        if(status.equals("5")){
            str="数据缺失";
        }
        if(status.equals("6")){
            str="数据恒值";
        }
        if(status.equals("7")){
            str="数据异常";
        }
        return  str;
    };

    @Override
    public EChartsVO resultCurve(String deviceId, String monitoringStartTime, String monitoringEndTime) {
        QueryWrapper<SRaRealTimeAnalysisStop> wrapper=new QueryWrapper<SRaRealTimeAnalysisStop>();
        wrapper.eq(StringUtils.isNotEmpty(deviceId), "device_id", deviceId);
        wrapper.ge("analyse_time", DateUtil.parse(monitoringStartTime,"yyyy-MM-dd HH:mm:ss"));
        wrapper.le("analyse_time", DateUtil.parse(monitoringEndTime,"yyyy-MM-dd HH:mm:ss"));
        wrapper.orderByAsc("analyse_time");
        List<SRaRealTimeAnalysisStop> sRaRealTimeAnalysisRuns = sRaRealTimeAnalysisStopMapper.selectList(wrapper);

        Map<String, String> timeStatusMap = sRaRealTimeAnalysisRuns.stream().collect(Collectors.toMap(o ->  DateUtil.format(o.getUpdateTime(),DatePattern.NORM_DATETIME_FORMATTER), o -> o.getOperationStatus(), (o1, o2) -> o1));
        // x轴数据
        List<String> xdata = DateUtils.getRangeTimes("M", monitoringStartTime, monitoringEndTime);

        EChartsVO.SeriesObj ser1 = new EChartsVO.SeriesObj();
        ser1.setName("运行");
        ser1.setProp("1");
        ser1.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser2 = new EChartsVO.SeriesObj();
        ser2.setName("停运");
        ser2.setProp("2");
        ser2.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser3 = new EChartsVO.SeriesObj();
        ser3.setName("启停");
        ser3.setProp("3");
        ser3.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser4 = new EChartsVO.SeriesObj();
        ser4.setName("停启");
        ser4.setProp("4");
        ser4.setValues(new ArrayList<>());

        EChartsVO.SeriesObj ser5 = new EChartsVO.SeriesObj();
        ser5.setName("数据缺失");
        ser5.setProp("5");
        ser5.setValues(new ArrayList<>());

        EChartsVO chartsVO = new EChartsVO();
        chartsVO.setXData(xdata);
        chartsVO.setSeries(Arrays.asList(ser1, ser2, ser3, ser4,ser5));

        /*
            填充系列值
         */

        // 当前时间设备状态
        String status = null;

        // 遍历x轴，保证系列值与x轴刻度一一对应
        for (String time : xdata) {
            String s = timeStatusMap.get(time);

            // 若不为空，更新状态，否则状态保持原值
            if (s != null) {
                status = s;
            }

            for (EChartsVO.SeriesObj ser : chartsVO.getSeries()) {
                // 若系列的prop属性与状态码相等，则设置系列值为状态码，否则填充null
                if (ser.getProp().equals(status)) {
                    ser.getValues().add(status);
                } else {
                    ser.getValues().add(null);
                }
            }
        }
        return chartsVO;
    }

    /**
     * 企业设备停限产报告导出
     * @param response
     * @param sRaRealTimeAnalysisStop
     */
    @Override
    public void exportWordReport(HttpServletResponse response, SRaRealTimeAnalysisStopQuery sRaRealTimeAnalysisStop) throws TemplateException, IOException {
        //获取设备停限产数量统计
        List<DeviceStatusWorkStepVO> deviceStatusWorkStepVOS = this.sRaRealTimeAnalysisStopMapper.selectDeviceByStatusAndWorkStep(sRaRealTimeAnalysisStop);
        Map<String,Object> map = new HashMap<>();
        map.put("dataTimeStr",sRaRealTimeAnalysisStop.getAnalyseStartTime()+"-"+sRaRealTimeAnalysisStop.getAnalyseEndTime());
        //记录设备id
        List<String>normalList = new ArrayList<>(),
                startStopList = new ArrayList<>(),
                stopList = new ArrayList<>();
        List<SRaRealTimeAnalysisStop> normalDataList = new ArrayList<>(),
                startStopDataList = new ArrayList<>(),
                stopDataList = new ArrayList<>();
        //初始化全局参数
        for (String value : deviceNameForWordParamMap.values()) {
                map.put(value+"Count",0);
                map.put(value+"StartStopCount",0);
                map.put(value+"ExceptionCount",0);
                map.put(value+"NormalCount",0);
                map.put(value+"StopCount",0);
        }
        //进行标记数据，根据状态的出现决定哪个数据增加数量
        for (DeviceStatusWorkStepVO deviceStatusWorkStepVO : deviceStatusWorkStepVOS) {
            //确定工序类型，进行累加
            String workStepName = "";
            for (Map.Entry<String, String> stringStringEntry : this.deviceNameForWordParamMap.entrySet()) {
                if(deviceStatusWorkStepVO.getWorkStep().equalsIgnoreCase(stringStringEntry.getKey())){
                    //进行赋值，跳出循环
                    workStepName =stringStringEntry.getValue();
                    break;
                }
            }
            String statuses = deviceStatusWorkStepVO.getDeviceStatuses();
            log.debug(deviceStatusWorkStepVO+":"+workStepName+":"+map.get(workStepName+"Count"));
            map.put(workStepName+"Count",(Integer)map.get(workStepName+"Count")+1);
            //启停类状态 3||4||(1，2) 出现如下情况，则为启停;
            if(statuses.indexOf("3") >= 0
                    || statuses.indexOf("4") >=0
                    || (statuses.indexOf("1") >= 0 && statuses.indexOf("2") >=0)){
                startStopList.add(deviceStatusWorkStepVO.getDeviceId());
                map.put(workStepName+"StartStopCount", (Integer)map.get(workStepName+"StartStopCount")+1);
                //异常类状态 5||6||7
            }else if(statuses.indexOf("5") >= 0
                    ||statuses.indexOf("6") >= 0
                    ||statuses.indexOf("7") >= 0){
                map.put(workStepName+"ExceptionCount", (Integer)map.get(workStepName+"ExceptionCount")+1);
                //正常状态
            }else if(statuses.indexOf("1") >= 0){
                normalList.add(deviceStatusWorkStepVO.getDeviceId());
                map.put(workStepName+"NormalCount", (Integer)map.get(workStepName+"NormalCount")+1);
                //停产状态
            }else if(statuses.indexOf("2") >= 0){
                stopList.add(deviceStatusWorkStepVO.getDeviceId());
                map.put(workStepName+"StopCount", (Integer)map.get(workStepName+"StopCount")+1);
            }
        }
        //添加列表数据
        List<SRaRealTimeAnalysisStop> sRaRealTimeAnalysisStops = selectSRaRealTimeAnalysisStopList(sRaRealTimeAnalysisStop);
        for (SRaRealTimeAnalysisStop raRealTimeAnalysisStop : sRaRealTimeAnalysisStops) {
            String deviceId = raRealTimeAnalysisStop.getDeviceId();
            if (normalList.contains(deviceId)) {
                normalDataList.add(raRealTimeAnalysisStop);
            }else if(stopList.contains(deviceId)){
                stopDataList.add(raRealTimeAnalysisStop);
            }else if(startStopList.contains(deviceId)){
                startStopDataList.add(raRealTimeAnalysisStop);
            }
        }
        map.put("normalDeviceFactoryList",normalDataList);
        map.put("stopDeviceFactoryList",stopDataList);
        map.put("startStopDeviceFactoryList",startStopDataList);
        ExportWordUtil.exportToWord(map,response,"wordReport/FactoryDeviceRunReport.ftl","wordReport/FactoryDeviceRunReport.docx","企业装备停限产分析报表.docx");
    }
}
