using HslCommunication;
using HslCommunication.Enthernet.Redis;
using HslCommunication.ModBus;
using HslCommunication.MQTT;
using MWS.Data.InterFace;
using MWS.Data.Manager;
using MWS.Domain.Common;
using MWS.Domain.Dto;
using MWS.Library;
using MWS.Library.Common;
using MWS.Model;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MWS.Domain.Tasks.Weighing
{
    /// <summary>
    /// 建立modbus从站写入数据，1000开始开关量，2000开始模拟量，1站
    /// </summary>
    public  class ModbusTcpServerTask
    {
        //private  Thread thread = new Thread(new ThreadStart(ThreadBackground));
        //private static MqttUtil mqttUtil;
        public NextTeamDto nextTeamDto;
        public ModbusTcpServer busTcpServer;
        private RedisClient _redisClient;
        private IDevice device;
        private IWeight weight;
        private MqttClient _mqttClient;
        private List<Device> devices;
        public ModbusTcpServerTask()
        {
            _redisClient = new RedisClient("127.0.0.1", 6379, null);
            _redisClient.SelectDB(1);
            busTcpServer = ModbusServerHelper.StartModbusServer();
            if (busTcpServer!=null)
            {
                InitData();
                #region MQTT
                var mqttPort = ConfigurationManager.AppSettings["MqttPort"];
                _mqttClient = new MqttClient(new MqttConnectionOptions
                {
                    ClientId = Guid.NewGuid().ToString("N").ToUpper(),
                    IpAddress = "127.0.0.1",
                    Port = mqttPort.ToInt(),
                });
                var operateResult = _mqttClient.ConnectServer();
                if (!operateResult.IsSuccess)
                {
                    LogHelper.WriteLog("MQTT服务连接失败！错误：" + operateResult.Message);
                }
                else
                {
                    var subscribeResult = _mqttClient.SubscribeMessage(new string[] { "WeightRealTimeData1", "WeightRealTimeData3", "WeightRealTimeData4", "WeightRealTimeData5", "WeightRealTimeData6", "WeightRealTimeData7", "TeamChange", "WeighingData" });
                    if (!subscribeResult.IsSuccess)
                    {
                        LogHelper.WriteLog("订阅主题失败！Message:" + subscribeResult.Message);
                    }
                    _mqttClient.OnMqttMessageReceived += MqttClient_OnMqttMessageReceived;
                    _mqttClient.OnNetworkError += MqttClient_OnNetworkError;
                }
                #endregion
            }



        }
        private  void MqttClient_OnMqttMessageReceived(MqttClient client, string topic, byte[] payload)
        {
            string changeRealTimeJson;
            switch (topic)
            {
                case "WeightRealTimeData1":
                    changeRealTimeJson = Encoding.UTF8.GetString(payload);
                    ModbusServerRealTimeWeight(changeRealTimeJson);
                    break;
                case "WeightRealTimeData3":
                    changeRealTimeJson = Encoding.UTF8.GetString(payload);
                    ModbusServerRealTimeWeight(changeRealTimeJson);
                    break;
                case "WeightRealTimeData4":
                    changeRealTimeJson = Encoding.UTF8.GetString(payload);
                    ModbusServerRealTimeWeight(changeRealTimeJson);
                    break;
                case "WeightRealTimeData5":
                    changeRealTimeJson = Encoding.UTF8.GetString(payload);
                    ModbusServerRealTimeWeight(changeRealTimeJson);
                    break;
                case "WeightRealTimeData6":
                    changeRealTimeJson = Encoding.UTF8.GetString(payload);
                    ModbusServerRealTimeWeight(changeRealTimeJson);
                    break;
                case "WeightRealTimeData7":
                    changeRealTimeJson = Encoding.UTF8.GetString(payload);
                    ModbusServerRealTimeWeight(changeRealTimeJson);
                    break;
                //case "WeighingData":
                //    var changeWeightJson = Encoding.UTF8.GetString(payload);
                //    ModbusServerWrite(changeWeightJson);
                //    break;
                //case "TeamChange":
                //    var changeTeamJson = Encoding.UTF8.GetString(payload);
                //    TeamChange(changeTeamJson);
                //    break;
            }
        }
        private void MqttClient_OnNetworkError(object sender, EventArgs e)
        {
            // 当网络异常的时候触发，可以在此处重连服务器
            if (sender is MqttClient client)
            {
                // 开始重连服务器，直到连接成功为止
                Console.WriteLine("网络异常，准备5秒后重新连接。");
                while (true)
                {
                    // 每隔5秒重连
                    Thread.Sleep(5000);
                    Console.WriteLine("准备重新连接服务器...");
                    OperateResult connect = client.ConnectServer();
                    if (connect.IsSuccess)
                    {
                        var subscribeResult = _mqttClient.SubscribeMessage(new string[] { "WeightRealTimeData1", "WeightRealTimeData3", "WeightRealTimeData4", "WeightRealTimeData5", "WeightRealTimeData6", "WeightRealTimeData7", "TeamChange", "WeighingData" });
                        if (!subscribeResult.IsSuccess)
                        {
                            LogHelper.WriteLog("订阅主题失败！Message:" + subscribeResult.Message);
                        }
                        // 连接成功后，可以在下方break之前进行订阅，或是数据初始化操作
                        Console.WriteLine("连接服务器成功！");
                        break;
                    }
                    Console.WriteLine("连接失败，准备5秒后重新连接。");
                }
            }
        }

        /// <summary>
        /// 重量推送时根据车辆实时更新对应重量
        /// </summary>
        /// <param name="changeJson"></param>
        private  void ModbusServerWrite(string changeJson)
        {
            try
            {
                JObject tagObject;
                if (changeJson != null)
                {
                    tagObject = JObject.Parse(changeJson.ToString());
                    int tempTeamId = tagObject.GetValue("TeamId").ToSafeInt();
                    int tempDeviceId = tagObject.GetValue("DeviceId").ToSafeInt();
                    var netWeight =Convert.ToSingle(tagObject.GetValue("NetWeight"));

                    var result = weight.GetTotal(tempDeviceId, tempTeamId, 1);
                    var Entrance1Netweight = result != null ? Convert.ToSingle(result) : 0;
                    var result1 = weight.GetTotal(tempDeviceId, tempTeamId, 2);
                    var Entrance2Netweight = result1 != null ? Convert.ToSingle(result1) : 0;

                    //switch (tempDeviceId)
                    //{
                    //    case 1:
                    //        busTcpServer.Write("2000", Entrance1Netweight);
                    //        busTcpServer.Write("2002", Entrance2Netweight);
                    //        break;
                    //    case 2:
                    //        busTcpServer.Write("2100", Entrance1Netweight);
                    //        busTcpServer.Write("2102", Entrance2Netweight);
                    //        break;
                    //    case 3:
                    //        busTcpServer.Write("2200", Entrance1Netweight);
                    //        busTcpServer.Write("2202", Entrance2Netweight);
                    //        break;
                    //}


                }

            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("modbusTCP写数据错误："+ex.Message);
            }

        }

        private void ModbusServerRealTimeWeight(string changeJson)
        {
            try
            {
                JObject tagObject;
                if (changeJson != null)
                {
                    tagObject = JObject.Parse(changeJson.ToString());
                    int tempDeviceId = tagObject.GetValue("DeviceId").ToSafeInt();
                    var netWeight = Convert.ToSingle(tagObject.GetValue("NetWeight"));
                    bool overLoad = Convert.ToBoolean(tagObject.GetValue("OverLoad"));
                    bool isSteady = Convert.ToBoolean(tagObject.GetValue("IsSteady"));
                    bool state = Convert.ToBoolean(tagObject.GetValue("State"));

                    switch (tempDeviceId)
                    {
                        case 1:
                            busTcpServer.Write("2000", netWeight);
                            break;
                        case 3:
                            busTcpServer.Write("2002", netWeight);
                            break;
                        case 4:
                            busTcpServer.Write("2004", netWeight);
                            break;
                        case 5:
                            busTcpServer.Write("2006", netWeight);
                            break;
                        case 6:
                            busTcpServer.Write("2008", netWeight);
                            break;
                        case 7:
                            busTcpServer.Write("2010", netWeight);
                            break;
                    }


                }

            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("modbusTCP写数据错误：" + ex.Message);
            }

        }



        private void TeamChange(string changTags)
        {

            JObject tagObject;
            if (changTags != null)
            {
                tagObject = JObject.Parse(changTags.ToString());
                int tempTeamId = tagObject.GetValue("Id").ToSafeInt();
                string tempName = tagObject.GetValue("Name").ToSafeString();
                nextTeamDto.Id = tempTeamId;
                nextTeamDto.Name = tempName;
                foreach (var item in devices)
                {
                    var result = weight.GetTotal(item.Id, nextTeamDto.Id, 1);
                    var Entrance1Netweight = result != null ? Convert.ToSingle(result) : 0;
                    var result1 = weight.GetTotal(item.Id, nextTeamDto.Id, 2);
                    var Entrance2Netweight = result1 != null ? Convert.ToSingle(result1) : 0;

                    switch (item.Id)
                    {
                        case 1:
                            busTcpServer.Write("2000", Entrance1Netweight);
                            busTcpServer.Write("2002", Entrance2Netweight);
                            break;
                        case 2:
                            busTcpServer.Write("2100", Entrance1Netweight);
                            busTcpServer.Write("2102", Entrance2Netweight);
                            break;
                        case 3:
                            busTcpServer.Write("2200", Entrance1Netweight);
                            busTcpServer.Write("2202", Entrance2Netweight);
                            break;
                    }

                }
            }
            
        }

        private void InitData()
        {
            //加载变量数据
            device = new DeviceManager();
            weight = new WeightManager();
            devices = device.GetAll();
            nextTeamDto = new NextTeamDto();
            float[] floats = new float[devices.Count];
            var operateResult = _redisClient.ReadKey("CurrentTeam");
            if (operateResult.Content != null)
            {
                JObject tagObject = JObject.Parse(operateResult.Content);
                nextTeamDto.Id = tagObject.GetValue("Id").ToSafeInt();
                nextTeamDto.Name = tagObject.GetValue("Name").ToSafeString();
                //result = weightManager.GetTotal(deviceId, teamId);
                //TeamTotal = result != null ? Convert.ToInt32(result) / 100 : 0;
            }
            //foreach (var item in devices)
            //{
            //    //var record = weight.GetOneByDevice(item.Id);
            //    var result = weight.GetTotal(item.Id,nextTeamDto.Id,1);
            //    var Entrance1Netweight= result != null ? Convert.ToSingle(result) : 0;
            //     var result1 = weight.GetTotal(item.Id, nextTeamDto.Id, 2);
            //    var Entrance2Netweight = result1 != null ? Convert.ToSingle(result1) : 0;
            //    //tempNetweight = Convert.ToSingle(tempNetweight);

            //    switch (item.Id)
            //    {
            //        case 1:
            //            busTcpServer.Write("2000", Entrance1Netweight);
            //            busTcpServer.Write("2002", Entrance2Netweight);
            //            break;
            //        case 2:
            //            busTcpServer.Write("2100", Entrance1Netweight);
            //            busTcpServer.Write("2102", Entrance2Netweight);
            //            break;
            //        case 3:
            //            busTcpServer.Write("2200", Entrance1Netweight);
            //            busTcpServer.Write("2202", Entrance2Netweight);
            //            break;
            //    }

            //}
            busTcpServer.Write("2000", Convert.ToSingle(0));
            busTcpServer.Write("2002", Convert.ToSingle(0));
            busTcpServer.Write("2004", Convert.ToSingle(0));
            busTcpServer.Write("2006", Convert.ToSingle(0));
            busTcpServer.Write("2008", Convert.ToSingle(0));
            busTcpServer.Write("20010", Convert.ToSingle(0));
            //switch (tempDeviceId)
            //{
            //    case 1:
            //        busTcpServer.Write("2000", netWeight);
            //        break;
            //    case 3:
            //        busTcpServer.Write("2002", netWeight);
            //        break;
            //    case 4:
            //        busTcpServer.Write("2004", netWeight);
            //        break;
            //    case 5:
            //        busTcpServer.Write("2008", netWeight);
            //        break;
            //    case 6:
            //        busTcpServer.Write("2010", netWeight);
            //        break;
            //    case 7:
            //        busTcpServer.Write("2012", netWeight);
            //        break;
            //}


        }

    }
}
