using BPA.SingleDevice.Interface;

namespace BPA.SingleDevice.Business
{
    public class Conveyer : IConveyer
    {
        public int ID { get; set; }

        public bool[] HaveVessel { get; set; }
        public int IsReverse { get; set; }
        public int InchSpeed { get; set; }
        public int MoveSpeed { get; set; }
        public int AccTime { get; set; }
        public int MoveLength { get; set; }
        public bool MoveComplete { get; set; }

        public bool AllowMove { get; set; }

        public bool IsConnected => modbus.IsConnected();

        private readonly object mocelock = new();

        private string iP = "192.168.6.104";
        private int port = 508;
        private ModbusTcp modbus = new();

        public async Task InitialAsync()
        {
            //因为设备中间有个空位。虽然是4台设备，但是需要设置5个位置。
            HaveVessel = new bool[5];

            //这里还需写入默认参数，从文件读取，如移动速度等。
            await Task.Run(() =>
            {
                modbus.WithModbusTcp(iP, port).UseConnected(() =>
                {
                    TaskManage.GetInstance.StartLong(() =>
                    {
                        modbus.Read<ushort>("VW300".ToModbusAdd()).OnSuccess((haveVessel) =>
                        {
                            HaveVessel[0] = haveVessel.GetBitValue(1);
                            HaveVessel[1] = haveVessel.GetBitValue(2);
                            HaveVessel[2] = true;
                            HaveVessel[3] = haveVessel.GetBitValue(3);
                            HaveVessel[4] = haveVessel.GetBitValue(4);
                        });

                        modbus.Read<bool>("M0.2".ToModbusAdd()).OnSuccess((moveComplete) =>
                        {
                            MoveComplete = moveComplete;
                        });
                    }, $"Conveyer【{ID}】:ReadData", true);
                });
            });
        }

        public void SetCommParam(int id, string ip, int port = 502)
        {
            this.iP = ip;
            this.port = port;
            this.ID = id;
        }

        public void StartInchMove()
        {
            if (IsConnected)
            {
                try
                {
                    modbus.Write<ushort>("VW0".ToModbusAdd(), 1);
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.Show(ex.Message);
                }
            }
        }

        public void StopInchMove()
        {
            if (IsConnected)
            {
                try
                {
                    modbus.Write<ushort>("VW0".ToModbusAdd(), 0);
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.Show(ex.Message);
                }
            }
        }

        public bool MoveOnce()
        {
            if (IsConnected && AllowMove)
            {
                try
                {
                    lock (mocelock)
                    {
                        return modbus.Write<ushort>("VW0".ToModbusAdd(), 2).IsSuccess;
                    }
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.Show(ex.Message);
                }
            }
            return false;
        }

        public bool SetInchParam(int isReverse, uint inchSpeed)
        {
            if (IsConnected)
            {
                try
                {
                    var result1 = modbus.Write<uint>("VD100".ToModbusAdd(), inchSpeed);
                    var result2 = modbus.Write<int>("VW200".ToModbusAdd(), isReverse);
                    return result1.IsSuccess && result2.IsSuccess;
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.Show(ex.Message);
                }
            }
            return false;
        }

        public bool SetMoveParam(uint moveSpeed, uint accTime, uint moveLength)
        {
            if (IsConnected)
            {
                try
                {
                    var result1 = modbus.Write<uint>("VD104".ToModbusAdd(), moveSpeed);
                    //var result2 = modbus.Write<int>("VW122".ToModbusAdd(), accTime);
                    var result3 = modbus.Write<uint>("VD108".ToModbusAdd(), moveLength);
                    return result1.IsSuccess && result3.IsSuccess;
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.Show(ex.Message);
                }
            }
            return false;
        }

        public bool InitalMoveParam()
        {
            if (IsConnected && AllowMove)
            {
                try
                {
                    var result1= modbus.Write<bool>("M0.2".ToModbusAdd(), false).IsSuccess;
                    var result2= modbus.Write<ushort>("VW0".ToModbusAdd(), 0).IsSuccess;

                    return result1 && result2;
                }
                catch (Exception ex)
                {
                    MessageLog.GetInstance.Show(ex.Message);
                }
            }
            return false;
        }
    }
}