package cn.cecep.talroad.service.strategy.support.gt;

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.BasDeviceConfig;
import cn.cecep.talroad.domain.MonDevReal;
import cn.cecep.talroad.domain.STaskYieldTrend;
import cn.cecep.talroad.enums.DeviceParamTypeEnum;
import cn.cecep.talroad.enums.ProblemTypeEnum;
import cn.cecep.talroad.enums.TimeTypeEnum;
import cn.cecep.talroad.enums.YieldTypeEnum;
import cn.cecep.talroad.service.IBasDeviceConfigService;
import cn.cecep.talroad.service.IBasDeviceParamService;
import cn.cecep.talroad.service.IMonDevRealService;
import cn.cecep.talroad.vo.BasDeviceParamVo;
import cn.cecep.talroad.vo.FactoryDeviceVo;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.math.BigDecimal;
import java.math.RoundingMode;
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 java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Auther: cjh
 * @Date: 2023-03-29 15:45
 * @Class: GtZlCountAdapter
 * @Deseription: 定时任务-计算转炉炉数每小时一次
 * @Version V1.0
 */
@Slf4j
@Service("GTZLZL")
public class GtZlCountAdapter extends GtYieldStrategyAdapter {

    @Autowired
    private IBasDeviceParamService basDeviceParamService;
    @Autowired
    private IBasDeviceConfigService basDeviceConfigService;
    @Autowired
    private IMonDevRealService monDevRealService;

    @Override
    protected void doProcessYieldData(FactoryDeviceVo vo, List<MonDevReal> currList, List<MonDevReal> oldList, Date lastHour, boolean flag) {
        List<STaskYieldTrend> yieldList = new ArrayList<>();
        List<BasDeviceParamVo> paramsList = basDeviceParamService.selectBasDeviceParamByCondition(vo.getDeviceId(), Arrays.asList("p2"));

        //查询吹氧量最小值
        AtomicReference<Double> minValue = new AtomicReference<>(0.0);
        AtomicReference<String> gcrl = new AtomicReference<>("");
        if (paramsList != null && paramsList.size() > 0) {
            paramsList.forEach(p -> {
                // 吹氧量
                if ("p2".equalsIgnoreCase(p.getParamCodeSvc())) {
                    minValue.set(p.getNormalValue().multiply(new BigDecimal(0.3)).setScale(2,RoundingMode.HALF_UP).doubleValue());
                }
            });
            log.info("设备编号:"+vo.getDeviceId()+"吹氧量最小值："+minValue.get());
            // 吹氧量最小值配置不为空
            if (minValue.get()!=null&&minValue.get()>0) {
                List<MonDevReal> allList = new ArrayList<>();
                if(currList!=null&&currList.size()>0) {
                    // 需要验证炉数计算逻辑
                    AtomicInteger it = new AtomicInteger();//0变成大于0的数量
                    AtomicInteger m = new AtomicInteger();//大于0变成0的数量
                    AtomicInteger c = new AtomicInteger();//索引下标
                    Map<Integer,List<Integer>> tmap  = new HashMap<>();
                    Double first = Double.valueOf(currList.stream().findFirst().get().getP2());
                    // 第一个值不为0
                    if(first.compareTo(0.0)!=0){
                        Date lastTwoHour = DateUtils.addHours(lastHour,-1);
                        Date lastTwoHourBegin = DateUtils.parseFormatDate("yyyy-MM-dd HH:00:00",lastTwoHour);
                        Date lastTwoHourEnd = DateUtils.parseFormatDate("yyyy-MM-dd HH:59:59",lastTwoHour);
                        MonDevReal real = new MonDevReal();
                        real.setFactoryId(vo.getFactoryId());
                        real.setDeviceId(vo.getDeviceId());
                        real.setTimeType(TimeTypeEnum.REAL.getCode());
                        Map<String, Object> params = new HashMap<>();
                        params.put("lastDate", lastTwoHourBegin);
                        params.put("currDate", lastTwoHourEnd);
                        real.setParams(params);
                        List<MonDevReal> lastTwoList = monDevRealService.selectLastHourData(real);
                        AtomicInteger a = new AtomicInteger();
                        AtomicInteger b = new AtomicInteger();
                        //获取最后一个0
                        lastTwoList.forEach(r->{
                            a.getAndIncrement();
                            if(Double.valueOf(r.getP2()).compareTo(0.0)==0){
                                b.set(a.get()-1);
                            }
                        });
                        if(b.get()>0) {
                            List<MonDevReal> sub = lastTwoList.subList(b.get(), lastTwoList.size());
                            allList.addAll(sub);
                        }
                    }
                    allList.addAll(currList);
                    // 合并后数据的第一个元素的吹氧量
                    Double newFirst = Double.valueOf(allList.stream().findFirst().get().getP2());
                    AtomicReference<Double> last = new AtomicReference<>(new Double(newFirst));
                    allList.forEach(real ->{
                        if(StringUtils.isNotEmpty(real.getP2())){
                            if(new BigDecimal(last.get()).compareTo(new BigDecimal(0))==0&&new BigDecimal(real.getP2()).compareTo(new BigDecimal(0.0))==1){
                                it.getAndIncrement();
                                List<Integer> s = tmap.get(it.get());
                                if(s==null){
                                    s = new ArrayList<>();
                                }
                                s.add(c.get());
                                tmap.put(it.get(),s);
                            }
                            if(it.get()>0&&new BigDecimal(last.get()).compareTo(new BigDecimal(0.0))==1&&new BigDecimal(real.getP2()).compareTo(new BigDecimal(0.0))==0){
                                m.getAndIncrement();
                                List<Integer> s = tmap.get(m.get());
                                if(s==null){
                                    s = new ArrayList<>();
                                }
                                s.add(c.get());
                                tmap.put(m.get(),s);
                            }
                            last.set(Double.valueOf(real.getP2()));
                        }
                    });


                    AtomicInteger ls = new AtomicInteger();
                    if(it.get()>m.get()){
                        ls.set(m.get());
                    }else{
                        ls.set(it.get());
                    }

                    tmap.values().forEach(l->{
                        if(l.size()==2){
                            List<MonDevReal> sub1 = currList.subList(l.get(0),l.get(1));
                            if(sub1.size()>0){
                                // 判断煤气回收三通阀状态在吹氧量从0变为非0再到0的过程中，是否出现过1，出现则算煤气回收过，没有出现过1，则算煤气未回收
                                AtomicBoolean isHs = new AtomicBoolean();
                                sub1.forEach(mq->{
                                    if(Double.valueOf(mq.getMq2()).compareTo(Double.valueOf(1))==0){
                                        isHs.set(true);
                                    }
                                });
                                // 煤气未回收则生成报警
                                if(!isHs.get()){
                                    StringBuffer sb = new StringBuffer();
                                    sb.append(vo.getFactoryName()).append(vo.getDeviceName()).append("在").append(DateUtils.parseDateToStr("yyyy-MM-dd HH",lastHour)).append("存在煤气未回收情况。");
                                    AmProblemFi problemFi = doProcessAlaram(vo.getFactoryId(), vo.getDeviceId(), vo.getDeviceName(), lastHour,DateUtils.parseFormatDate("yyyy-MM-dd HH:59:59",lastHour)
                                        , ProblemTypeEnum.GAS_UNRECOVER, sb.toString(),
                                        "炉数,吹氧量,煤气回收三通阀状态", "p1,p2,mq2");
                                    super.doSaveAlarm(problemFi);
                                }
                                Double max = sub1.stream().mapToDouble(s->{return Double.valueOf(s.getP2());}).max().getAsDouble();
                                if(new BigDecimal(max).compareTo(new BigDecimal(minValue.get()))==-1){
                                    ls.set(ls.get() - 1);
                                }
                            }
                        }
                    });
                    log.info("设备编号:"+vo.getDeviceId()+"炉数:"+ls);
                    if (ls.get() > 0) {
                        // 炉数
                        QueryWrapper<BasDeviceConfig> configQueryWrapper = new QueryWrapper<>();
                        configQueryWrapper.eq("factory_id", vo.getFactoryId());
                        configQueryWrapper.eq("device_id", vo.getDeviceId());
                        configQueryWrapper.eq("industry", vo.getIndustry());
                        configQueryWrapper.eq("device_type", vo.getDeviceType());
                        List<BasDeviceConfig> configList = basDeviceConfigService.list(configQueryWrapper);
                        if (configList != null && configList.size() > 0) {
                            configList.forEach(p -> {
                                // 公称容量
                                if (DeviceParamTypeEnum.GC_TYPE.getCode()
                                    .equalsIgnoreCase(p.getParamCode())) {
                                    if (StringUtils.isNotEmpty(p.getNormalValue())) {
                                        gcrl.set(p.getNormalValue());
                                    }
                                }
                            });
                        }

                        Date analyseTime = DateUtils.parseFormatDate("yyyy-MM-dd HH", lastHour);

                        BigDecimal cl = new BigDecimal(0);
                        if(minValue.get()!=null) {
                            //计算出钢量

                            Double cgl = currList.stream().filter(
                                real -> StringUtils.isNotEmpty(real.getP2())
                                    && Double.valueOf(real.getP2()) > Double.valueOf(minValue.get())).mapToDouble(t -> Double.valueOf(t.getG938())).sum();

                            // 出钢量
                            STaskYieldTrend cglYield = super.doBuildTrenData(vo.getFactoryId(), vo.getDeviceId(),YieldTypeEnum.GT_003,lastHour,new BigDecimal(cgl),flag);
                            yieldList.add(cglYield);
                            Double gcrlCount = new Double(0);
                            // 公称容量不为空
                            if(StringUtils.isNotEmpty(gcrl.get())) {
                                cl = new BigDecimal(gcrl.get()).multiply(new BigDecimal(ls.get())).setScale(2, RoundingMode.HALF_UP);
                                gcrlCount = Double.valueOf(gcrl.get());
                            } // 保存转炉产量
                            super.doSaveAnalysisConverterData(vo,gcrlCount, ls.get(), cgl, analyseTime, cl);
                        }

                        // 炉数
                        STaskYieldTrend lsYield = super.doBuildTrenData(vo.getFactoryId(), vo.getDeviceId(),YieldTypeEnum.GT_001,lastHour,new BigDecimal(ls.get()),flag);
                        yieldList.add(lsYield);
                        // 焦炉产量
                        STaskYieldTrend clYield = super.doBuildTrenData(vo.getFactoryId(), vo.getDeviceId(),YieldTypeEnum.GT_002,lastHour,cl,flag);
                        yieldList.add(clYield);
                    }
                    // 批量保存更新产量
                    super.doSaveBatchYieldTrendData(yieldList);
                }
            }
        }
    }

}
