package cn.cecep.talroad.service.strategy;

import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.common.core.utils.StringUtils;
import cn.cecep.talroad.domain.AmProblemFi;
import cn.cecep.talroad.domain.BasDeviceSalAnalysis;
import cn.cecep.talroad.domain.SRaRealTimeAnalysisRunOne;
import cn.cecep.talroad.domain.analysis.SRaRealTimeAnalysisCo;
import cn.cecep.talroad.domain.analysis.SRaRealTimeAnalysisRun;
import cn.cecep.talroad.enums.DeviceStatusEnum;
import cn.cecep.talroad.enums.JudgeEnum;
import cn.cecep.talroad.enums.ProblemTypeEnum;
import cn.cecep.talroad.enums.ReleaseStatusEnum;
import cn.cecep.talroad.service.IAmProblemFiService;
import cn.cecep.talroad.service.IBasDeviceSalAnalysisService;
import cn.cecep.talroad.service.ISRaRealTimeAnalysisRunOneService;
import cn.cecep.talroad.service.analysis.ISRaRealTimeAnalysisCoService;
import cn.cecep.talroad.service.analysis.ISRaRealTimeAnalysisRunService;
import cn.cecep.talroad.vo.FactoryDeviceVo;
import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Auther: cjh
 * @Date: 2023-04-27 15:53
 * @Class: StatusStrategyAdapter
 * @Deseription:
 * @Version V1.0
 */
@Slf4j
public abstract class StatusStrategyAdapter extends AbstractStrategyAdapter {

    @Autowired
    private IBasDeviceSalAnalysisService basDeviceSalAnalysisService;
    @Autowired
    private ISRaRealTimeAnalysisRunService raRealTimeAnalysisRunService;
    @Autowired
    private IAmProblemFiService amProblemFiService;
    @Autowired
    private ISRaRealTimeAnalysisCoService sRaRealTimeAnalysisCoService;
    @Autowired
    private ISRaRealTimeAnalysisRunOneService isRaRealTimeAnalysisRunOneService;

    @Override
    protected void doProcess(String industry, String deviceType, Date tempDate) {
        this.doProcessStatus(industry,deviceType,tempDate);
    }

    /**
     * 处理产量统计
     * @param vo
     */
    @Override
    protected void doProcessYield(FactoryDeviceVo vo){

    }
    /**
     * 临时处理历史数据
     * @param factoryId
     * @param industry
     * @param deviceType
     * @param tempDate
     * @return
     */
    @Override
    protected void doProcessYieldTemp(String factoryId,String industry,String deviceType,Date tempDate){

    }

    /**
     * 处理设备停限产状态、放散状态、产量计算
     * @param industry
     * @param deviceType
     * @return
     */
    protected abstract void doProcessStatus(String industry,String deviceType,Date tempDate);

    /**
     * 处理设备运行状态
     * @param vo
     * @param start
     * @param oldStatus
     * @param currentStatus
     * @param judgeEnum
     * @return
     */
    protected SRaRealTimeAnalysisRun doProcessDeviceRunStatus(FactoryDeviceVo vo, Date start,Date end,
        SRaRealTimeAnalysisRunOne oldStatus,  DeviceStatusEnum currentStatus, JudgeEnum judgeEnum) {
        SRaRealTimeAnalysisRun realRun = new SRaRealTimeAnalysisRun();
        realRun.setFactoryId(vo.getFactoryId());
        realRun.setFactoryName(vo.getFactoryName());
        realRun.setDistrictCode(vo.getCityCode());
        realRun.setDistrictName(vo.getCityName());
        realRun.setIndustryCategoryCode(vo.getIndustry());
        realRun.setIndustryCategoryName(vo.getIndustryName());
        realRun.setPerformanceLevel(vo.getPreConLevel());
        realRun.setDeviceId(vo.getDeviceId());
        realRun.setDeviceName(vo.getDeviceName());
        realRun.setDeviceType("1");//1 生产设备 2 治理设备
        realRun.setJudgementBasis(judgeEnum.getCode());//判断依据
        realRun.setUpdateTime(DateUtils.parseFormatDate("yyyy-MM-dd HH:mm:00",end));
        realRun.setCreateTime(new Date());
        // 设备缺失参数
        if(DeviceStatusEnum.MISS.getCode().equals(currentStatus.getCode())) {
            // 数据缺失情况调用
            //String runEtc = getRunEtc(start,end, currentStatus.getValue());
            realRun.setOperationStatus(currentStatus.getCode());
            //realRun.setRunEtc(runEtc);
        }else {
            // 判断启停、停启状态两个参数为必须值 设备上次状态为生产，
            if (oldStatus != null && StringUtils.isNotEmpty(oldStatus.getDataId()) && DeviceStatusEnum.RUN.getCode().equals(oldStatus.getOperationStatus())) {
                //本次为生产
                if( DeviceStatusEnum.RUN.getCode().equals(currentStatus.getCode())) {
                    //本次停运，获取启停运行时间段
                    //String runEtc = getRunEtc(start, end, DeviceStatusEnum.RUN.getValue());
                    realRun.setOperationStatus(DeviceStatusEnum.RUN.getCode());
                    //realRun.setRunEtc(runEtc);
                }else if(DeviceStatusEnum.STOP.getCode().equals(currentStatus.getCode())){
                    //本次停运，获取启停运行时间段
                    //String runEtc = getRunEtc(start, end, DeviceStatusEnum.RUN_STOP.getValue());
                    realRun.setOperationStatus(DeviceStatusEnum.RUN_STOP.getCode());
                    //realRun.setRunEtc(runEtc);
                }
            } else if (oldStatus != null&& StringUtils.isNotEmpty(oldStatus.getDataId()) && DeviceStatusEnum.STOP.getCode().equals(oldStatus.getOperationStatus())){
                //上次设备状态为停运
                //本次为停运
                if(DeviceStatusEnum.STOP.getCode().equals(currentStatus.getCode())) {
                    //String runEtc = getRunEtc(start,end, DeviceStatusEnum.STOP.getValue());
                    realRun.setOperationStatus(DeviceStatusEnum.STOP.getCode());
                    //realRun.setRunEtc(runEtc);
                }else if(DeviceStatusEnum.RUN.getCode().equals(currentStatus.getCode())){
                    //本次运行，获取停启运行时间段
                    //String runEtc = getRunEtc(start, end, DeviceStatusEnum.STOP_RUN.getValue());
                    realRun.setOperationStatus(DeviceStatusEnum.STOP_RUN.getCode());
                    //realRun.setRunEtc(runEtc);
                }
            }else {
                //String runEtc = getRunEtc(start, start, currentStatus.getCode());
                realRun.setOperationStatus(currentStatus.getCode());
                //realRun.setRunEtc(runEtc);
            }
        }

        return  realRun;
    }

    /**
     * 获取运行时间段
     * @param start
     * @param runStatus
     * @return
     */
    protected String getRunEtc(Date start, Date end,String runStatus) {
        StringBuffer sb = new StringBuffer();
        sb.append(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",start)).append("-").append(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00",end)).append(runStatus);
        return sb.toString();
    }

    /**
     * 查询设备上次状态
     * @param factoryId
     * @param deviceId
     * @return
     */
    protected SRaRealTimeAnalysisRunOne getOldDeviceStatus(String factoryId,String deviceId){
        SRaRealTimeAnalysisRunOne run = new SRaRealTimeAnalysisRunOne();
        try {
            run.setFactoryId(factoryId);
            run.setDeviceId(deviceId);
            List<SRaRealTimeAnalysisRunOne> runList = isRaRealTimeAnalysisRunOneService.selectAnalysisRunByParams(run);
            if (runList != null && runList.size() > 0) {
                return runList.get(0);
            }
        } catch (Exception e) {
            log.error("查询设备上一次运行状态异常："+e);
        }
        return run;
    }

    /**
     * 保存co放散分析数据
     * @param vo    设备信息
     * @param start     日期
     * @param status    放散情况
     */
    protected SRaRealTimeAnalysisCo doProcessAnalysisCoData(FactoryDeviceVo vo,Date start,Date end, ReleaseStatusEnum status) {
        String old = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", start);
        String curr = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", end);

        SRaRealTimeAnalysisCo analysisCo = new SRaRealTimeAnalysisCo();
        analysisCo.setFactoryId(vo.getFactoryId());
        analysisCo.setFactoryName(vo.getFactoryName());
        analysisCo.setDistrictCode(vo.getCityCode());
        analysisCo.setDistrictName(vo.getCityName());
        analysisCo.setIndustryCategoryCode(vo.getIndustry());
        analysisCo.setIndustryCategoryName(vo.getIndustryName());
        analysisCo.setPerformanceLevel(vo.getPreConLevel());
        analysisCo.setWorkingProcedure(vo.getWorkStep());
        analysisCo.setDeviceName(vo.getDeviceName());
        analysisCo.setDeviceId(vo.getDeviceId());
        analysisCo.setDiffuse(old+"-"+curr+status.getName());
        analysisCo.setAnalyseTime(DateUtils.parseFormatDate("yyyy-MM-dd HH:mm:00", start));
        analysisCo.setCreateTime(new Date());
        analysisCo.setUpdateTime(DateUtils.parseFormatDate("yyyy-MM-dd HH:mm:00", start));
        analysisCo.setDiffuseStartTime(DateUtils.parseFormatDate("yyyy-MM-dd HH:mm:00",start));
        analysisCo.setDiffuseEndTime(DateUtils.parseFormatDate("yyyy-MM-dd HH:mm:00",end));
        analysisCo.setDiffuseStatus(status.getCode());
        return analysisCo;
    }

    /**
     * 处理设备状态
     * @param factoryId
     * @param deviceId
     * @param stauts
     * @param gasStatus
     */
    public BasDeviceSalAnalysis doProcessDeviceAnalysisStatus(String factoryId,String deviceId,String stauts,String gasStatus){
        QueryWrapper<BasDeviceSalAnalysis> basDeviceStatus = new QueryWrapper<>();
        basDeviceStatus.eq("factory_id", factoryId);
        basDeviceStatus.eq("device_id", deviceId);
        basDeviceStatus.last("limit 1");
        BasDeviceSalAnalysis oldBasDevice = null;
        try {
            // 查询设备原有设备状态
            oldBasDevice = basDeviceSalAnalysisService.getOne(basDeviceStatus);
        } catch (Exception e) {
            log.error("AbstractStrategyAdapter.doCheckProcess##查询原有状态报错"+e.getMessage());
        }
        if(oldBasDevice!=null) {
            oldBasDevice.setMonTime(new Date());
            oldBasDevice.setMonStatus(stauts);
            oldBasDevice.setCoalGasStatus(gasStatus);
            return oldBasDevice;
        }else{
            BasDeviceSalAnalysis newBasDevice = new BasDeviceSalAnalysis();
            newBasDevice.setDeviceId(deviceId);
            newBasDevice.setFactoryId(factoryId);
            newBasDevice.setMonTime(new Date());
            newBasDevice.setMonStatus(stauts);
            newBasDevice.setCoalGasStatus(gasStatus);
            newBasDevice.setCreateTime(new Date());
            return newBasDevice;
        }
    }

    /**
     * 处理报警数据
     * @param factoryId
     * @param deviceId
     * @param deviceName
     * @param start
     * @param end
     * @param problemType
     * @param msg
     */
    protected AmProblemFi doProcessAlaram(String factoryId,String deviceId,String deviceName, Date start, Date end, ProblemTypeEnum problemType, String msg,String param,String paramProperty) {
        AmProblemFi problemFi = new AmProblemFi();
        problemFi.setProblemSources("1");
        problemFi.setFactoryId(factoryId);
        problemFi.setProblemDetails(msg);
        problemFi.setType(0);
        // 数据缺失专有字段
        if(problemType.getCode().equals(ProblemTypeEnum.SJQS.getCode())) {
            problemFi.setDeviceName(deviceName);
        }
        problemFi.setProblemType(problemType.getCode());
        problemFi.setProblemTreatmentState("1");
        problemFi.setAnalyseTime(start);
        problemFi.setAnalyseTimeEnd(end);
        problemFi.setStationId(deviceId);
        problemFi.setStationName(deviceName);
        problemFi.setCreateTime(new Date());
        if(StringUtils.isNotEmpty(param)) {
            Map<String, Object> map = new HashMap<>();
            List<Map<String, Object>> list = new ArrayList<>();
            Map m = new HashMap();
            m.put("deviceId", deviceId);
            m.put("params", Arrays.asList(paramProperty.split(",")));
            list.add(m);
            map.put("dcsDeviceList", list);
            problemFi.setExtra(JSON.toJSONString(map));
        }
        return problemFi;
    }

    /**
     * 批量保存co放散分析
     * @param list
     */
    protected void doSaveBatchSRaRealTimeAnalysisCo(List<SRaRealTimeAnalysisCo> list){
        if(list!=null&&list.size()>0){
            List<List<SRaRealTimeAnalysisCo>> partion = ListUtil.partition(list,1000);
            partion.forEach(p->{
                sRaRealTimeAnalysisCoService.saveBatch(p);
            });
        }
    }

    /**
     * 设备状态批量保存或更新
     * @param list
     */
    protected void doSaveOrUpdateBatchDeviceStatus(List<BasDeviceSalAnalysis> list){
        if(list!=null&&list.size()>0) {
            List<List<BasDeviceSalAnalysis>> partion = ListUtil.partition(list,1000);
            partion.forEach(p->{
                basDeviceSalAnalysisService.saveOrUpdateBatch(p);
            });
        }
    }

    /**
     * 批量保存设备运行状态
     * @param list
     */
    protected void doSaveBatchAnalysisRunStatus(List<SRaRealTimeAnalysisRun> list){
        if(list!=null&&list.size()>0) {
            List<List<SRaRealTimeAnalysisRun>> partion = ListUtil.partition(list,1000);
            partion.forEach(p->{
                raRealTimeAnalysisRunService.saveBatch(p);
            });

        }
    }

    /**
     * 批量保存设备运行状态
     * @param list
     */
    protected void doSaveBatchAnalysisRunOneStatus(List<SRaRealTimeAnalysisRunOne> list){
        if(list!=null&&list.size()>0) {
            list.forEach(t->{
                isRaRealTimeAnalysisRunOneService.saveOrUpdate(t);
            });
        }
    }

    /**
     * 批量保存报警数据
     * @param list
     */
    protected void doSaveBatchAlarm(List<AmProblemFi> list){
        if(list!=null&&list.size()>0) {
            List<List<AmProblemFi>> partion = ListUtil.partition(list,1000);
            partion.forEach(p->{
                amProblemFiService.saveBatch(p);
            });
        }
    }
}
