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 WellDownTrendDataDiagnostic 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;
        int iCount = this.trendDataList.size();
        if (iCount < 2) {
            return analyseResult;
        }

        int downTotalCount = 0;
        double downTotalSec = 0.0;
        ArrayList<SecValue> listDownSecValues = new ArrayList<SecValue>();
        double downStepValue = 0.0;
        TimeValuePair<Hashtable> currentTimeValue = null;
        TimeValuePair<Hashtable> prevTimeValue = null;

        //第一个时间点数据值
        TimeValuePair<Hashtable> tvStep = this.trendDataList.get(0);
        double stepCompareUpDownValue = 0.0;
        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();
            //判断上升还是下降
            if (stepCompareUpDownValue < 0.0) {
                //下降
                downTotalSec += totalSeconds;
                downTotalCount++;

                downStepValue += currentTimeValue.getValue() - prevTimeValue.getValue();
                this.UpdateLastSecValues(listDownSecValues, new SecValue(downTotalSec, downStepValue, tvStep.getDateTime(), currentTimeValue.getDateTime()));
                sv = listDownSecValues.get(listDownSecValues.size() - 1);
                //判断是否满足退出条件
                if (Math.abs(sv._value) > this.param._totalNum && Math.abs(stepCompareUpDownValue) > this.param._totalNum && sv._sec > this.param._continuedTime) {
                    break;
                }
            } 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 (listDownSecValues.size() > 0) {
                int last = listDownSecValues.size() - 1;
                sv = listDownSecValues.get(last);
//                boolean bCmpResult = false;
//                if (this.param._trendTypeParam == TrendTypeParam.TT_TOTALNUM) {
//                    bCmpResult = (stepCompareUpDownValue * -1.0> this.param._totalNum);
//                } else if (this.param._beginValue <= currentTimeValue.getValue() && currentTimeValue.getValue() <= this.param._endValue) {
//                    bCmpResult = (currentTimeValue.getValue() > tvStep.getValue() * this.param._mul * -1.0);
//                }
                //if (bCmpResult && sv._sec * -1.0 > this.param._continuedTime && tvStep.getValue() * -1.0 > this.param._continueValue && sv._value > this.param._continueValue) {
                if (Math.abs(sv._value) > this.param._totalNum && Math.abs(stepCompareUpDownValue) > this.param._totalNum && sv._sec > this.param._continuedTime) {
                    AlarmPoint description = new AlarmPoint();
                    description.name = this.param._name;
                    description.field = this.param._realField;
                    //description.alarmDate = tvStep.getDateTime();
                    description.alarmType = this.param._analyseType.toString();
                    description.alarmDate = new Date(currentTimeValue.getDateTime().getTime());//sv._endTime;
                    //description._startValue = tvStep.getValue();
                    description.value = currentTimeValue.getValue();
                    //description._startDepth = getWellDepth(tvStep.getData());
                    //description._startZtDepth = getDrillDepth(tvStep.getData());
                    description.depth = getWellDepth(currentTimeValue.getData());
                    description.ztDepth = getWellDepth(currentTimeValue.getData());
                    // 202211
                    DecimalFormat valueDf = new DecimalFormat("0.00");
                    double beginValue = Math.abs(sv._value);
                    if(Math.abs(sv._value) < description.value) {
                        beginValue = description.value + Math.abs(sv._value);
                    }
                    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(beginValue) + param._unit + "↘"
                                    + valueDf.format(description.value) + param._unit);
                    description.des = this.setDes("", description, stepCompareUpDownValue, trendExplain);
                    description.WarningCause = this.setWarningCause(description, stepCompareUpDownValue);
                    this._secondState.SetAlarm(true);
                    analyseResult.result = true;
                    analyseResult.description = description;
                    analyseResult.percent = sv._sec / this.param._continuedTime;
                    //analyseResult.resetAllParams = false;
                    log.debug(" {}, 数据趋势downTrend,位置{}，currentTimeValue {}",
                            DataDiagnosticEngineer.packStackStr(Thread.currentThread().getStackTrace()),
                            trendDataList.size(),
                            currentTimeValue.getDateTime().getTime());
                    log.debug(" {}, 结果: {}, 计算：{}",
                            DataDiagnosticEngineer.packStackStr(Thread.currentThread().getStackTrace()),
                            description.des,
                            String.format("Math.abs(sv._value) %s > this.param._totalNum %s && Math.abs(stepCompareUpDownValue) %s > this.param._totalNum %s && sv._sec %s > this.param._continuedTime %s",
                                    Math.abs(sv._value), this.param._totalNum, Math.abs(stepCompareUpDownValue), this.param._totalNum, sv._sec, this.param._continuedTime));
                    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) + ")";
        }

        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) + "倍).";
        }

    }
}
