using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Common;
using Dao;
using Domain;
using RCUHost.Protocols;
using System.Xml;
using System.Threading.Tasks;
using CommonEntity;

namespace RCUHost.Implement
{
    /// <summary>
    /// 插卡取电 Receiver
    /// </summary>
    public class RoomCardReceiver : GenericReceiverBase
    {
        private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(RoomCardReceiver));
        //private static string debug_hotel_code = System.Configuration.ConfigurationManager.AppSettings["debug_hotel_code"];

        public IHostRepository HostRepository { get; set; }
        public IRoomCardRepository RoomCardRepository { get; set; }
        public IHostRoomCardRepository HostRoomCardRepository { get; set; }
        public IRoomCardTypeRepository RoomCardTypeRepository { get; set; }
        public IAlarmSettingRepository AlarmSettingRepository { get; set; }
        public IRoomServiceRepository RoomServiceRepository { get; set; }
        public IRoomServiceRecordRepository RoomServiceRecordRepository { get; set; }
        public IHostModalRepository HostModalRepository { get; set; }

        public override void Process(ReceiverContext context)
        {
            Reply(context);
            string HostNumberOnly = context.SystemHeader.Value.HostNumber.ToString();
            int startIndex = StructConverter.SizeOf(context.SystemHeader);
            InsertCardPacket? packet = DecodeInsertCardPacket(context.Data, startIndex);
            if (packet.HasValue)
            {
                //SomeDeviceExistsData host = null;
                //RoomStatusReceiver R = new RoomStatusReceiver();
                //host = R.HostDataTake(context);

                Host host = null;
                string Key = CacheKey.RoomStatus_Prefix + "_" + HostNumberOnly;
                object obj = MemoryCacheHelper.Get(Key);
                if (obj != null)
                {
                    host = obj as Host;
                }
                else
                {
                    Host host_O = HostRepository.GetByHostNumber(HostNumberOnly);
                    MemoryCacheHelper.SlideSet(Key,host_O);
                    host = host_O;
                }


                if (host != null)
                {
                    //Host hhh = new Host();
                    //hhh.ID = host.HostID;
                    //hhh.FrameNo = host.FrameNo;
                    //hhh.PowerSupply = host.PowerSupply;
                    //hhh.LockVoltage = host.LockVoltage;
                    //hhh.HostTemp = host.HostTemp;

                    //var tuple_a = state as Tuple<Host, InsertCardPacket?>;
                    //var host = tuple_a.Item1;
                    //var packet = tuple_a.Item2;
                    switch (packet.Value.InsertCard)
                    {
                        case 1://插卡
                            var cardType = RoomCardTypeRepository.Get((int)packet.Value.CardType);//获取房卡类型
                            if (cardType == null)
                            {
                                cardType = RoomCardTypeRepository.Get(1);//如果没有记录，获取有人房卡类型
                            }
                            var roomCard = RoomCardRepository.GetByCartType(cardType, packet.Value.CardNumber.ToString(), host.SysHotel.ID); //GetRoomCard(packet.Value.CardNumber.ToString(), cardType);
                            if (roomCard == null)//如果该房卡未创建记录，自动创建
                            {
                                roomCard = new RoomCard();
                                roomCard.CardNumber = packet.Value.CardNumber.ToString();
                                roomCard.RoomCardType = cardType;
                                roomCard.HotelID = host.SysHotel.ID;
                                RoomCardRepository.Save(roomCard);
                            }
                            HostRepository.SetRoomCard(host, roomCard);
                            break;
                        default://拔卡
                            HostRepository.SetRoomCard(host, null);
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// 处理连通房插卡取电
        /// </summary>
        /// <param name="host"></param>
        //private void ProcessConnectingRooms(Host host, byte insertCard, RoomCardType cardType, RoomCard roomCard)
        //{
        //    byte[] data = CreateInsertCardDataPacket(insertCard, cardType, roomCard);			
        //    var connectingRoomHosts = HostRepository.GetConnectRoomHosts(host);
        //    foreach (var host1 in connectingRoomHosts)
        //    {
        //        Send(data, host.HostNumber);// host1.IP, host1.Port);
        //    }
        //}

        /// <summary>
        /// 处理房卡相关逻辑
        /// </summary>
        /// <param name="host"></param>
        private void ProcessRoomCard(Host host)
        {
            #region 处理“非客人在保险箱开”异常
            {
                var abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C03");
                var abnormity = RoomServiceRepository.Get(host.ID, abnormitySetting.Code);
                if (abnormitySetting != null && abnormity != null)
                {
                    bool isUpdated = false;
                    //如果非客人，且已出租，且保险箱开，则报警
                    if (host.RoomCard != null && host.RoomCard.RoomCardType != null && host.RoomCard.RoomCardType.ID != 0x20 &&
                        host.RoomStatus != null && host.RoomStatus.ID == 0x02 && host.SafeStatus == 1)
                    {
                        isUpdated = true;
                        if (!abnormity.Status)
                        {
                            abnormity.Status = true;
                            abnormity.StartTime = DateTime.Now;
                            RoomServiceRepository.Update(abnormity);

                            var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C03", true);
                            if (abnormityRecord == null)
                            {
                                abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormitySetting);
                                RoomServiceRecordRepository.Save(abnormityRecord);
                            }
                        }
                    }
                    if (!isUpdated)//关掉报警
                    {
                        if (abnormity.Status)
                        {
                            abnormity.Status = false;
                            abnormity.StartTime = DateTime.Now;
                            RoomServiceRepository.Update(abnormity);

                            var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C03", true);
                            if (abnormityRecord != null)
                            {
                                abnormityRecord.Status = false;
                                abnormityRecord.EndTime = DateTime.Now;
                                RoomServiceRecordRepository.Update(abnormityRecord);
                            }
                        }
                    }
                }
            }
            #endregion

            #region 处理“非客人在房门关”异常
            {
                // "非客人在房门关报警" 设置
                var abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'A', "A05");
                if (abnormitySetting != null)
                {
                    bool isUpdated = false;
                    var abnormity = RoomServiceRepository.Get(host.ID, "C06");
                    if (abnormity != null && host.RoomCard != null && host.RoomCard.RoomCardType != null && host.RoomCard.RoomCardType.ID != 0x20 && !host.DoorLockStatus)
                    {
                        isUpdated = true;
                        var delaySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'A', "A06");
                        if (delaySetting == null || Convert.ToInt16(delaySetting.Value) == 0)//不延时报警
                        {
                            if (!abnormity.Status && abnormity.StartTime < DateTime.Now.AddSeconds(-Convert.ToInt16(delaySetting.Value)))
                            {
                                abnormity.Status = true;
                                abnormity.StartTime = DateTime.Now;
                                RoomServiceRepository.Update(abnormity);
                                // “非客人在房门关”异常 记录
                                var abnormityRecordSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C06");
                                var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C06", true);
                                if (abnormityRecordSetting != null && abnormityRecord == null)
                                {
                                    abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormityRecordSetting);
                                    RoomServiceRecordRepository.Save(abnormityRecord);
                                }
                            }
                        }
                        else
                        {
                            //启用线程执行延时报警
                            Tools.SetTimeout(Convert.ToInt16(delaySetting.Value) * 1000, delegate
                            {
                                if (!abnormity.Status)
                                {
                                    abnormity.Status = true;
                                    abnormity.StartTime = DateTime.Now;
                                    RoomServiceRepository.Update(abnormity);
                                    // “非客人在房门关”异常 记录
                                    var abnormityRecordSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C06");
                                    var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C06", true);
                                    if (abnormityRecordSetting != null && abnormityRecord == null)
                                    {
                                        abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormityRecordSetting);
                                        RoomServiceRecordRepository.Save(abnormityRecord);
                                    }
                                }
                            });
                        }
                    }
                    if (!isUpdated)
                    {
                        if (abnormity != null && abnormity.Status)
                        {
                            abnormity.Status = false;
                            abnormity.StartTime = DateTime.Now;
                            RoomServiceRepository.Update(abnormity);
                            // “非客人在房门关 记录
                            var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C06", true);
                            if (abnormityRecord != null)
                            {
                                abnormityRecord.Status = false;
                                abnormityRecord.EndTime = DateTime.Now;
                                RoomServiceRecordRepository.Update(abnormityRecord);
                            }
                        }
                    }
                }
            }
            #endregion

            #region 处理“无人房门开”异常
            {
                // "无人在房门开报警" 设置
                var abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'A', "A03");
                if (abnormitySetting != null)
                {
                    if (host.RoomCard == null && host.DoorLockStatus)
                    {
                        //报警延时设置
                        var delaySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'A', "A04");
                        if (delaySetting == null || Convert.ToInt16(delaySetting.Value) == 0)//不延时报警
                        {
                            var abnormity = RoomServiceRepository.Get(host.ID, "C02");
                            if (abnormity != null && !abnormity.Status)
                            {
                                abnormity.Status = true;
                                abnormity.StartTime = DateTime.Now;
                                RoomServiceRepository.Update(abnormity);
                                // “无人房门开”异常 记录
                                var abnormityRecordSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C02");
                                var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C02", true);
                                if (abnormityRecordSetting != null && abnormityRecord == null)
                                {
                                    abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormityRecordSetting);
                                    RoomServiceRecordRepository.Save(abnormityRecord);
                                }
                            }
                        }
                        else
                        {
                            //启用线程执行延时报警
                            Tools.SetTimeout(Convert.ToInt16(delaySetting.Value) * 1000, delegate
                            {
                                var abnormity = RoomServiceRepository.Get(host.ID, "C02");
                                if (abnormity != null && !abnormity.Status && abnormity.StartTime < DateTime.Now.AddSeconds(-Convert.ToInt16(delaySetting.Value)))
                                {
                                    abnormity.Status = true;
                                    abnormity.StartTime = DateTime.Now;
                                    RoomServiceRepository.Update(abnormity);
                                    // “无人房门开”异常 记录
                                    var abnormityRecordSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C02");
                                    var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C02", true);
                                    if (abnormityRecordSetting != null && abnormityRecord == null)
                                    {
                                        abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormityRecordSetting);
                                        RoomServiceRecordRepository.Save(abnormityRecord);
                                    }
                                }
                            });
                        }
                    }
                    else
                    {
                        var abnormity = RoomServiceRepository.Get(host.ID, "C02");
                        if (abnormity != null && abnormity.Status)
                        {
                            abnormity.Status = false;
                            abnormity.StartTime = DateTime.Now;
                            RoomServiceRepository.Update(abnormity);
                            // “无人房门开”异常 记录
                            var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C02", true);
                            if (abnormityRecord != null)
                            {
                                abnormityRecord.Status = false;
                                abnormityRecord.EndTime = DateTime.Now;
                                RoomServiceRecordRepository.Update(abnormityRecord);
                            }
                        }
                    }
                }
            }
            #endregion

            #region 处理“客人在房门开”异常
            {
                // "客人在房门开报警" 设置
                var abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'A', "A01");
                if (abnormitySetting != null)
                {
                    if (host.RoomCard != null && host.RoomCard.RoomCardType != null && host.RoomCard.RoomCardType.ID == 0x20 && host.DoorLockStatus)
                    {
                        //报警延时设置
                        var delaySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'A', "A02");
                        if (delaySetting == null || Convert.ToInt16(delaySetting.Value) == 0)//不延时报警
                        {
                            var abnormity = RoomServiceRepository.Get(host.ID, "C01");
                            if (abnormity != null && !abnormity.Status)
                            {
                                abnormity.Status = true;
                                abnormity.StartTime = DateTime.Now;
                                RoomServiceRepository.Update(abnormity);
                                // “客人在房门开”异常 记录
                                var abnormityRecordSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C01");
                                var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C01", true);
                                if (abnormityRecordSetting != null && abnormityRecord == null)
                                {
                                    abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormityRecordSetting);
                                    RoomServiceRecordRepository.Save(abnormityRecord);
                                }
                            }
                        }
                        else
                        {
                            //启用线程执行延时报警
                            Tools.SetTimeout(Convert.ToInt16(delaySetting.Value) * 1000, delegate
                            {
                                var abnormity = RoomServiceRepository.Get(host.ID, "C01");
                                if (abnormity != null && !abnormity.Status && abnormity.StartTime < DateTime.Now.AddSeconds(-Convert.ToInt16(delaySetting.Value)))
                                {
                                    abnormity.Status = true;
                                    abnormity.StartTime = DateTime.Now;
                                    RoomServiceRepository.Update(abnormity);
                                    // “客人在房门开”异常 记录
                                    var abnormityRecordSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C01");
                                    var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C01", true);
                                    if (abnormityRecordSetting != null && abnormityRecord == null)
                                    {
                                        abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormityRecordSetting);
                                        RoomServiceRecordRepository.Save(abnormityRecord);
                                    }
                                }
                            });
                        }
                    }
                    else
                    {
                        var abnormity = RoomServiceRepository.Get(host.ID, "C01");
                        if (abnormity != null && abnormity.Status)
                        {
                            abnormity.Status = false;
                            abnormity.StartTime = DateTime.Now;
                            RoomServiceRepository.Update(abnormity);
                            // “客人在房门开”异常 记录
                            var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, "C01", true);
                            if (abnormityRecord != null)
                            {
                                abnormityRecord.Status = false;
                                abnormityRecord.EndTime = DateTime.Now;
                                RoomServiceRecordRepository.Update(abnormityRecord);
                            }
                        }
                    }
                }
            }
            #endregion
        }

        //private RoomCard GetRoomCard(string cardNumber, RoomCardType cardType)
        //{
        //    return RoomCardRepository.Get(cardType, cardNumber);
        //}
        /// <summary>
        /// 获取最后一次插卡未拔卡的记录
        /// </summary>
        /// <param name="hostID"></param>
        /// <returns></returns>
        private HostRoomCard GetLastHostRoomCard(int hostID)
        {
            return HostRoomCardRepository.GetLastHostRoomCard(hostID);
        }

        /// <summary>
        /// 创建插卡数据包
        /// </summary>
        /// <returns></returns>
        private byte[] CreateInsertCardDataPacket(byte insertCard, RoomCardType cardType, RoomCard roomCard)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                var headerLen = StructConverter.SizeOf(typeof(SystemHeader));
                stream.Seek(headerLen, SeekOrigin.Begin);
                stream.WriteByte(insertCard);
                stream.WriteByte((byte)(cardType != null ? cardType.ID : 0));
                int cardNumber = 0;
                if (roomCard != null && String.IsNullOrEmpty(roomCard.CardNumber))
                {
                    cardNumber = Convert.ToInt32(roomCard.CardNumber);
                }
                stream.Write(BitConverter.GetBytes(cardNumber), 0, 4);
                stream.Write(new byte[] { 0, 0 }, 0, 2);
                var systemHeader = CreateSystemHeader((int)stream.Length - headerLen);
                var headerData = StructConverter.StructToBytes(systemHeader);
                stream.Seek(0, SeekOrigin.Begin);
                stream.Write(headerData, 0, headerData.Length);
                return stream.ToArray();
            }
        }
        /// <summary>
        /// 解码 InsertCardPacket
        /// </summary>
        /// <param name="data"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        private InsertCardPacket? DecodeInsertCardPacket(byte[] data, int startIndex)
        {
            return StructConverter.BytesToStruct(data, startIndex, typeof(InsertCardPacket)) as InsertCardPacket?;
        }

        public override CommandType CommandType
        {
            get { return CommandType.InsertCard; }
        }
    }
}
