using IoT3D.Framework.DataModel;

using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;

namespace IoT3D.Framework
{
    public class RPCModule
    {
        private static Dictionary<int, Dictionary<int, YcItemData>> m_YcItemDics = new Dictionary<int, Dictionary<int, YcItemData>>();
        private static Dictionary<int, Dictionary<int, YxItemData>> m_YxItemDics = new Dictionary<int, Dictionary<int, YxItemData>>();
        public static Dictionary<int, EquipBaseData> m_EquipItemDics = new Dictionary<int, EquipBaseData>();
        private static List<int> SubscribedEquipNos = new List<int>();

        private static List<RealTimeEventItem> m_RealTimeEvents = new List<RealTimeEventItem>();
        public static List<RealTimeEventItem> RealTimeEvents { get => m_RealTimeEvents;}
        public static Dictionary<int, Dictionary<int, YcItemData>> YcItemDics { get => m_YcItemDics;}
        public static Dictionary<int, Dictionary<int, YxItemData>> YxItemDics { get => m_YxItemDics; }


        public static RealTimeSnapshotEvent AddRealTimeSnapshotListener = new RealTimeSnapshotEvent();
        public static RealTimeSnapshotEvent DeleteRealTimeSnapshotListener = new RealTimeSnapshotEvent();



        private static IRpcHelper _IRpcHelper;
        public static IRpcHelper Rpc
        {
            get
            {
                return _IRpcHelper;
            }
        }
        public static void SetRpc(IRpcHelper rpc)
        {
            _IRpcHelper = rpc;
        }
        public static async Task<T> GetAsyncSQLData<T>(string sql)
        {
            return await Rpc?.GetAsyncSQLData<T>(sql);
        }
        /// <summary>
        /// ȡʽֵ
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cmd"></param>
        /// <returns></returns>
        public static async Task<T> GetExpressionValueAsync<T>(string cmd)
        {
            if (Rpc == null)
                return default;
            if (!string.IsNullOrEmpty(cmd))
            {
                string data = await Rpc.GetValueExpressionData(cmd);
                if (data != null)
                {
                    T value = JsonConvert.DeserializeObject<T>(data);
                    return value;
                }
            }
            return default;
        }
        /// <summary>
        /// ȡңֵ
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="equipNo"></param>
        /// <param name="ycNo"></param>
        /// <returns></returns>
        public static async Task<T> GetValueAsync<T>(int equipNo, int ycNo)
        {
            if (Rpc == null)
                return default;
            string data = await Rpc.GetYcValueData(equipNo, ycNo);
            // Debug.Log(data);
            if (data != null)
            {
                try
                {
                    T value = JsonConvert.DeserializeObject<T>(data);
                    return value;
                }
                catch (Exception ex)
                {
                    Debug.LogWarning(ex.Message);
                    return default;
                }
            }
            return default;
        }

        /// <summary>
        /// 豸
        /// </summary>
        /// <param name="eventMessage"></param>
        public static void UpdateEquipItem(EquipBaseData eventMessage)
        {
            if (!m_EquipItemDics.ContainsKey(eventMessage.EquipNo))
            {
                m_EquipItemDics.Add(eventMessage.EquipNo, eventMessage);
            }
            else
            {
                EquipBaseData equipData = m_EquipItemDics[eventMessage.EquipNo];
                equipData.State = eventMessage.State;
                Debug.LogError("£"+ equipData.State);
            }
        }
        /// <summary>
        /// ң
        /// </summary>
        /// <param name="ycEventitem"></param>
        public static void UpdateYCItem(YcItemData ycEventitem)
        {
            if (!YcItemDics.ContainsKey(ycEventitem.EquipNo))
            {
                YcItemDics.Add(ycEventitem.EquipNo, new Dictionary<int, YcItemData>());
                YcItemDics[ycEventitem.EquipNo].Add(ycEventitem.YcNo, ycEventitem);
            }
            else
            {
                Dictionary<int, YcItemData> _ycItems = YcItemDics[ycEventitem.EquipNo];
                if (_ycItems.ContainsKey(ycEventitem.YcNo))
                {
                    //_ycItems[ycEventitem.YcNo] = ycEventitem;
                    _ycItems[ycEventitem.YcNo].YcValue = ycEventitem.YcValue;
                    _ycItems[ycEventitem.YcNo].EquipState = ycEventitem.EquipState;
                    _ycItems[ycEventitem.YcNo].IsAlarm = ycEventitem.IsAlarm;
                    _ycItems[ycEventitem.YcNo].Unit = ycEventitem.Unit;
                }
                else
                {
                    _ycItems.Add(ycEventitem.YcNo, ycEventitem);
                }
            }
        }
        /// <summary>
        /// ң
        /// </summary>
        /// <param name="yxEventitem"></param>
        public static void UpdateYXItem(YxItemData yxEventitem)
        {
            if (!YxItemDics.ContainsKey(yxEventitem.EquipNo))
            {
                YxItemDics.Add(yxEventitem.EquipNo, new Dictionary<int, YxItemData>());
                YxItemDics[yxEventitem.EquipNo].Add(yxEventitem.YxNo, yxEventitem);
                //Debug.LogError("Add:" + yxEventitem.EquipNo);
            }
            else
            {
                Dictionary<int, YxItemData> _yxItems = YxItemDics[yxEventitem.EquipNo];
                if (_yxItems.ContainsKey(yxEventitem.YxNo))
                {
                    _yxItems[yxEventitem.YxNo].YxValue = yxEventitem.YxValue;
                    _yxItems[yxEventitem.YxNo].EquipState = yxEventitem.EquipState;
                    _yxItems[yxEventitem.YxNo].IsAlarm = yxEventitem.IsAlarm;
                    _yxItems[yxEventitem.YxNo].State = yxEventitem.State;
                    // Debug.LogError("Update:" + yxEventitem.EquipNo);
                }
                else
                {
                    _yxItems.Add(yxEventitem.YxNo, yxEventitem);
                    //Debug.LogError("Add:" + yxEventitem.EquipNo);
                }
            }
        }
        /// <summary>
        /// ȡң
        /// </summary>
        /// <param name="equipNo">豸</param>
        /// <param name="ycNo">ң</param>
        /// <returns></returns>
        public static YcItemData GetYcItem(int equipNo, int ycNo)
        {
            ChecekSubscribedEquipNos(equipNo);
            if (YcItemDics.ContainsKey(equipNo))
            {
                return YcItemDics[equipNo].Values.ToList().Find(x => x.EquipNo == equipNo && x.YcNo == ycNo);
            }
            return null;
        }
        /// <summary>
        /// ȡң
        /// </summary>
        /// <param name="equipNo">豸</param>
        /// <param name="yxNo">ңź</param>
        /// <returns></returns>
        public static YxItemData GetYxItem(int equipNo, int yxNo)
        {
            ChecekSubscribedEquipNos(equipNo);
            if (YxItemDics.ContainsKey(equipNo))
            {
                return YxItemDics[equipNo].Values.ToList().Find(x => x.EquipNo == equipNo && x.YxNo == yxNo);
            }
            return null;
        }
        /// <summary>
        /// ȡ仯ң
        /// </summary>
        /// <param name="equipNo">豸</param>
        /// <returns></returns>
        public static List<YcItemData> GetYcChangedItems(int equipNo)
        {
            ChecekSubscribedEquipNos(equipNo);
            if (YcItemDics.ContainsKey(equipNo))
            {
                return YcItemDics[equipNo].Values.ToList();
            }
            return null;
        }
        /// <summary>
        /// ȡ仯ң
        /// </summary>
        /// <param name="equipNo">豸</param>
        /// <returns></returns>
        public static List<YxItemData> GetYxChangedItems(int equipNo)
        {
            ChecekSubscribedEquipNos(equipNo);
            if (YxItemDics.ContainsKey(equipNo))
            {
                return YxItemDics[equipNo].Values.ToList();
            }
            return null;
        }
        /// <summary>
        /// ȡ豸
        /// </summary>
        /// <param name="equipNo">豸</param>
        /// <returns></returns>
        public static EquipBaseData GetEquipDataItem(int equipNo)
        {
            ChecekSubscribedEquipNos(equipNo);
            if (m_EquipItemDics.ContainsKey(equipNo))
                return m_EquipItemDics[equipNo];
            return null;
        }
        /// <summary>
        /// 豸
        /// </summary>
        /// <param name="equipNo">豸</param>
        private static void ChecekSubscribedEquipNos(int equipNo)
        {
            if (!SubscribedEquipNos.Contains(equipNo))
            {
                SubscribedEquipNos.Add(equipNo);
                Rpc.AddEquipStateSubscribe(equipNo);
               // Debug.LogError("¶"+ equipNo);
            } 
        }
    }
    public class RealTimeSnapshotEvent : UnityEvent<RealTimeEventItem>
    { }
}
