using MegaRobo.Connections;
using MegaRobo.Connections.Modbus;
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.Tasks;
using static MegaRobo.C00225155.ControlDevices.HighTemperatureMotorControlService;
using static MegaRobo.Connections.Modbus.ModbusParams;

namespace MegaRobo.C00225155.ControlDevices
{
    public class WeightService_Ts02 : ConnectorBase<MegaTcpClient>
    {
        /// <summary>
        /// 寄存器地址枚举
        /// </summary>
        private enum MotorRegisterAddress : ushort
        {
            WeightValueLow = 0x0000,
            WeightValueHigh = 0x0002,

            /// <summary>
            /// 1：校正  2：置零
            /// </summary>
            Command = 0x0007,
            /// <summary>
            /// 1：去皮
            /// </summary>
            Peel = 0x000B,
            /// <summary>
            /// 波特率 19200
            /// </summary>
            BuartRate = 0x0010,

            Decimalpos = 0x0014,
        }

        public override async Task<string> Initialize(ICoreService coreService, params object[] args)
        {
            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 || tcpMsg.Data == null || tcpMsg.Data.Length == 0)
                return;
            string hexData = BitConverter.ToString(tcpMsg.Data).Replace("-", " ");
        }

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

        public override async Task<ConnectionState> CheckConnected()
        {
            var state = ConnectionState.None;
            if (ConnectorAdapter is not null)
            {
                state = await ConnectorAdapter.CheckConnectedAsync();
            }
            ConnectionState = state;
            return state;
        }


        /// <summary>
        /// 去皮
        /// </summary>
        /// <returns></returns>
        public async Task<bool> Peel()
        {
            try
            {
                var writeResult = ModbusRTU.WriteRegisterSingle(
                    deviceAdress: 4,  // 从站地址（默认1）
                    startAdress: (ushort)MotorRegisterAddress.Peel,
                    lstData: (ushort)1,
                    byteOrder: ByteOrder.AB  // 协议要求高字节在前
                );

                if (!writeResult.IsSuccessed)
                {
                    Logger.LogError($"去皮失败：{writeResult.Message}");
                    return false;
                }
                ConnectorAdapter.Write(writeResult.Respond);
                return true;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService_Ts02", "Peel", 150, false);
                return false;
            }
        }

        /// <summary>
        /// 置零
        /// </summary>
        /// <returns></returns>
        public async Task<bool> ResetZero()
        {
            try
            {
                var writeResult = ModbusRTU.WriteRegisterSingle(
                    deviceAdress: 4,  // 从站地址（默认1）
                    startAdress: (ushort)MotorRegisterAddress.Command,
                    lstData: (ushort)2,
                    byteOrder: ByteOrder.AB
                );

                if (!writeResult.IsSuccessed)
                {
                    Logger.LogError($"置零失败：{writeResult.Message}");
                    return false;
                }

                ConnectorAdapter.Write(writeResult.Respond);
                return true;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService_Ts02", "ResetZero", 150, false);
                return false;
            }
        }

        /// <summary>
        /// 读取称的值
        /// </summary>
        /// <returns></returns>
        public async Task<double> ReadWeightValue()
        {
            try
            {
                var readResult = ModbusRTU.GetReadMessage(
                    slaveStation: 4,
                    readType: ModbusReadCodes.READ_HOLDING_REGISTERS,  // 功能码03
                    startAdr: (ushort)MotorRegisterAddress.WeightValueLow,
                    length: 2  // 状态寄存器是1个16位寄存器，长度=1
                );

                if (readResult.IsSuccessed)
                {
                    //FF 03 00 14 00 01 D1 D0 =>  04 03 02 00 01 B5 84
                    var digitCountMessage = await ConnectorAdapter.WriteAndGetReplyAsync(new byte[] { 0xFF, 0x03, 0x00, 0x14, 0x00, 0x01, 0xD1, 0xD0 }, TimeSpan.FromSeconds(5));
                    if (digitCountMessage == null || digitCountMessage.Data == null)
                    {
                        return 0;
                    }
                    var digitCount = ModbusRTU.ReadRegisterShort(digitCountMessage.Data, ByteOrder.AB).Respond[0];
                    var tcpMessage = await ConnectorAdapter.WriteAndGetReplyAsync(readResult.Respond, TimeSpan.FromSeconds(5));
                    if (tcpMessage == null || tcpMessage.Data == null)
                    {
                        return 0;
                    }
                    var parseResult = ModbusRTU.ReadRegisterShort(tcpMessage.Data, ByteOrder.AB);
                    if (!parseResult.IsSuccessed)
                    {
                        Logger.LogError($"状态解析失败：{parseResult.Message}");
                        return 0;
                    }
                    var res = ((int)parseResult.Respond[0] | ((int)parseResult.Respond[1] << 16)) / (Math.Pow(10, digitCount));
                    return res;
                    //return parseResult.Respond[0] / 10.0;
                }
            }
            catch (Exception ex)
            {
                Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService_Ts02", "ReadWeightValue", 150, false);
                return 0;
            }
            return 0;
        }

        /// <summary>
        /// 设置小数点位数
        /// </summary>
        /// <param name="value">0~5</param>
        /// <returns></returns>
        public async Task<bool> SetDecimalPoint(ushort value)
        {
            if (value < 0 || value > 5)
            {
                return false;
            }
            try
            {
                var writeResult = ModbusRTU.WriteRegisterSingle(
                    deviceAdress: 4,  // 从站地址（默认1）
                    startAdress: (ushort)MotorRegisterAddress.Decimalpos,
                    lstData: value,
                    byteOrder: ByteOrder.AB
                );

                if (!writeResult.IsSuccessed)
                {
                    Logger.LogError($"写小数点位数失败：{writeResult.Message}");
                    return false;
                }
                ConnectorAdapter.Write(writeResult.Respond);
                return true;
            }
            catch (Exception ex)
            {
                Logger.LogException(ex, null, LogEvent.Error, null, LogLevel.Error, "WeightService_Ts02", "SetDecimalPoint", 150, false);
                return false;
            }
        }

    }
}
