package jtznyj.engineer.service.dataDiagnosticService;

import cn.hutool.core.date.DateUtil;
import jtznyj.engineer.service.dataDiagnosticService.data.AlarmPoint;
import jtznyj.engineer.service.dataDiagnosticService.data.DrillState;
import jtznyj.engineer.service.dataDiagnosticService.data.TrendTypeParam;
import jtznyj.engineer.service.winform.data.mcp_.SecValue;
import lombok.extern.slf4j.Slf4j;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;

/**
 * 单井趋势--递增诊断
 */
@Slf4j
public class WellUpTrendDataDiagnostic extends WellTrendDataDiagnostic {
    /**
     * 单一模型诊断分析
     *
     * @param record
     * @param currentPumpState
     * @param drillState
     * @param lastPumpRunTime
     * @param lastPumpStopTime
     * @return
     */
    @Override
    protected DataDiagnosticAnalyzeResult internalAnalyse(Hashtable record, boolean currentPumpState, DrillState drillState, Date lastPumpRunTime, Date lastPumpStopTime) {
        DataDiagnosticAnalyzeResult analyseResult = this.beforeAnalyse(record, currentPumpState, drillState, lastPumpRunTime, lastPumpStopTime);
        if (!analyseResult.result) {
            //提前退出--不报警
            analyseResult.result = false;
            return analyseResult;
        }

        analyseResult.result = false;
//        System.out.println(this.param._name);
        int iCount = this.trendDataList.size();
        if (iCount < 2) {
            return analyseResult;
        }

        int upTotalCount = 0;
        double upTotalSec = 0.0;
        ArrayList<SecValue> listUpSecValues = new ArrayList<SecValue>();
        double upStepValue = 0.0;
        TimeValuePair<Hashtable> currentTimeValue = null;
        TimeValuePair<Hashtable> prevTimeValue = null;

        //第一个时间点数据值
        TimeValuePair<Hashtable> tvStep = this.trendDataList.get(0);
        double stepCompareUpDownValue = 0.0;
        boolean bCmpResult = false;
        SecValue sv;

        //==============================================================================================
        //趋势分析--上升或者下降--begin
        for (int i = 1; i < iCount; i++) {
            currentTimeValue = this.trendDataList.get(i);
            prevTimeValue = this.trendDataList.get(i - 1);
            //两个时间点的时间间隔（秒）
            int totalSeconds = (int) Math.abs(((currentTimeValue.getDateTime().getTime() - prevTimeValue.getDateTime().getTime()) / 1000));
            stepCompareUpDownValue = currentTimeValue.getValue() - tvStep.getValue();
            //int prevUpCount = upTotalCount;
            //int prevDownCount = downTotalCount;
            //判断上升还是下降
            if (stepCompareUpDownValue > 0.0) {
                //上升
                upTotalSec += totalSeconds;
                upTotalCount++;

                upStepValue += currentTimeValue.getValue() - prevTimeValue.getValue();
                this.UpdateLastSecValues(listUpSecValues, new SecValue(upTotalSec, upStepValue, tvStep.getDateTime(), currentTimeValue.getDateTime()));

                sv = listUpSecValues.get(listUpSecValues.size() - 1);
                if (this.param._trendTypeParam == TrendTypeParam.TT_TOTALNUM) {
                    bCmpResult = (stepCompareUpDownValue > this.param._totalNum);
                } else if (this.param._beginValue <= currentTimeValue.getValue() && currentTimeValue.getValue() <= this.param._endValue) {
                    bCmpResult = (currentTimeValue.getValue() > tvStep.getValue() * this.param._mul);
                }
                //判断是否满足退出条件
                boolean stepGt = tvStep.getValue() > this.param._continueValue;
                boolean svGt = sv._value > this.param._continueValue;
                if (bCmpResult && sv._sec > this.param._continuedTime && stepGt && svGt) {
                    break;
                }
            } else {
                //没有上升，重置上升变量
                upStepValue = 0.0;
                upTotalCount = 0;
                upTotalSec = 0.0;
            }

//            //下降
//            if (prevDownCount != downTotalCount) {
//                downStepValue += currentTimeValue._value - prevTimeValue._value;
//                listDownSecValues = this.UpdateLastSecValues(listDownSecValues, new SecValue(downTotalSec, downStepValue, tvStep._dateTime, currentTimeValue._dateTime));
//                listUpSecValues.clear();
//            } else {
//                //没有下降，重置下降变量
//                downStepValue = 0.0;
//                downTotalCount = 0;
//                downTotalSec = 0.0;
//            }
        }

        //================================================
        //趋势分析
        if (this.trendDataList.size() > 0) {
            int last = this.trendDataList.size() - 1;
            this._secondState.SetTrend(this.trendDataList.get(0).getDateTime(),
                    this.trendDataList.get(last).getDateTime(), this.trendDataList.get(0).getValue(), this.trendDataList.get(last).getValue());
        }

        //上升趋势
        if (this.trendDataList.size() >= 1) {
            if (listUpSecValues.size() > 0) {
                int last = listUpSecValues.size() - 1;
                sv = listUpSecValues.get(last);
                if (this.param._trendTypeParam == TrendTypeParam.TT_TOTALNUM) {
                    bCmpResult = (stepCompareUpDownValue > this.param._totalNum);
                } else if (this.param._beginValue <= currentTimeValue.getValue() && currentTimeValue.getValue() <= this.param._endValue) {
                    bCmpResult = (currentTimeValue.getValue() > tvStep.getValue() * this.param._mul);
                }
                if (bCmpResult == true) {
                    System.out.println(11);
                }
                boolean stepGt = tvStep.getValue() > this.param._continueValue;
                boolean svGt = sv._value > this.param._continueValue;
                if (bCmpResult && sv._sec > this.param._continuedTime && stepGt && svGt) {
                    AlarmPoint description = new AlarmPoint();
                    description.name = this.param._name;
                    description.field = this.param._realField;
                    description.alarmType = this.param._analyseType.toString();
                    //description._dtStart = tvStep.getDateTime();
                    description.alarmDate = new Date(currentTimeValue.getDateTime().getTime()); //sv._endTime;
                    //description._startValue = tvStep.getValue();
                    description.value = currentTimeValue.getValue();
                    // 202211
                    DecimalFormat valueDf = new DecimalFormat("0.00");
                    String trendExplain = String.format(",从%s到%s，%s",
                            DateUtil.format(sv._startTime, "HH:mm:ss"), DateUtil.format(description.alarmDate, "HH:mm:ss"),
                            description.name + valueDf.format(Math.abs(sv._value)) + param._unit + "↗"
                                    + valueDf.format(description.value) + param._unit);
                    description.des = this.setDes("", description, stepCompareUpDownValue, trendExplain);
                    //description._startDepth = getWellDepth(tvStep.getData());

                    //description._startZtDepth = getDrillDepth(tvStep.getData());
                    description.depth = getWellDepth(currentTimeValue.getData());
                    description.ztDepth = getWellDepth(currentTimeValue.getData());
                    this._secondState.SetAlarm(true);
                    //description._secondState = (SecondState) this._secondState.Clone();
                    analyseResult.result = true;
                    analyseResult.percent = sv._sec / this.param._continuedTime;
                    analyseResult.description = description;
                    description.WarningCause = this.setWarningCause(description, stepCompareUpDownValue);
                    log.debug(" {}, 数据趋势upTrend,{}",
                            DataDiagnosticEngineer.packStackStr(Thread.currentThread().getStackTrace()),
                            description.WarningCause);
                    //analyseResult.resetAllParams = false;
                    return analyseResult;
                }
            }
        }
        //趋势分析--上升或者下降--end
        //==============================================================================================

        return analyseResult;
    }


    private String setDes(String jh, AlarmPoint description, double stepCompareUpDownValue, String trendExplain) {

        DecimalFormat decimalFormat = new DecimalFormat("###################.###########");
        DecimalFormat valueDf = new DecimalFormat("0.00");

        String des = "";
        des += "[" + this.jh + " " + description.name + "]";
        des += "\n";
        des += "时间: " + DateUtil.format(description.alarmDate, "yyyy-MM-dd HH:mm:ss");
        des += "\n";
        des += "深度段: " + description.depth;
        des += "\n";
        if (this.param._trendTypeParam == TrendTypeParam.TT_TOTALNUM) {
            //按总量
            des += "异常原因:符合上升异常趋势(总量:" + decimalFormat.format(this.param._totalNum)
                    + this.param._unit + ",当前值: " + valueDf.format(description.value) + this.param._unit + trendExplain + ").";
        } else {
            //按倍数
            des += "异常原因:符合上升异常趋势(倍数:" + decimalFormat.format(this.param._mul)
                    + "倍, 当前值:" + valueDf.format(description.value) + this.param._unit + ").";
        }
        return des;
    }

    private String setWarningCause(AlarmPoint description, double stepCompareUpDownValue) {

        DecimalFormat decimalFormat = new DecimalFormat("###################.###########");
        DecimalFormat valueDf = new DecimalFormat("0.00");

        if (this.param._trendTypeParam == TrendTypeParam.TT_TOTALNUM) {
            //按总量
            return "符合下降异常趋势(总量:" + decimalFormat.format(this.param._totalNum) + this.param._unit + ")";
        } else {
            //按倍数
            return "符合下降异常趋势(倍数:" + decimalFormat.format(this.param._mul) + "倍)";
        }

    }
}

