using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using Domain;
using Dao;
using RCUHost;
using RCUHost.Protocols;
using Spring.Context;
using Spring.Context.Support;
using System.Threading.Tasks;

namespace RCUHost.TimingHelper
{
    public sealed class HostTimingControlHelper
    {
        private static IHostRepository HostRepository { get; set; }
        private static IHostTimingControlRepository HostTimingControlRepository { get; set; }
        private static IRoomTypeSceneModalRepository RoomTypeSceneModalRepository { get; set; }
        private static IRoomTypeSceneRepository RoomTypeSceneRepository { get; set; }
        private static IDeviceControlReceiver _DeviceControlReceiver;

        public static void HostTimingControl(IDeviceControlReceiver deviceControlReceiver)
        {
            System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                _DeviceControlReceiver = deviceControlReceiver;
                using (DataTable dt = HostTimingControlRepository.LoadHostTimingToExec())
                {
                    foreach (DataRow row in dt.Rows)
                    {
                        DateTime now = DateTime.Now;
                        switch (Convert.ToInt16(row["TimingType"]))
                        {
                            case 0://每天定时发送场景
                                ExecHostTiming(row, now);
                                break;
                            case 1://每周
                                foreach (string week in row["TimingDay"].ToString().Split(','))
                                {
                                    if (Convert.ToInt16(week) == Convert.ToInt16(now.DayOfWeek))
                                    {
                                        ExecHostTiming(row, now);
                                        break;
                                    }
                                }
                                break;
                            case 2://每月
                                foreach (string day in row["TimingDay"].ToString().Split(','))
                                {
                                    if (Convert.ToInt16(day) == now.Day)
                                    {
                                        ExecHostTiming(row, now);
                                        break;
                                    }
                                }
                                break;
                        }
                    }
                }
            }, System.Threading.CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
        }
        /// <summary>
        /// 处理定时任务
        /// </summary>
        /// <param name="row"></param>
        /// <param name="now"></param>
        private static void ExecHostTiming(DataRow row, DateTime now)
        {
            foreach (string timing in row["Timing"].ToString().Split(','))
            {
                DateTime dtTiming = Convert.ToDateTime(now.ToString("yyyy-MM-dd") + " " + timing);// row["Timing"].ToString());
                double totalMinutes = (now - dtTiming).TotalMinutes;
                if (totalMinutes >= 0 && totalMinutes < 6)//6分钟以内执行，超过不执行
                {
                    foreach (string hostID in row["HostIDs"].ToString().Split(','))
                    {
                        SendSceneToHost(Convert.ToInt32(hostID), Convert.ToInt32(row["RoomTypeSceneID"]), Convert.ToInt16(row["RoomStatusID"]), Convert.ToInt16(row["RoomCardTypeID"]));
                    }
                    HostTimingControl htc = HostTimingControlRepository.Get(Convert.ToInt32(row["ID"]));
                    htc.ExecStatus = true;
                    htc.ExecTime = now;
                    HostTimingControlRepository.Update(htc);
                }
            }
        }
        /// <summary>
        /// 发送场景指令
        /// </summary>
        /// <param name="hostID"></param>
        /// <param name="roomTypeSceneID">场景ID</param>
        /// <param name="roomStatusID">房态ID</param>
        /// <param name="roomCardTypeID">房卡类型ID</param>
        private static void SendSceneToHost(Int32 hostID, Int32 roomTypeSceneID, int roomStatusID, int roomCardTypeID)
        {
            Host host = HostRepository.Get(hostID);
            if (null == host)
            {
                return;
            }
            if (roomStatusID > 0 && host.RoomStatus == null)//房态空的情况
            {
                //return;
            }
            if (roomStatusID > 0 && host.RoomStatus != null && host.RoomStatus.ID != roomStatusID)
            {
                return;
            }

            //出租无人的情况下也要
            if (roomCardTypeID > -1 && host.RoomCard == null)//房卡是空的情况
            {
                //所以下面的要注释掉
                //return;
            }
            if (roomCardTypeID > -1 && host.RoomCard != null && host.RoomCard.RoomCardType.ID != roomCardTypeID)
            {
                return;
            }
            RoomTypeScene rts = RoomTypeSceneRepository.Get(roomTypeSceneID);

            if (rts.Type == SceneType.Custom)
            {
                var sceneModals = RoomTypeSceneModalRepository.LoadAll(rts);
                if (sceneModals.Count > 0)
                {
                    var devices = new List<Device>();
                    foreach (var sceneModal in sceneModals)
                    {
                        Device device = new Device();
                        device.Address = sceneModal.Modal.ModalAddress;
                        device.AddressType = AddressType.DeviceAddress;
                        device.Type = sceneModal.Modal.Type;
                        device.Status = (byte)sceneModal.Status;
                        device.Brightness = (byte)sceneModal.Brightness;
                        device.Temperature = (byte)sceneModal.CurrentTemp;
                        device.FanSpeed = (byte)sceneModal.FanSpeed;
                        device.Mode = (byte)sceneModal.Mode;
                        device.Valve = (byte)sceneModal.Valve;
                        device.AirExecMode = (sceneModal.Status << 14) + (sceneModal.Mode << 12) + (sceneModal.FanSpeed << 10) + (sceneModal.Valve << 8) + sceneModal.CurrentTemp;//空调执行方式和内容
                        device.FloorHotExecMode = (sceneModal.Status << 12) + (sceneModal.Mode << 8) + (sceneModal.Valve << 6) + sceneModal.CurrentTemp;//地暖执行方式和内容
                        device.MusicExecMode = sceneModal.Status + (sceneModal.Brightness << 12) + (sceneModal.Mode << 8);//背景音乐执行方式和内容
                        devices.Add(device);
                    }
                    _DeviceControlReceiver.Send(host, devices);
                }
            }
            else if (rts.Type == SceneType.Command)
            {
                Device device = new Device();
                device.Address = rts.GroupAddress;
                device.AddressType = AddressType.GroupAddress;
                device.Status = 0x01;
                _DeviceControlReceiver.Send(host, device);
            }
        }
    }
}
