using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using FBoxClientDriver;
using FBoxClientDriver.Contract;
using FBoxClientDriver.Impl;
using NLog;

namespace Ropin.Environmentally.WebScada
{
    public class FlexBox
    {
    }
    public class FBoxClientParameters
    {

        //Fbox线上地址,私有云的改成私有地址即可。
        public static string IdServer { get; set; } = "https://account.flexem.com/core";
        public static string MainServer { get; set; } = "http://fbox360.com";
        public static string HdataServer { get; set; } = "http://fbhs1.fbox360.com";



        //填写平台创建的开发者账号
        public static string ClientId { get; set; } = "b19d14eeacb74522bd29627b79c18ab8"; //"a1d6d4291a0e4caf8d1b486cdb12ba0f"
        public static string ClientSecret { get; set; } = "7b89e021586c43d3b79440ba6eea0b67"; //"412e1a83cd1e4e64a98ef9eb83f9aaf9"


    }




    public class demo : IDisposable //实现接口
    {
        public static Logger logger = LogManager.GetLogger("SimpleDemo"); //打印日志在文件夹中,文件夹命名SimpleDemo

        public readonly IFBoxClientManager _fbox;


        private readonly string guid = Guid.NewGuid().ToString("N");

        public demo()
        {
            HttpClient httpClient = new HttpClient();

            var provider = new DefaultCredentialProvider(FBoxClientParameters.ClientId, FBoxClientParameters.ClientSecret);


            _fbox = new FBoxClientManager(FBoxClientParameters.IdServer, FBoxClientParameters.MainServer,
            FBoxClientParameters.HdataServer, provider, guid, null, httpClient);



            //侦听盒子状态变更事件     (订阅事件是,只能订阅一次)
            _fbox.BoxConnectStateChanged += _fbox_BoxConnectStateChanged;

            // 侦听实时数据变更事件 ,和盒子状态变更事件同时用
            //_fbox.DataMonitorValueChanged += _fbox_DataMonitorValueChanged;

            //侦听报警触发推送,和盒子状态变更事件同时用
            // _fbox.AlarmTriggered += _fbox_AlarmTriggered;

            //监听时报警还原推送
            //_fbox.AlarmRecoverd += _fbox_AlarmRecoverd;

            Console.WriteLine(guid);
            Console.WriteLine();

        }


        public void Dispose()
        {
            _fbox?.Dispose();
        }

        //时实数据推送方法,处理有时间限制,尽量控制在100秒左右
        private void _fbox_DataMonitorValueChanged(object sender, IList<DataMonitorValueChangedArgs> e)
        {
            foreach (var dmon in e)
            {
                Console.WriteLine(
                    $"dmv:{dmon.Uid},Value:{dmon.Value},Status:{dmon.Status},BoxNo:{dmon.BoxNo},Name:{dmon.Name},BoxId:{dmon.BoxId},GroupName:{dmon.GroupName},Timestamp:{dmon.Timestamp}");
                //logger.Error($"uid:{dmon.Uid},value:{dmon.Value},Status:{dmon.Status},BoxNo:{dmon.BoxNo},BoxId:{dmon.BoxId},GroupName:{dmon.GroupName},Timestamp:{dmon.Timestamp},Name:{dmon.Name}");
                System.DateTime currentTime = new System.DateTime();
                currentTime = System.DateTime.Now;
                Console.WriteLine(currentTime);
                logger.Info("时间" + currentTime + "Uid" + dmon.Uid + "名称:" + dmon.Name + "值:" + dmon.Value + "状态:" + dmon.Status + "盒子号:" + dmon.BoxNo + "分组名称:" + dmon.GroupName + "时间" + dmon.Timestamp);


            }

            //接收数据,先存数据,再把数据显示到页面上
        }

        /// <summary>
        /// 盒子状态变更函数监听一次事件也叫(订阅事件)
        /// 第一个连接上或者是重连signalr,推送的盒子的状态只会推送盒子的在线状态
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        ///
        ///

        private void _fbox_BoxConnectStateChanged(object sender, IList<BoxConnectionStateItem> e) //处理有时间限制,尽量控制在100秒左右
        {
            foreach (var stateItem in e)
            {
                //  每一个盒子断线之后再上线,需要重新调用这个方法判断盒子的一个状态  ,这个方法是不包含在这个监听事件里面的,只是写在这个地方了,如果客户自己写的话,需要客户调用这个方法。
                if (stateItem.NewState == BoxConnectionState.Connected ||
                    stateItem.NewState == BoxConnectionState.TimedOut) //判断这个盒子的在线的一个状态
                {
                    //监控所有的监控点,(这个方法里面会有报错误500,需要在task里面捕获异常,需要添加重试机制)
                    _fbox.StartAllDataMonitorPointsOnBox(new BoxArgs(stateItem.BoxNo)).Wait();

                }

                Console.WriteLine($"{stateItem.BoxNo},{stateItem.NewState},{stateItem.NetworkType}");

                logger.Error($"{stateItem.BoxNo},{stateItem.NewState}"); //打印日志在文件夹中
                logger.Info("盒子号:" + stateItem.BoxNo + "状态:" + stateItem.NewState);
                logger.Info("信号:" + stateItem.Rssi);
            }
        }

        private int guard;


        //  报警触发推送
        private void _fbox_AlarmTriggered(object sender, IList<AlarmTriggerDefinitionArgs> e)
        {
            foreach (var triggered in e)
            {
                Console.WriteLine(
                    $"dmv:{triggered.BoxNo},{triggered.BoxId}{triggered.Uid},{triggered.Value},{triggered.Name}{triggered.Message}");
            }

            System.DateTime currentTime = new System.DateTime();
            currentTime = System.DateTime.Now;
            Console.WriteLine(currentTime);
        }


        //报警还原推送

        private void _fbox_AlarmRecoverd(object sender, IList<AlarmRecoverDefinitonArgs> e)
        {
            foreach (var recover in e)
            {
                Console.WriteLine($"dmv:{recover.Uid},{recover.Value},{recover.Name},{recover.Message}");
            }
        }



        //<summary>
        //启用
        //</summary>
        public async Task Start()
        {
            try
            {
                //通过参数登录服务器,连接signalr

                await _fbox.Restart();
                //只会重启一次,是单例,盒子和服务器只能建立一条通道传输数据

            }

            catch (Exception e)
            {
                Console.WriteLine(e); //控制台输出
                throw e; //抛异常

            }

        }


        // <summary>
        //监控点写值
        //  </summary>
        // public void WriteValue()
        // {
        //
        //     try
        //     {
        //         _fbox.WriteValue(new DataMonitorWriteValueArgsV2()
        //         {
        //             BoxNo = boxNo,
        //             // DataMonitorUid = 177968673027267519,
        //             DataMonitorGroupName= "test",
        //             DataMonitorName= "ceshi1",
        //             Value = 1,
        //             Type = 0
        //         }).Wait();
        //        
        //     }
        //     catch (Exception e)
        //     {
        //         Console.WriteLine(e);
        //         throw;
        //     }
        //
        // }



        //<summary>
        //获取历史记录条目 (历史记录接口)
        //</summary>
        // public void GetHdataItems()
        // {
        //     var itemsss = _fbox.GetHdataItems(new BoxArgs()
        //     {
        //         BoxNo = boxNo
        //     }).Result;
        //     foreach (var items in itemsss)
        //     {
        //         Console.WriteLine(items.BoxId);
        //         foreach (var channels in items.Channels)
        //         {
        //             Console.WriteLine(channels.Uid);                //通道Id
        //             Console.WriteLine(channels.HasSubAddress);      //寄存器是否有子地址
        //             Console.WriteLine(channels.HasSubIndex);        //寄存器是否有DB块地址
        //             Console.WriteLine(channels.DataType);           //数据类型,详情见接口文档中附录二
        //             Console.WriteLine(channels.MainAddress);        //主地址
        //             Console.WriteLine(channels.RegName);            //寄存器名称
        //             Console.WriteLine(channels.RegId);              //寄存器Id
        //             Console.WriteLine(channels.IoWidth);            //寄存器位宽
        //             Console.WriteLine(channels.StationNo);          //站号
        //             Console.WriteLine(channels.SubAddress);         //子地址
        //             Console.WriteLine(channels.DevAlias);           //PLC别名
        //             Console.WriteLine(channels.SubIndex);           //DB块地址
        //         }
        //         Console.WriteLine(items.Name);                      //名称
        //         Console.WriteLine(items.RecordingPeriod);           //采集周期
        //         Console.WriteLine(items.Uid);                       //主键
        //         Console.WriteLine(items.IsControl);                 //是否使用使能
        //     }
        // }


        //获取历史记录数据
        //获取历史的数据的sdk里方法的时间是正确时间,如果是调用接口的话需要加上8小时。
        // public IList<ByRowHistoryDataRow> GetByRowHistoryData()
        // {
        //     try
        //     {
        //         var hdata = _fbox.GetByRowHistoryData(new GetHistoryDataArgs()
        //         {
        //             BoxNo = boxNo,                                //盒子号
        //             StartTime = DateTime.Parse("2020-12-10 05:00:00"),  //new DateTime(2020, 8, 11, 6, 0, 0)     //起始时间
        //             EndTime = DateTime.Parse("2020-12-11 06:00:00"),        //结束时间
        //             Limit = 500,                                 //最大获取数据条数
        //             TimeRange = TimeRangeTypes.BeginOpenEndOpen, //区间类型,BeginCloseEndClose:全毕区间,BeginCloseEndOpen:左闭右开,BeginOpenEndClose:左开右闭,BeginOpenEndOpen:全开区间
        //             HdataItemName = "test2",                        //历史数据条目名称
        //             HdataChannelNames = new List<string>() { "test2","test3" }//通道名称
        //         }).Result;
        //
        //         foreach (var d in hdata.Rows)
        //         {
        //             Console.WriteLine(d.Time); // 历史数据条目的采集时间
        //             Console.WriteLine(d.Values[0]); // 对应通道名称集合中的第一个元素
        //             Console.WriteLine(d.Values[1]); // 对应通道名称集合中的第二个元素
        //         }
        //         return hdata.Rows;
        //         //Console.WriteLine(itemssData.Rows.Count);    //不是数组集合,不用循环
        //         //return itemssData.Rows;
        //     }
        //     catch (Exception e)
        //     {
        //         Console.WriteLine(e);
        //         throw e;
        //     }
        // }




    }
}