using MegaRobo.Connections;
using MegaRobo.Connections.Sockets.Tcp;
using MegaRobo.Contract;
using MegaRobo.ControlDevices.Abstractions;
using MegaRobo.Logger;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace MegaRobo.C00225155.ControlDevices.WeightDevice
{
    public class WeightService_MT : ConnectorBase<MegaTcpClient>
    {
        public event EventHandler<TcpMessage> DataReceived;

        public override async Task<string> Initialize(ICoreService coreService, params object[] args)
        {
            this.CoreService = coreService;
            try
            {
                base.CoreService = coreService;
                if (args is [IPEndPoint remoteHost, ..])
                {
                    base.ConnectorAdapter = new MegaTcpClient
                    {
                        Logger = coreService.Logger,
                        Name = base.Name
                    };
                    if (base.ConnectorAdapter != null)
                    {
                        base.ConnectorAdapter.DataReceived += ConnectorOnDataReceived;
                    }

                    ConnectionState = await base.ConnectorAdapter.ConnectAsync(remoteHost);
                }
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                return await Task.FromResult(ex.Message);
            }
            return string.Empty;
        }

        private void ConnectorOnDataReceived(object sender, TcpMessage tcpMsg)
        {
            if (tcpMsg is null)
                return;
            var msg = tcpMsg.ParseStirng();
            if (string.IsNullOrEmpty(msg)) return;
            this.Logger.LogInformation($"接收到梅特勒称重仪_{this.Name}数据:{msg?.Trim()}");
            this.DataReceived?.Invoke(this, tcpMsg);
        }

        public override Task<ConnectionState> ReconnectAsync()
        {
            return base.ReconnectAsync();
        }

        /// <summary>
        /// 重置清零
        /// </summary>
        /// <param name="immediatly">是否立即，否：使用采用当前稳定重量值作为零点</param>
        /// <returns></returns>
        public bool Reset(bool immediately = true)
        {
            try
            {
                string command = immediately ? "ZI" : "Z";
                ConnectorAdapter.WriteLine(command);
            }
            catch (Exception ex)
            {
                base.Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService", "Reset", 150, false);
            }
            return true;
        }

        /// <summary>
        /// 去皮
        /// </summary>
        /// <param name="immediately"></param>
        /// <returns></returns>
        public bool Peel(bool immediately = true)
        {
            try
            {
                string command = immediately ? "TI" : "T";
                ConnectorAdapter.WriteLine(command);
            }
            catch (Exception ex)
            {
                base.Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService", "Peel", 150, false);
            }
            return true;
        }

        public bool ClearPeel()
        {
            try
            {
                string command = "TAC";
                ConnectorAdapter.WriteLine(command);
            }
            catch (Exception ex)
            {
                base.Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService", "ClearPeel", 150, false);
            }
            return true;
        }

        /// <summary>
        /// 读取称重值
        /// </summary>
        /// <param name="timeout"></param>
        /// <param name="immediately"></param>
        /// <returns></returns>
        public async Task<string> ReadWeightAsnyc(TimeSpan timeout, bool immediately = true)
        {
            try
            {
                string cmd = immediately ? "SI\r\n" : "S\r\n";
                byte[] sendBytes = ConnectorAdapter.StringEncoder.GetBytes(cmd);
                var tcpMessage = await ConnectorAdapter.WriteAndGetReplyAsync(sendBytes, timeout);
                if (tcpMessage is null)
                    return string.Empty;
                var result = tcpMessage.ParseStirng();
                //"S S     0.0000 g\r\n"
                //"S D     -0.0000 g\r\n"
                var match = Regex.Match(result, @"-?[0-9]+(\.[0-9]{1,4})");
                return match.Success ? match.Groups[0].Value : "";

                //这边是不是要加个校验  S   d  像你写的那样 无所谓的  因为 能读到就行  我看你的 引用地方 也没有对 非重量数值做处理
            }
            catch (Exception ex)
            {
                base.Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService", "ReadWeightAsnyc", 150, false);
            }
            return string.Empty;
        }

        /// <summary>
        /// 检测连接状态
        /// </summary>
        /// <returns></returns>
        public override async Task<ConnectionState> CheckConnected()
        {
            var state = ConnectionState.None;
            if (ConnectorAdapter is not null)
            {
                state = await ConnectorAdapter.CheckConnectedAsync();
            }
            ConnectionState = state;
            return state;
        }

    }
}
