using MwFramework.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MainShell.Recipe.Models
{
    public class PIDOperater
    {
        public void SendPIDParameters(AxisPIDParameter axisPIDParameter)
        {
            var controller = GetControler();
            foreach (var property in axisPIDParameter.GetType().GetProperties())
            {
                var value = property.GetValue(axisPIDParameter);
                if (value is PIDLabel<double> pIDLabel)
                {
                    controller.WriteVariableBuffer(-1, axisPIDParameter.ModuleName + pIDLabel.Name, pIDLabel.Value);
                }
            }
           
        }

        public AxisPIDParameter ReadPIDParametersFromDevice(string moduleName)
        {
            var controller = GetControler();
          
            AxisPIDParameter axisPIDParameter = new AxisPIDParameter(moduleName);
            var props = axisPIDParameter.GetType()
                .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(p => p.CanRead && p.CanWrite);
            foreach (var property in props)
            {
                var value = property.GetValue(axisPIDParameter);
                if (value is PIDLabel<double> pIDLabel)
                {
                    controller.ReadVariableBuffer(-1, axisPIDParameter.ModuleName + pIDLabel.Name, out var val);
                    if (val == null)
                    {
                        continue;
                    }
                    pIDLabel.Value = Convert.ToDouble(val);
                }
            }
            return axisPIDParameter;
        }

        private IMotionController GetControler()
        {
            var hw = IoC.Get<Hardware.HardwareManager>();
            if (hw?.AcsCard?.Controller == null)
                throw new InvalidOperationException("硬件控制器未初始化 (HardwareManager.AcsCard.Controller is null).");
            return hw.AcsCard.Controller;
        }

        public void SendPIDFilteringParameters(AxisFilteringParameter pidFilteringParameter)
        {
            var controller = GetControler();
            foreach (var property in pidFilteringParameter.GetType().GetProperties())
            {
                var value = property.GetValue(pidFilteringParameter);
                if (value is PIDLabel<double> pIDLabel)
                {
                    controller.WriteVariableBuffer(-1,  pIDLabel.Name, pIDLabel.Value);
                }
                else if (value is PIDLabel<bool> pIDLabelBool)
                {
                    var val= pIDLabelBool.Value== true ? 1 : 0;
                    controller.WriteVariableBuffer(-1, pIDLabelBool.Name, val);
                }
            }
        }
        public AxisFilteringParameter ReadPIDFilteringParametersFromDevice()
        {
            var controller = GetControler();
            var axisFilteringParameter = new AxisFilteringParameter();
            var props = axisFilteringParameter.GetType()
                .GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .Where(p => p.CanRead && p.CanWrite);
            foreach (var property in props)
            {
                var value = property.GetValue(axisFilteringParameter);
                if (value is PIDLabel<double> pIDLabel)
                {
                    controller.ReadVariableBuffer(-1,  pIDLabel.Name, out var val);
                    if (val == null)
                    {
                        continue;
                    }
                    pIDLabel.Value = Convert.ToDouble(val);
                }
                else if (value is PIDLabel<bool> pIDLabelBool)
                {
                    controller.ReadVariableBuffer(-1,  pIDLabelBool.Name, out var val);
                    if (val == null)
                    {
                        continue;
                    }
                    pIDLabelBool.Value = Convert.ToInt32(val) != 0;
                }
            }
            return axisFilteringParameter;
        }
    }
}
