package org.jeecg.modules.newWarning.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jtznyj.engineer.service.dataDiagnosticService.data.DrillState;
import jtznyj.engineer.service.dataDiagnosticService.data.DrillStateResult;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.newWarning.common.WarningCatch;
import org.jeecg.modules.newWarning.entity.TabQi;
import org.jeecg.modules.newWarning.mapper.TabQiMapper;
import org.jeecg.modules.newWarning.service.TabQiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Zhao RenJi
 */
@Service
@DS("chartDataSource")
@Slf4j
public class TabQiServiceImpl extends ServiceImpl<TabQiMapper, TabQi> implements TabQiService {


    @Resource
    private TabQiMapper tabQiMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public Page<TabQi> selectListPage(String tableName, QueryWrapper<TabQi> queryWrapper, Page<TabQi> page) {
        //redisUtil.del(tableName);
        return tabQiMapper.selectListPage(tableName, queryWrapper, page);
    }

    @Override
    public TabQi selectOne(String tableName, QueryWrapper<TabQi> queryWrapper) {
        return tabQiMapper.selectOne(tableName, queryWrapper);
    }

    @Override
    public TabQi selectOneOrcale(String tableName) {
        return tabQiMapper.selectOneOrcale(tableName);
    }

    @Override
    public void delRedisJh(String tableName) {
        redisUtil.del(tableName);
    }

    @Override
    public List<TabQi> selectList(String tableName, QueryWrapper<TabQi> queryWrapper) {
        return tabQiMapper.selectList(tableName, queryWrapper);
    }

    @Override
    public JSONObject getSmoothInterval(TabQi tabQi) {
        JSONObject resJson = new JSONObject();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        QueryWrapper<TabQi> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.apply(("TIME <= '" + sdf.format(tabQi.getTime()) + "'"));
        queryWrapper1.orderByDesc("TIME");
        //以当前点时间为起始点倒序查三条数据
        List<TabQi> page1 = tabQiMapper.selectListPOrcale(tabQi.getJhTableName(), queryWrapper1);
        TabQi one = new TabQi();
        TabQi two;
        TabQi three;
        if (page1.size() >= 3) {
            one = page1.get(0);
            two = page1.get(1);
            three = page1.get(2);
        } else {
            resJson.put("nowPointTime", one.getTime());
            resJson.put("nowPointWoh", one.getWoh());
            resJson.put("isStartMonitor", false);
            return resJson;
        }
        DrillStateResult drillingStatus = judgeWorkingCondition(two, one);
        boolean isCatchData = redisUtil.hasKey(tabQi.getJhTableName());
        WarningCatch catchData = JSONObject.toJavaObject(JSONObject.parseObject(JSON.toJSONString(redisUtil.get(tabQi.getJhTableName()))), WarningCatch.class);
        //判断当前点如果未钻进则删除缓存数据
        if (drillingStatus.state.value() == 1 || drillingStatus.state.value() == 2) {
            JSONObject ress = new JSONObject();
            Boolean aBoolean = CirculateDrillingCal(tabQi, one, drillingStatus);
            if (aBoolean) {
                ress.put("nowPointTime", one.getTime());
                ress.put("nowPointWoh", one.getWoh());
                ress.put("nowHkh", one.getHkh());
                ress.put("nowBitdepth", one.getBitdepth());
                ress.put("nowWholeWorking", drillingStatus.state.name());
                ress.put("isStartMonitor", true);
                return ress;
            }
            ress.put("isMax", false);
            ress.put("message", "当前点工况钻进");
            ress.put("isStartMonitor", false);
            if (isCatchData) {
                redisUtil.del(tabQi.getJhTableName());
            }
            return ress;
        }
        if (one.getBitdepth() <= tabQi.getBitdepth()) {
            JSONObject ress = new JSONObject();
            ress.put("isMax", false);
            ress.put("message", "钻头位置<=" + tabQi.getBitdepth());
            ress.put("isStartMonitor", false);
            if (isCatchData) {
                redisUtil.del(tabQi.getJhTableName());
            }
            return ress;
        }
        tabQi.setHkh(one.getHkh());
        tabQi.setWoh(one.getWoh());
        Object o = redisUtil.get(tabQi.getJhTableName());
        //根据表名获取缓存中存放的最新的正常柱以及钻井状态数据
        /**
         *判断当前点工况 4;起钻 2：下钻
         **/

        // DrillStateResult drillingStatus2 = judgeWorkingCondition(three, two);
        resJson.put("nowCondition", drillingStatus.state.name());
        resJson.put("nowPointTime", one.getTime());
        resJson.put("nowPointWoh", one.getWoh());
        resJson.put("nowHkh", one.getHkh());
        resJson.put("nowBitdepth", one.getBitdepth());
        resJson.put("nowWoh", one.getWoh());
        //判断当前点大钩位置趋势
        // Integer trend = judgeHookTrend(one, two);
        //缓存中是否有该井的缓存状态数据，以此判断起下钻开始点位
        BigDecimal oneBig = BigDecimal.valueOf(one.getHkh());
        //大钩位置变化幅度阈值
        int range = oneBig.subtract(BigDecimal.valueOf(two.getHkh())).abs().compareTo(BigDecimal.valueOf(tabQi.getHkhRang()));
        //当缓存数据为空时判断当前点工况是否为起下钻工况，如果是则将该点作为起点数据
        if (!isCatchData) {
            if (drillingStatus.state.value() == 4 || drillingStatus.state.value() == 8) {
                //判断大钩位置：1：上升 -1:下降 0:不变
                WarningCatch warningCatch = new WarningCatch();
                List<TabQi> list = new ArrayList<>();
                list.add(one);
                //记录起点位置
                warningCatch.setStartTime(one.getTime());
                warningCatch.setNormaNum(0);
                warningCatch.setRecordDataStatus(0);
                warningCatch.setNormalList(list);
                redisUtil.set(tabQi.getJhTableName(), warningCatch);
                resJson.put("第一柱开始", one.getTime());
            }
            resJson.put("isStartMonitor", false);
        } else {
            Integer recordDataStatus = catchData.getRecordDataStatus();
            Integer normaNum = catchData.getNormaNum();
            List<TabQi> normalList = catchData.getNormalList();
//            System.out.println("缓存的柱数据:"+normalList);
            //判断是否开始记录正常柱数据
            if (recordDataStatus == 0) {//第一柱数据
                if (drillingStatus.state.value() == 4 || drillingStatus.state.value() == 8) {
                    normalList.add(one);
                    resJson.put("第一柱添加中", one.getTime());
                } else if (drillingStatus.state.value() == 16 || drillingStatus.state.value() == 20 || drillingStatus.state.value() == 64) {
                    normaNum++;
                    catchData.setRecordDataStatus(1);
                    catchData.setNormaNum(normaNum);
                    normalList = new ArrayList<>();
                    resJson.put("第一柱结束", one.getTime());
                }
                resJson.put("isStartMonitor", false);
                catchData.setNormalList(normalList);
                redisUtil.set(tabQi.getJhTableName(), catchData);
            } else if (recordDataStatus == 1) {//第二柱数据
                resJson.put("isStartMonitor", false);
                if (drillingStatus.state.value() == 4 || drillingStatus.state.value() == 8) {
//                    if (range >= 0) {
                    normalList.add(one);
                    catchData.setNormalList(normalList);
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                    catchData.setRecordDataStatus(2);
                    resJson.put("第二柱添加开始", one.getTime());
                    resJson.put("正常柱数据", normalList);
//                    } else {
//                        resJson.put("第二柱", "大钩变化幅度小于1米");
//                        resJson.put("状态", drillingStatus.state.name());
//                    }
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                }
            } else if (recordDataStatus == 2) {//第二柱添加中
                resJson.put("isStartMonitor", false);
                if (drillingStatus.state.value() == 4 || drillingStatus.state.value() == 8) {
//                    if (range >= 0) {
                    normalList.add(one);
                    catchData.setNormalList(normalList);
                    if (normalList.size() > 4) {
                        catchData.setStatus(drillingStatus.state.value());
                    }
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                    resJson.put("第二柱添加中", one.getTime());
                    resJson.put("正常柱数据", normalList);
//                    } else {
//                        resJson.put("第二柱", "大钩变化幅度小于" + tabQi.getHkhRang() + "米");
//                        resJson.put("状态", drillingStatus.state.name());
//                    }
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                } else if (drillingStatus.state.value() == 16 || drillingStatus.state.value() == 20 || drillingStatus.state.value() == 64) {
//                    if (range >= 0) {
                    catchData.setStartTime(normalList.get(0).getTime());
                    List<TabQi> newlist = new ArrayList<>();
                    catchData.setNowList(newlist);
                    catchData.setRecordDataStatus(3);
                    catchData.setNowIsNormal(true);
                    if(normalList.size()<=4){
                        catchData.setNormalList(new ArrayList<TabQi>());
                        catchData.setRecordDataStatus(1);
                        System.out.println("柱数量小于4个");
                        resJson.put("isStartMonitor", false);
                        redisUtil.set(tabQi.getJhTableName(), catchData);
                        return resJson;
                    }
                    catchData.setEmptyWoh(one.getWoh());
                    catchData.setNotEmptyWoh(catchData.getNormalList().get(2).getWoh());
                    Double mostWoh = getNormalWoh(normalList, catchData.getStatus());
                    catchData.setMostWoh(mostWoh);
                    resJson.put("正常柱数据", catchData.getNormalList());
                    resJson.put("第二柱结束", one.getTime());
//                    } else {
//                        resJson.put("第二柱", "当前点变化小于" + tabQi.getHkhRang() + "米");
//                    }
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                }
            } else if (recordDataStatus == 3) {
                //监测预警数据
                List<TabQi> nowList = catchData.getNowList();
                //判断当前点工况是否未起下钻工况
                if (drillingStatus.state.value() == 4 || drillingStatus.state.value() == 8) {
                    int i = BigDecimal.valueOf(one.getWoh()).compareTo(BigDecimal.valueOf(catchData.getEmptyWoh()).multiply(BigDecimal.valueOf(1.5)));
                    if ( i >= 0) {
                        nowList.add(one);
                        catchData.setNowList(nowList);
                        WarningCatch calculation = calculation(catchData.getMostWoh(), catchData.getStatus(), drillingStatus.state.value(),
                                one, two, catchData.getNormaNum(), tabQi.getColumnWeight(), tabQi.getWarningValue(), catchData);
                        //log.info("预警监测计算:当前柱数据:{},/tr 上一柱数据:{}",nowList,catchData.getNormalList());
                        Boolean isNormal = calculation.getIsNormal();
                        if (!catchData.getNowIsNormal()) {
                            catchData.setNowIsNormal(isNormal);
                        }
                        resJson.put("isStartMonitor", true);
                        catchData.setRecordDataStatus(4);
                        resJson.put("nowPointTimes", catchData.getNormalList().get(0).getTime() + "~" +
                                catchData.getNormalList().get(catchData.getNormalList().size() - 1).getTime());
                        resJson.put("nowStart", catchData.getNormalList().get(0).getTime());
                        resJson.put("nowEnd", catchData.getNormalList().get(catchData.getNormalList().size() - 1).getTime());

                        //整体工况
                        resJson.put("nowWholeWorking", catchData.getStatus());
                        //当前柱状态
                        resJson.put("nowColumnState", catchData.getNowIsNormal());
                        //正常点钩载最值
                        resJson.put("frontColumn", catchData.getMostWoh());
                        //正常柱与最新点间隔柱数量
                        resJson.put("normaNum", catchData.getNormaNum());
                        //当前点是否正常
                        resJson.put("isNormal", isNormal);
                        resJson.put("nowTime", one.getTime());
                    } else {
                        resJson.put("isStartMonitor", false);
                        resJson.put("预警监测柱", "当前点处于空钩载不计算" + tabQi.getHkhRang() + "米");
                    }
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                } else {
                    resJson.put("isStartMonitor", false);
                }
            } else if (recordDataStatus == 4) {
                //监测预警数据添加中
                List<TabQi> nowList = catchData.getNowList();
                //判断当前点工况是否未起下钻工况
                if (drillingStatus.state.value() == 4 || drillingStatus.state.value() == 8) {
                    int i = BigDecimal.valueOf(one.getWoh()).compareTo(BigDecimal.valueOf(catchData.getEmptyWoh()).multiply(BigDecimal.valueOf(1.5)));
                    if (i >= 0) {
                        System.out.println("预警监测中");
                        resJson.put("isStartMonitor", true);
                        nowList.add(one);
                        catchData.setNowList(nowList);
                        WarningCatch calculation = calculation(catchData.getMostWoh(), catchData.getStatus(), drillingStatus.state.value(),
                                one, two, catchData.getNormaNum(), tabQi.getColumnWeight(), tabQi.getWarningValue(), catchData);
                        Boolean isNormal = calculation.getIsNormal();
                        //log.info("预警监测计算:当前柱数据:{},/tr 上一柱数据:{}",nowList,catchData.getNormalList());
                        if (!catchData.getNowIsNormal()) {
                            catchData.setNowIsNormal(isNormal);
                        }
                        //前一柱时间区间
                        resJson.put("nowPointTimes", catchData.getNormalList().get(0).getTime() + "~" +
                                catchData.getNormalList().get(catchData.getNormalList().size() - 1).getTime());
                        resJson.put("nowStart", catchData.getNormalList().get(0).getTime());
                        resJson.put("nowEnd", catchData.getNormalList().get(catchData.getNormalList().size() - 1).getTime());

                        //整体工况
                        resJson.put("nowWholeWorking", catchData.getStatus());
                        //当前柱状态
                        resJson.put("nowColumnState", catchData.getNowIsNormal());
                        //正常点钩载最值
                        resJson.put("frontColumn", catchData.getMostWoh());
                        //正常柱与最新点间隔柱数量
                        resJson.put("normaNum", catchData.getNormaNum());
                        //当前点是否正常
                        resJson.put("isNormal", isNormal);
                        resJson.put("nowTime", one.getTime());

                    } else {
                        resJson.put("isStartMonitor", false);
                        resJson.put("当前点处于空钩载不计算", "");
                    }
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                } else if (drillingStatus.state.value() == 16 || drillingStatus.state.value() == 20 || drillingStatus.state.value() == 64) {
                    long l = timeDifference(catchData.getNowList().get(catchData.getNowList().size() - 1).getTime(), one.getTime());
                    resJson.put("isStartMonitor", false);
                    if (l > 10 * 60) {
                        redisUtil.del(tabQi.getJhTableName());
                    }
                    if (range >= 0) {
                        if (catchData.getNowList().size() > 3) {
                            if (catchData.getNowIsNormal()) {
                                catchData.setNormalList(catchData.getNowList());
                                // System.out.println("数据:"+catchData.getNowList());
                                Double mostWoh = getNormalWoh(catchData.getNowList(), catchData.getStatus());
                                catchData.setMostWoh(mostWoh);
                                catchData.setNormaNum(1);
                            } else {
                                normaNum++;
                                catchData.setNormaNum(normaNum);
                            }
                        }
                        resJson.put("当前柱是否正常柱", catchData.getNowIsNormal());
                        resJson.put("监测预警数据数据", catchData.getNowList());
                        resJson.put("监测预警数据结束", one.getTime());
                        List<TabQi> newwlist = new ArrayList<>();
                        catchData.setRecordDataStatus(3);
                        catchData.setNowList(newwlist);
                        catchData.setNormaNum(normaNum);
                    } else {
                        resJson.put("预警监测", "当前点大钩位置变化小于" + tabQi.getHkhRang() + "米");
                    }
                    redisUtil.set(tabQi.getJhTableName(), catchData);
                } else {
                    resJson.put("isStartMonitor", false);
                }
            }
        }
        //System.out.println(resJson);
        return resJson;
    }

    /**
     * 循环下钻工况点计算
     *
     * @param tabQi
     */
    public Boolean CirculateDrillingCal(TabQi tabQi, TabQi nowPoint, DrillStateResult nowState) {
        Boolean res = false;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(nowPoint.getTime());
        calendar.add(Calendar.MILLISECOND, 60);
        Date time = calendar.getTime();
        //查询当前点前一分钟的点
        QueryWrapper<TabQi> wrapper = new QueryWrapper<TabQi>();
        wrapper.apply(("TIME <= '" + sdf.format(time) + "'"));
        TabQi tabQi1 = tabQiMapper.selectWOneOrcale(tabQi.getJhTableName(), wrapper);
        QueryWrapper<TabQi> wrapper1 = new QueryWrapper<TabQi>();
        wrapper.apply(("TIME <= '" + sdf.format(tabQi1.getTime()) + "'"));
        List<TabQi> page1 = tabQiMapper.selectListPOrcale(tabQi.getJhTableName(), wrapper1);
        TabQi perPoint = page1.get(0);
        DrillStateResult drillStateResult = judgeWorkingCondition(page1.get(1), page1.get(0));
        int value = drillStateResult.state.value();
        if (nowState.state.value() == value) {
            BigDecimal pumpB1 = BigDecimal.valueOf(nowPoint.getPump1());
            BigDecimal pumpB2 = BigDecimal.valueOf(nowPoint.getPump2());
            BigDecimal pumpB3 = BigDecimal.valueOf(nowPoint.getPump3());
            //当前点泵冲
            Double nowPointSumPump = calSumPump(pumpB1, pumpB2, pumpB3);
            //一分钟前点的泵冲
            Double perSumPump = calSumPump(BigDecimal.valueOf(perPoint.getPump1()), BigDecimal.valueOf(perPoint.getPump2()), BigDecimal.valueOf(perPoint.getPump3()));
            BigDecimal pumpSubtract = BigDecimal.valueOf(nowPointSumPump).subtract(BigDecimal.valueOf(perSumPump));
            BigDecimal divide = pumpSubtract.divide(BigDecimal.valueOf(perSumPump),BigDecimal.ROUND_CEILING);
            int i = divide.compareTo(BigDecimal.valueOf(tabQi.getLoopDrillingpump()));
            // log.info("井号:"+nowPoint.getJh()+"当前点泵冲"+nowPointSumPump+";时间:"+sdf.format(nowPoint.getTime()));
            //log.info("当前点泵冲"+pumpSubtract+";时间:"+sdf.format( perPoint.getTime()));
            System.out.println("当前点泵冲"+nowPointSumPump);
            System.out.println("上一点泵冲"+perSumPump);
            System.out.println("泵冲差值"+pumpSubtract);
            System.out.println("泵冲除值"+divide);
            if (1 >= 0) {
                res = false;
            } else {
                BigDecimal nowSppB = BigDecimal.valueOf(nowPoint.getSpp());
                BigDecimal perSppB = BigDecimal.valueOf(perPoint.getSpp());
                BigDecimal sppSub = nowSppB.subtract(perSppB);
                BigDecimal divide1 = sppSub.divide(perSppB,BigDecimal.ROUND_CEILING);
                int i1 = divide1.compareTo(BigDecimal.valueOf(tabQi.getLoopDrillingSpp()));
                if (i1 > 0) {
                    res = true;
                } else {
                    res = false;
                }
            }
        } else {
            res = false;
        }
        return res;
    }

    /**
     * 计算总泵冲
     *
     * @param pump1 一号泵冲
     * @param pump2 二号泵冲
     * @param pump3 三号泵冲
     * @return
     */
    public Double calSumPump(BigDecimal pumpB1, BigDecimal pumpB2, BigDecimal pumpB3) {
        BigDecimal zero = BigDecimal.valueOf(0);
        BigDecimal res = BigDecimal.valueOf(0);
        //判断三个泵冲是否有参数值;负值为无参数
        if (pumpB1.compareTo(zero) >= 0 && pumpB2.compareTo(zero) >= 0 && pumpB3.compareTo(zero) >= 0) {
            res = pumpB1.add(pumpB2).add(pumpB3);
        } else {
            if (pumpB1.compareTo(zero) >= 0 && pumpB2.compareTo(zero) >= 0) {
                res = pumpB1.add(pumpB2);
            } else if (pumpB1.compareTo(zero) >= 0 && pumpB3.compareTo(zero) >= 0) {
                res = pumpB1.add(pumpB3);
            } else if (pumpB2.compareTo(zero) >= 0 && pumpB3.compareTo(zero) >= 0) {
                res = pumpB2.add(pumpB2);
            } else {
                if (pumpB1.compareTo(zero) >= 0) {
                    res = pumpB1;
                } else if (pumpB2.compareTo(zero) >= 0) {
                    res = pumpB2;
                } else if (pumpB3.compareTo(zero) >= 0) {
                    res = pumpB3;
                }
            }
        }
        Double sumPump = res.doubleValue();
        return sumPump;
    }

    /**
     * 当前点计算对比是否异常
     *
     * @param normalWoh     正常点钩载最值
     * @param nowPointType  当前总体工况
     * @param wellType      当前点工况
     * @param nowPoint      当前点
     * @param previousPoint 上一点
     * @param normaNum      正常柱距离当前点柱数量
     * @param rodWeight     柱杆重
     * @param value         异常对比值
     * @param warningCatch  缓存数据
     */
    private WarningCatch calculation(Double normalWoh, Integer nowPointType,
                                     Integer wellType, TabQi nowPoint,
                                     TabQi previousPoint, Integer normaNum,
                                     Double rodWeight, Double value, WarningCatch warningCatch) {

        if (nowPointType.equals(wellType)) {
            if (nowPointType == 4) {//起钻
                BigDecimal subtract = BigDecimal.valueOf(nowPoint.getWoh()).subtract(BigDecimal.valueOf(normalWoh));
                BigDecimal add = subtract.add(BigDecimal.valueOf(rodWeight));
                System.out.println("起钻计算公式:"+"当前点钩载"+nowPoint.getWoh()+"-"+"钩载最值:"+normalWoh+"+"+"杆重:"+rodWeight+"="+add);
                System.out.println("对比结果:"+"和值:"+"报警阈值:"+add.compareTo(BigDecimal.valueOf(value)));
                //log.info("起钻计算公式:"+"当前点钩载"+nowPoint.getWoh()+"-"+"钩载最值:"+normalWoh+"+"+"杆重:"+rodWeight+"="+add);
                //log.info("对比结果:"+"和值:"+"报警阈值:"+add.compareTo(BigDecimal.valueOf(value)));
                int i = add.compareTo(BigDecimal.valueOf(value));
                if (i > 0) {
                    warningCatch.setIsNormal(false);
                } else {
                    warningCatch.setIsNormal(true);
                }
            } else {//下钻
                BigDecimal subtract = BigDecimal.valueOf(normalWoh).subtract(BigDecimal.valueOf(nowPoint.getWoh()).subtract(BigDecimal.valueOf(rodWeight)));
                int i = subtract.compareTo(BigDecimal.valueOf(value));
                System.out.println("下钻计算公式:"+"钩载最值:"+normalWoh+"-"+"当前点钩载"+nowPoint.getWoh()+"-"+"杆重:"+rodWeight+"="+subtract);
                System.out.println("对比结果:"+"差值:"+"报警阈值:"+subtract.compareTo(BigDecimal.valueOf(value)));
                // log.info("下钻计算公式:"+"钩载最值:"+normalWoh+"-"+"当前点钩载"+nowPoint.getWoh()+"-"+"杆重:"+rodWeight+"="+subtract);
                //log.info("对比结果:"+"差值:"+"报警阈值:"+subtract.compareTo(BigDecimal.valueOf(value)));
                if (i > 0) {
                    warningCatch.setIsNormal(false);
                } else {
                    warningCatch.setIsNormal(true);
                }
            }
            if (warningCatch.getOutlier() != null) {
                warningCatch.setOutlier(new TabQi());
            }
        } else {
            TabQi outlierModel = warningCatch.getOutlier();
//            System.out.println(outlierModel);
            if (outlierModel == null) {
                warningCatch.setIsNormal(true);
                return warningCatch;
            }
            //缓存数据中突出突变点判断是否有,如果有则计算当前点与异常点大钩位置是大于阈值
            if (outlierModel != null && outlierModel.getHkh() != null) {
                int hkhSub = BigDecimal.valueOf(nowPoint.getHkh()).subtract(BigDecimal.valueOf(outlierModel.getHkh())).abs().compareTo(BigDecimal.valueOf(3));
//                System.out.println(hkhSub);
                if (hkhSub >= 0) {
                    warningCatch = judgeOutlierPoint(warningCatch, wellType, outlierModel, nowPoint, normalWoh, rodWeight, value, normaNum);
                } else {
                    warningCatch.setIsNormal(true);
                }
            } else {
                warningCatch.setOutlier(previousPoint);
                int hkhSub = BigDecimal.valueOf(nowPoint.getHkh()).subtract(BigDecimal.valueOf(previousPoint.getHkh())).abs().compareTo(BigDecimal.valueOf(3));
//                System.out.println(hkhSub);
                if (hkhSub >= 0) {
                    warningCatch = judgeOutlierPoint(warningCatch, wellType, previousPoint, nowPoint, normalWoh, rodWeight, value, normaNum);
                } else {
                    warningCatch.setIsNormal(true);
                }
            }

        }
        return warningCatch;
    }

    /**
     * 突变点计算
     *
     * @param warningCatch
     * @param wellType
     * @param previousPoint
     * @param nowPoint
     * @param normalWoh
     * @param rodWeight
     * @param value
     * @param normaNum
     * @return
     */
    private WarningCatch judgeOutlierPoint(WarningCatch warningCatch, Integer wellType, TabQi previousPoint, TabQi nowPoint, Double normalWoh,
                                           Double rodWeight, Double value, Integer normaNum) {
        //摩阻
        BigDecimal Friction = BigDecimal.valueOf(previousPoint.getWoh()).
                subtract(BigDecimal.valueOf(nowPoint.getWoh()));
        //杆重
        BigDecimal rodWeightSum = BigDecimal.valueOf(rodWeight).multiply(BigDecimal.valueOf(normaNum));
        if (wellType == 4) {//起钻
            BigDecimal res = BigDecimal.valueOf(warningCatch.getMostWoh()).
                    add(rodWeightSum).
                    subtract(Friction).subtract(BigDecimal.valueOf(value));
            int i = BigDecimal.valueOf(nowPoint.getWob()).compareTo(res);
            if (1 >= 0) {
                warningCatch.setIsNormal(false);
            } else {
                warningCatch.setIsNormal(true);
            }
        } else {//下钻
            BigDecimal res = BigDecimal.valueOf(warningCatch.getMostWoh()).
                    subtract(rodWeightSum).
                    subtract(Friction).subtract(BigDecimal.valueOf(value));
            int i = BigDecimal.valueOf(nowPoint.getWob()).compareTo(res);
            if (1 >= 0) {
                warningCatch.setIsNormal(false);
            } else {
                warningCatch.setIsNormal(true);
            }
        }
        return warningCatch;
    }


    /**
     * 获取正常柱钩载最值
     *
     * @param list
     * @param Type
     * @return
     */
    private Double getNormalWoh(List<TabQi> list, Integer Type) {
        //默认移除第一个点何最后一个点数据,根据工况取出钩载最大/最小值
        System.out.println("获取的钩载最值的数组"+list);
        double res = 0.00;
        try {
            if (Type == 4) {//起钻获取最大值
                list.remove(list.size() - 1);

                res = list.stream().mapToDouble(TabQi::getWoh).max().getAsDouble();
            } else {
                list.remove(0);
                res = list.stream().mapToDouble(TabQi::getWoh).min().getAsDouble();
            }

        }catch (Exception e){
            log.error(e.getMessage(),e);
            e.printStackTrace();
        }
        System.out.println("获取的钩载最值的结果值"+res);
        return res;
    }


    //计算两个时间差
    @Override
    public long timeDifference(Date startTime, Date endTime) {
        long between = (endTime.getTime() - startTime.getTime()) / 1000;
        long day = between / (24 * 3600);
        long hour = between % (24 * 3600) / 3600;
        long minute = between % 3600 / 60;
        long second = between % 60 / 60;
        return between;
    }

    /**
     * float转double
     *
     * @param ConvertData
     * @return
     */
    private Double floatToDouble(Float ConvertData) {
        BigDecimal b = new BigDecimal(String.valueOf(ConvertData));
        return b.doubleValue();
    }


    /**
     * 判断当前点趋势
     */
    public Integer judgeHookTrend(TabQi nowModel, TabQi previousModel) {
        BigDecimal nowBig = BigDecimal.valueOf(nowModel.getHkh());
        int trend = nowBig.compareTo(BigDecimal.valueOf(previousModel.getHkh()));
        return trend;
    }


    /**
     * 判断工况
     */
    public DrillStateResult judgeWorkingCondition(TabQi previous, TabQi nowModel) {
        //当前点状态:1起钻 2下钻 3钻进 4划眼 5倒划眼 6停工 7下套管
        DrillStateResult drillStateResult = new DrillStateResult();
        DrillState curDrillState = null;
        //立管压力是否等于0
        int sppIsZero = BigDecimal.valueOf(nowModel.getSpp()).compareTo(BigDecimal.valueOf(0));
        //判断当前点钻压是否等于0如果等于0则继续往下走判断
        BigDecimal nowBitdepth = BigDecimal.valueOf(new BigDecimal(String.valueOf(nowModel.getBitdepth())).doubleValue());
        BigDecimal nowDepth = BigDecimal.valueOf(new BigDecimal(String.valueOf(nowModel.getDepth())).doubleValue());
        BigDecimal nowWob = BigDecimal.valueOf(new BigDecimal(String.valueOf(nowModel.getWob())).doubleValue());
        //钻压
        int i4 = nowWob.compareTo(BigDecimal.valueOf(0));
        //循环:井深-钻头位置>1 钻压>0
        //钻进:井深-钻头位置<=1 钻压>=0
        //井深-钻头位置 是否大于1
        int i2 = BigDecimal.valueOf(nowModel.getDepth()).subtract(BigDecimal.valueOf(nowModel.getBitdepth())).compareTo(BigDecimal.valueOf(1));
        BigDecimal pimp1i = BigDecimal.valueOf(nowModel.getPump1());
        BigDecimal pimp2i = BigDecimal.valueOf(nowModel.getPump2());
        BigDecimal pimp3i = BigDecimal.valueOf(nowModel.getPump3());
        Double sumPump = calSumPump(pimp1i, pimp2i, pimp3i);
        if (i2 > 0 && i4 > 0) {
            curDrillState = DrillState.Circulate;
            drillStateResult.state = curDrillState;
            return drillStateResult;
        }
        if (i2 <= 0 && sumPump > 0) {
            curDrillState = DrillState.Drilling;
            drillStateResult.state = curDrillState;
            return drillStateResult;
        }

        BigDecimal nowhkh = BigDecimal.valueOf(new BigDecimal(String.valueOf(nowModel.getHkh())).doubleValue());
        BigDecimal previoushkh = BigDecimal.valueOf(new BigDecimal(String.valueOf(previous.getHkh())).doubleValue());
        //比较当前点与上一个点大钩位置
        int i = nowhkh.compareTo(previoushkh);
        //如果i不等于则说明大钩位置发生了变化
        if (i != 0) {
            BigDecimal previousBitdepth = BigDecimal.valueOf(new BigDecimal(String.valueOf(previous.getBitdepth())).doubleValue());
            //比较当前点钻头位置
            int i1 = nowBitdepth.compareTo(previousBitdepth);
            if (i1 == 1) {//钻头位置增大(包含下钻工况)
                //判断比较当前点立管压力
                if (sppIsZero == 0) {//下钻
                    curDrillState = DrillState.DrillDown;
                } else if (sppIsZero > 0) {
                    curDrillState = DrillState.ClearHole;
                    // status=4;//划眼
                } else {
                    if (sumPump == 0) {
                        curDrillState = DrillState.DrillDown;
                    } else {
                        curDrillState = DrillState.ClearHole;
                    }
                }
            } else if (i1 < 0) {//钻头位置减小(包含起钻工况)
                if (sppIsZero == 0) {//起钻
                    curDrillState = DrillState.Trip;
                } else if (sppIsZero > 0) {
                    curDrillState = DrillState.ClearHole;
                    //status=5;//倒划眼
                } else {
                    if (sumPump == 0) {
                        curDrillState = DrillState.DrillDown;
                    } else {
                        curDrillState = DrillState.ClearHole;
                    }
                }
            } else if (i1 == 0) {//钻头位置不变，下套管
                curDrillState = DrillState.Casing;
            }
        } else {//停工
            curDrillState = DrillState.Stop;
        }
        drillStateResult.state = curDrillState;
        return drillStateResult;
    }
}
