using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
namespace RestApi
{

    public class CustomDateTimeConverter : IsoDateTimeConverter
    {
        public CustomDateTimeConverter()
        {
            DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; // 可覆盖默认ISO格式
        }
    }

    /// <summary>
    /// 最新的5分钟，轧机振动能量
    /// </summary>
    public class EnergyTrend
    {

        [DataMember]
        public double[] energyValues { get; set; }
        [DataMember]
        public double[] energyThreshold { get; set; }

        public static readonly int dataLenth = 1500;


        public EnergyTrend()
        {
            energyValues = new double[dataLenth];
            energyThreshold = new double[dataLenth];
        }
    }

    public class CZState
    {
        [DataMember]
        public bool[] values { get; set; }
        [DataMember]
        public string[] names { get; set; }

        public CZState()
        {
            values = new bool[2] { false, false };
            names = new string[2] { "CZ02", "CZ03" };
        }
        public void initData(bool[] values, string[] names)
        {
            this.values = values;
            this.names = names;
        }

    }

    public class RMVibData
    {
        [DataMember]
        public double[] vib_data { get; set; }

        public static readonly int dataLenth = 1024;//采样点数
        public RMVibData()
        {
            vib_data = new double[dataLenth];
        }


    }

    public class StandRMVibData
    {
        [DataMember]
        public RMVibData F1;
        [DataMember]
        public RMVibData F2;
        [DataMember]
        public RMVibData F3;
        [DataMember]
        public RMVibData F4;
        [DataMember]
        public RMVibData F5;
        [DataMember]
        public RMVibData F6;
        [DataMember]
        public int flag;

        //[JsonConverter(typeof(CustomDateTimeConverter))]
        //public DateTime nowTime { set; get; }


        public StandRMVibData()
        {
            F1 = new RMVibData();
            F2 = new RMVibData();
            F3 = new RMVibData();
            F4 = new RMVibData();
            F5 = new RMVibData();
            F6 = new RMVibData();
            flag = 0;
        }
        public StandRMVibData(RMVibData[] rmVibData)
        {
            if (rmVibData.Length != 6)
            {
                return;
            }
            F1 = rmVibData[0];
            F2 = rmVibData[1];
            F3 = rmVibData[2];
            F4 = rmVibData[3];
            F5 = rmVibData[4];
            F6 = rmVibData[5];
           // nowTime = DateTime.Now;
        }
        public bool BindData(RMVibData[] rmVibData)
        {
            if (rmVibData.Length != 6)
            {
                return false;
            }
            F1 = rmVibData[0];
            F2 = rmVibData[1];
            F3 = rmVibData[2];
            F4 = rmVibData[3];
            F5 = rmVibData[4];
            F6 = rmVibData[5];
           // nowTime = DateTime.Now;
            return true;
        }

        public RMVibData[] ToArray()
        {
            return new RMVibData[] { F1, F2, F3, F4, F5, F6 };
        }
    }

    public class RollMillEnergyTrend
    {
        public EnergyTrend F1 { set; get; }
        public EnergyTrend F2 { set; get; }
        public EnergyTrend F3 { set; get; }
        public EnergyTrend F4 { set; get; }
        public EnergyTrend F5 { set; get; }

        public EnergyTrend F6 { set; get; }

        public int startIndex { set; get; }


        public RollMillEnergyTrend()
        {
            F1 = new EnergyTrend();
            F2 = new EnergyTrend();
            F3 = new EnergyTrend();
            F4 = new EnergyTrend();
            F5 = new EnergyTrend();
            F6 = new EnergyTrend();
            startIndex = 0;
        }
        public void updateData(double[] energyValues, double[] energyThreshold)
        {
            F1.energyValues[startIndex] = energyValues[0];
            F2.energyValues[startIndex] = energyValues[1];
            F3.energyValues[startIndex] = energyValues[2];
            F4.energyValues[startIndex] = energyValues[3];
            F5.energyValues[startIndex] = energyValues[4];
            F6.energyValues[startIndex] = energyValues[5];

            F1.energyThreshold[startIndex] = energyThreshold[0];
            F2.energyThreshold[startIndex] = energyThreshold[1];
            F3.energyThreshold[startIndex] = energyThreshold[2];
            F4.energyThreshold[startIndex] = energyThreshold[3];
            F5.energyThreshold[startIndex] = energyThreshold[4];
            F6.energyThreshold[startIndex] = energyThreshold[5];
            startIndex++;
            startIndex = startIndex % EnergyTrend.dataLenth;
        }

    }
    public class BoxData
    {
        //最小的数据 包括点位名称，数据值，各数据点的报警水平，总体报警水平
        [DataMember]
        public string[] names { get; set; }

        [DataMember]
        public double[] values { get; set; }


        [DataMember]
        public int[] levels { get; set; }

        [DataMember]
        public int level { get; set; }

        [DataMember]
        public double[] alarmValues { get; set; }

        [DataMember]
        public double[] faultValues { get; set; }

        public void update_data(double[] rvalues, double[] rvaluesL, double[] rvalueH)
        {
            try
            {
                int data_size = rvalues.Length;
                int l = 0;
                for (int i = 0; i < data_size; i++)
                {
                    values[i] = rvalues[i];
                    alarmValues[i] = rvaluesL[i];
                    faultValues[i] = rvalueH[i];
                    levels[i] = rvalues[i] < rvaluesL[i] ? 0 : (rvalues[i] < rvalueH[i] ? 1 : 2);
                    l = Math.Max(l, levels[i]);
                }
                level = l;
            }
            catch (Exception ex)
            {
                throw new Exception("|BoxData|update_data|ERROR| " + ex.Message + "StackTrace:" + ex.StackTrace);

            }


        }
        public BoxData copy()
        {
            return new BoxData
            {
                names = (string[])this.names.Clone(),
                values = (double[])this.values.Clone(),
                levels = (int[])this.levels.Clone(),
                level = this.level,
                alarmValues = (double[])this.alarmValues.Clone(),
                faultValues = (double[])this.faultValues.Clone()
            };
        }

        public BoxData SortDes(int max_indexi)
        {

            int max_index = Math.Min(max_indexi, this.values.Length);
            if (max_indexi <= 0)
            {
                max_index = this.values.Length;
            }
            //Dictionary<int, int> dic = new Dictionary<int, int>();
            Dictionary<int, double> dic = new Dictionary<int, double>();
            for (int i = 0; i < this.values.Length; i++)
            {
                dic.Add(i, this.values[i]);
            }
            dic = dic.OrderByDescending(o => o.Value).ToDictionary(p => p.Key, o => o.Value);
            string[] names = new string[max_index];
            int[] levels = new int[max_index];
            int level = 0;
            double[] values = new double[max_index];

            double[] alarmValues = new double[max_index];
            double[] faultValues = new double[max_index];
            int index = 0;
            foreach (var item in dic)
            {

                names[index] = this.names[item.Key];
                values[index] = this.values[item.Key];
                levels[index] = this.levels[item.Key];
                level = Math.Max(level, levels[index]);

                alarmValues[index] = this.alarmValues[item.Key];
                faultValues[index] = this.faultValues[item.Key];

                index = index + 1;
                if (index >= max_index)
                {
                    return new BoxData
                    {
                        names = (string[])names.Clone(),
                        values = (double[])values.Clone(),
                        levels = (int[])levels.Clone(),
                        level = level,
                        alarmValues = (double[])alarmValues.Clone(),
                        faultValues = (double[])faultValues.Clone()
                    };
                }
            }
            return this;

        }
    }


    public class StandAlarmState
    {
        [DataMember]
        public bool[,] standAlarmState;
        public bool[] stdIsAlarm { set; get; }


        private int[,] standAlarmTimes;

        private bool lastState;
        private bool nowState;
        private readonly int falseTimesMin = 3;
        public StandAlarmState()
        {
            standAlarmState = new bool[6, 3];
            standAlarmTimes = new int[6, 3];
            stdIsAlarm = new bool[6] { false, false, false, false, false, false };
            for (int i = 0; i < 6; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    standAlarmState[i, j] = false;
                    standAlarmTimes[i, j] = 0;
                }

            }
        }

        public void update(bool[,] standAlarmStateP)
        {
            for (int i = 0; i < 6; i++)
            {
                bool flag = false;
                for (int j = 0; j < 3; j++)
                {
                    lastState = standAlarmState[i, j];
                    nowState = standAlarmStateP[i, j];
                    //下降沿 延迟 standAlarmTimes[j, i]次
                    if (lastState == true && nowState == false)
                    {
                        standAlarmTimes[i, j]++;
                        if (standAlarmTimes[i, j] >= falseTimesMin)
                        {
                            standAlarmState[i, j] = nowState;
                        }
                    }
                    else
                    {
                        standAlarmState[i, j] = nowState;
                        standAlarmTimes[i, j] = 0;
                    }
                    flag = flag || standAlarmState[i, j];
                }
                stdIsAlarm[i] = flag;
            }
        }


    }
    /// <summary>
    /// 报警信息
    /// </summary>
    public class AlarmInfo
    {
        public AlarmInfo()
        {
            message = "无报警";
            level = 0;
            outLetStripLenth = 0;
            outLetStripLenthName = "卷取长度";
            isAlarm = false;
            //stdNo = 0;
            stdIsAlarm = new bool[6] { false, false, false, false, false, false };

            standAlarmState = new StandAlarmState();
            standAlarmStates = new bool[6, 3];

            standAlarmStates = standAlarmState.standAlarmState;
            stdIsAlarm = standAlarmState.stdIsAlarm;
        }

        [IgnoreDataMember]
        public StandAlarmState standAlarmState { get; set; }

        [DataMember]
        public string message { set; get; }

        [DataMember]
        public int level { set; get; }

        [DataMember]
        public bool isAlarm { set; get; }

        [DataMember]
        //public int stdNo { set; get; }
        public bool[] stdIsAlarm { set; get; }

        [DataMember]
        public bool[,] standAlarmStates { set; get; }

        [DataMember]
        public double outLetStripLenth { get; set; }
        [DataMember]
        public string outLetStripLenthName { set; get; }
        public void reset()
        {
            message = "无报警";
            level = 0;
            outLetStripLenth = 0;
            isAlarm = false;
            //stdNo = 0;
            for (int i = 0; i < 6; i++)
            {
                stdIsAlarm[i] = false;

            }
        }
        public void update(string alarmInfo, int stdNo, string alarmType, bool[,] defectflag)
        {
            message = alarmInfo;
            int indexF = alarmType == "低频" ? 0 : (alarmType == "中频" ? 1 : 2);
            level = defectflag[stdNo, indexF] == true ? 2 : 1;
            //this.stdNo = stdNo + 1;
        }
        public void update(string alarmInfo, bool defectflag)
        {
            message = alarmInfo;
            level = defectflag == true ? 2 : 1;
        }
    }
    public class RollMillData
    {

        [DataMember]
        public BoxData F1 { get; set; }

        [DataMember]
        public BoxData F2 { get; set; }

        [DataMember]
        public BoxData F3 { get; set; }

        [DataMember]
        public BoxData F4 { get; set; }

        [DataMember]
        public BoxData F5 { get; set; }

        [DataMember]
        public BoxData F6 { get; set; }

        [DataMember]
        public AlarmInfo AF { get; set; }

        //[JsonConverter(typeof(CustomDateTimeConverter))]
        //public DateTime nowTime { set; get; }


        public RollMillData() { }
        public RollMillData(BoxData[] box_data_array)
        {
            F1 = box_data_array[0];
            F2 = box_data_array[1];
            F3 = box_data_array[2];
            F4 = box_data_array[3];
            F5 = box_data_array[4];
            F6 = box_data_array[5];
            AF = new AlarmInfo();
           // nowTime = DateTime.Now;

        }

    }

}


