using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common;
using System.Collections.Concurrent;
using System.Threading;
namespace CommonEntity
{
    public class DataTongJi
    {
        public static ConcurrentDictionary<string, UDPPackageCount> TotalCount = new ConcurrentDictionary<string, UDPPackageCount>();
        public static ConcurrentBag<double> CPU_Data = new ConcurrentBag<double>();

        /// <summary>
        /// 下位机黑名单 
        /// </summary>
        //public static UDPPackageBlockFilter BlockLowerMachineList = new UDPPackageBlockFilter();
        public static ConcurrentDictionary<string, ConcurrentBag<string>> BlockLowerMachineList = new ConcurrentDictionary<string, ConcurrentBag<string>>();
        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(DataTongJi));

        /// <summary>
        /// 0x19数据 
        /// </summary>
        public static ConcurrentBag<string> ZeroX19_PassHotelCode = new ConcurrentBag<string>();
        /// <summary>
        /// RCU在线数量
        /// </summary>
        public static ConcurrentDictionary<string, RCUOnLineExtra> ONLINERCU = new ConcurrentDictionary<string, RCUOnLineExtra>();


        /// <summary>
        /// 取电开关
        /// </summary>
        public static ConcurrentDictionary<string, MTakeCardData> TakeCardOnLine = new ConcurrentDictionary<string, MTakeCardData>();

        /// <summary>
        /// 在线用户
        /// </summary>
        public static ConcurrentDictionary<string, OnLineUser> OnLineUserList_IP = new ConcurrentDictionary<string, OnLineUser>();
        //public static ConcurrentDictionary<string, OnLineUser> OnLineUserList_Account = new ConcurrentDictionary<string, OnLineUser>();

        public class MTakeCardData
        {
            public string HostNUMBER { get; set; }
            public string HotelCode { get; set; }
            public byte Status { get; set; }
            public DateTime LastUpdateTime { get; set; }
        }
        public class OtherServiceInfo
        {
            public string HotelCode { get; set; }
            public string HostNumber { get; set; }
            public string Address { get; set; }
            public ushort StatusReceiver { get; set; }
            public DateTime LastUpdateTime { get; set; }
        }

        public static long DefineLostPackage = 0;

        /// <summary>
        /// 记录丢失的数据
        /// </summary>
        public static long RecordLostPackage = 0;
        public static int LostPackage_Interval = 60;


        /// <summary>
        /// 判断 A数组是否包含B数组
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="subsequence"></param>
        /// <returns></returns>
        public static bool ContainsSubsequence<T>(List<T> source, List<T> subsequence)
        {
            if (subsequence.Count == 0) return true;
            if (source.Count < subsequence.Count) return false;

            for (int i = 0; i <= source.Count - subsequence.Count; i++)
            {
                var subList = source.GetRange(i, subsequence.Count);
                if (subList.SequenceEqual(subsequence))
                    return true;
            }
            return false;
        }


        public static void CeShi()
        {
            List<byte> A = new List<byte> { 0x01, 0x02, 0x04, 0x00, 0x01, 0xff, 0xff, 0xff, 0x04, 0x00, 0x01, 0xAA, 0xBB, 0xCC, 0x04, 0x00, 0x01, 0xCC, 0xDD, 0x01 };
            List<byte> target = new List<byte> { 0x04, 0x00, 0x01 };

            // 查找所有匹配的位置
            List<int> matchIndices = FindAllMatches(A, target);

            if (matchIndices.Count > 0)
            {
                Console.WriteLine("找到匹配的序列：");
                foreach (int index in matchIndices)
                {
                    // 提取匹配序列及其后两个字节
                    int start = index;
                    int end = Math.Min(index + target.Count + 3, A.Count);
                    List<byte> extracted = A.GetRange(start, end - start);

                }
            }
            else
            {
                Console.WriteLine("未找到匹配的序列");
            }
        }

        /// <summary>
        /// 查找匹配的位置 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        public static List<int> FindAllMatches(List<byte> source, List<byte> target)
        {
            List<int> indices = new List<int>();
            if (target.Count == 0 || source.Count < target.Count) return indices;

            for (int i = 0; i <= source.Count - target.Count; i++)
            {
                bool match = true;
                for (int j = 0; j < target.Count; j++)
                {
                    if (source[i + j] != target[j])
                    {
                        match = false;
                        break;
                    }
                }
                if (match)
                {
                    indices.Add(i);
                }
            }
            return indices;
        }
        /// <summary>
        /// 给某个模块添加 调用次数统计，统计是每个小时 调用的总数
        /// </summary>
        /// <param name="ModuleName"></param>
        public static void InvokeCount(string ModuleName)
        {
            try
            {
                DateTime DDT = DateTime.Now;
                int Year = DDT.Year;
                int MM = DDT.Month;
                int dd = DDT.Day;
                int HH = DDT.Hour;

                string Key = ModuleName + Year + "-" + MM + "-" + dd + "#" + HH;
                //string hotelid = Session["CurrentHotelID"].ToString();
                //string HotelName = Session["CurrentHotelName"].ToString();
                long data = CSRedisCacheHelper.Get_Partition<long>(Key, 1);
                if (data == 0)
                {
                    CSRedisCacheHelper.Set_PartitionWithTime<long>(Key, 1, 120, 1);
                }
                else
                {
                    CSRedisCacheHelper.Set_PartitionWithTime<long>(Key, data += 1, 120, 1);
                }
            }
            catch (Exception)
            {

            }
        }
    }
    public class RCUOnLineExtra
    {
        public DateTime CurrentDateTime { get; set; }
        public string HotelCode { get; set; }
    }

    public class StepInfo
    {
        public long EveryMessageId { get; set; }
        public long Monitor_0E_01 { get; set; }

        public string HotelCode { get; set; }
        public string HostNumber { get; set; }
        public string MessageId { get; set; }
        public string TriggerTime { get; set; }
        public double Step { get; set; }
        public string StepDescription { get; set; }
        public byte[] Content { get; set; }
    }

    public class OnLineUser
    {
        public string Account { get; set; }
        public string IP { get; set; }
        public string HotelCode { get; set; }
        public int HotelId { get; set; }
        public DateTime LastUpdateTime { get; set; }
    }

    public class NengHao
    {
        public long HotelCode { get; set; }
        public string HostNumber { get; set; }
        public string RoomNumber { get; set; }
        public string Mac { get; set; }
        public string EndPoint { get; set; }
        public string Version { get; set; }
        public bool IsTakeCard { get; set; }
        public int CarbonVIP { get; set; }
        public double V { get; set; }
        public double A { get; set; }
        public double P { get; set; }
        public double KW_H { get; set; }
        public double Sum_KW_H { get; set; }

        public long CreateTime { get; set; }

        public DateTime ReportTime { get; set; }
    }

    public class NengHao4BaoJing
    {
        public long HotelCode { get; set; }
        public string HostNumber { get; set; }
        public string RoomNumber { get; set; }
        public string Mac { get; set; }
        public string EndPoint { get; set; }
        public string Version { get; set; }
        /// <summary>
        /// 这个叫是否 取电 取断电状态 
        /// </summary>
        public int IsTakeCard { get; set; }

        /// <summary>
        /// 是否插卡
        /// </summary>
        public int IsInsertCard { get; set; }

        /// <summary>
        ///短离长离 
        ///我们这里叫卡事件
        /// </summary>
        public ushort CardEvent { get; set; }

        /// <summary>
        /// PMS 状态
        /// </summary>
        public string PMS_Status { get; set; }

        public int CarbonVIP { get; set; }
        public List<NengHao_Repeat> NengHaoList { get; set; }
        //public double V { get; set; }
        //public double A { get; set; }
        //public double P { get; set; }
        //public double Energy_Consumption { get; set; }
        //public double Sum_Energy_Consumption { get; set; }
        public long CreateTime { get; set; }
        public string ReportTime { get; set; }
        public List<DingShiReportDate> AllDeviceData { get; set; }

        /// <summary>
        /// 卡身份
        /// </summary>
        public int IdentityInfo { get; set; }
        public int Bright_G { get; set; }
    }

    /// <summary>
    /// ts 日志
    /// </summary>
    public class NewVersionLog
    {
        public string hotel_id { get; set; }
        public string room_id { get; set; }
        public string device_id { get; set; }
        public string ip { get; set; }

        public ushort power_state { get; set; }
        public ushort guest_type { get; set; }
        public ushort cardless_state { get; set; }
        public ulong service_mask { get; set; }
        public ushort pms_state { get; set; }
        public ushort carbon_state { get; set; }
        public int device_count { get; set; }
        public ushort comm_seq { get; set; }
        public List<NengHaolog> electricity { get; set; }
        public List<KongTiao> air_conditioner { get; set; }
        public extra_data extra { get; set; }


        public int insert_card { get; set; }
        public int bright_g { get; set; }
        public int version { get; set; }
    }

    public class ts_deviceitem
    {
        public short dev_type { get; set; }
        public short dev_addr { get; set; }
        public short dev_loop { get; set; }
        public int dev_data { get; set; }
    }
    public class ts_faultitem
    {
        public short dev_type { get; set; }
        public short dev_addr { get; set; }
        public short dev_loop { get; set; }
        public short error_type { get; set; }
        public int error_data { get; set; }
    }
    public class ts_controlitem
    {
        public short dev_type { get; set; }
        public short dev_addr { get; set; }
        public short dev_loop { get; set; }
        public short type_l { get; set; }
        public int type_h { get; set; }
    }
    /// <summary>
    /// 0x36
    /// </summary>
    public class DeviceActionData 
    {
        public long ts_ms { get; set; }
        public string hotel_id { get; set; }
        public string room_id { get; set; }
        public string device_id { get; set; }
        /// <summary>
        /// "上报" 或 "下发"
        /// </summary>
        public string direction { get; set; }

        public string cmd_word { get; set; }
        public int frame_id { get; set; }
        public byte[] udp_raw { get; set; }
        public int sys_lock_status { get; set; }

        public int report_count { get; set; }
        public int fault_count { get; set; }
        public List<ts_deviceitem> device_list { get; set; }
        public List<ts_faultitem> fault_list { get; set; }
        public List<ts_controlitem> control_list { get; set; }

    }
    public class NengHaolog
    {
        public string address { get; set; }
        public double voltage { get; set; }
        public double ampere { get; set; }
        public double power { get; set; }
        //public double watt { get; set; }
        public double energy { get; set; }
        public double sum_energy { get; set; }
        public string phase { get; set; }
    }
    public class KongTiao
    {
        public string address { get; set; }
        public int state { get; set; }
        public int model { get; set; }
        public int speed { get; set; }
        public int set_temp { get; set; }
        public int now_temp { get; set; }
        public int solenoid_valve { get; set; }
    }
    public class extra_data
    {
        public byte[] original_byte { get; set; }
        public string source { get; set; }
        public string ver { get; set; }
        public object ac { get; set; }
        public object meter { get; set; }
    }

    public class Interface3Log
    {
        public string HotelCode { get; set; }
        public string HostNumber { get; set; }
        public string RoomNumber { get; set; }
        public HttpActionData ActionData { get; set; }
        public DateTime TriggerTime { get; set; }
        public string CommandType { get; set; }
    }
    public class HttpActionData
    {
        public double Step { get; set; }
        public string RequestData { get; set; }
        public string ResponseData { get; set; }
    }

    public class WelcomeAction
    {
        public string CUID { get; set; }
        public string VoiceDeviceClass { get; set; }
        public string CommandType { get; set; }
    }



    public class StepTongJi
    {
        /// <summary>
        /// 每一条消息都有一个ID
        /// </summary>
        public static long EveryMessageIDNo = 0;
        /// <summary>
        /// 每一个01和0E的编号
        /// </summary>
        public static long Every_0E_01_MessageID = 0;

        /// <summary>
        /// 每 一条消息都有一个ID
        /// </summary>
        public static string EveryMessageID = "";

        /// <summary>
        /// 1000包抓取一包,抓包计数器
        /// </summary>
        public static long LookDataCounter = 0;

        /// <summary>
        /// 要监听的数据包编号
        /// </summary>
        public static string GlobalListenID = "";
        public static string GlobalListenIDNo = "";

        /// <summary>
        /// 是否要锁定
        /// </summary>
        public static int IsLocked = 0;


        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(StepTongJi));
        /// <summary>
        /// 发送Redis广播
        /// </summary>
        /// <param name="step"></param>
        /// <param name="desc"></param>
        /// <param name="context_messageid"></param>
        public static void SendInfo(double step, string desc, string context_messageid, bool ismonitor)
        {
            try
            {
                if (ismonitor)
                {
                    StepInfo s = new StepInfo();
                    s.MessageId = context_messageid;
                    s.Step = step;
                    s.StepDescription = desc;
                    //string ti = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffffff");
                    string ti = CPUData.GetNowPrecise().ToString("yyyy-MM-dd HH:mm:ss.ffffff");
                    s.TriggerTime = ti;

                    string NNN = Newtonsoft.Json.JsonConvert.SerializeObject(s);
                    CSRedisCacheHelper.Publish("redis-roomstatus-monitor", NNN);
                }
            }
            catch (Exception ex)
            {
                logger.Error("StepTongJi Error:" + ex.Message);
            }
        }
    }
}
