using Aitex.Common.Util;
using Aitex.Core.RT.ConfigCenter;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.CommonData.PowerSupplier;
using MECF.Framework.Common.Device.LinMot;
using MECF.Framework.Common.Layout;
using MECF.Framework.Common.TwinCat;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MECF.Framework.Common.Device.PowerSupplier
{
    public class PowerSupplierDeviceConfigManager : Singleton<PowerSupplierDeviceConfigManager>
    {
        #region 常量
        #endregion
        #region 内部变量
        /// <summary>
        /// PowerSupplier对象字典(key-名称,value-PowerSupplier对象)
        /// </summary>
        private Dictionary<string, PowerSupplierDevice> _namePowerSupplierDic = new Dictionary<string, PowerSupplierDevice>();
        /// <summary>
        /// Modbus通信对象字典(key-名称,value
        /// </summary>
        private Dictionary<string, PowerSupplierModbusDevice> _nameModbusDeviceDic = new Dictionary<string, PowerSupplierModbusDevice>();
        /// <summary>
        /// 模块变量注册事件字典
        /// </summary>
        private Dictionary<string, BeckhoffDelegate.OnUpdateModuleVariableValue> _moduleVariableActionDic = new Dictionary<string, BeckhoffDelegate.OnUpdateModuleVariableValue>();
        /// <summary>
        /// 地址模块字典(key-母级模块,value-supplier device模块名称
        /// </summary>
        private Dictionary<string, string> _powerSupplierDeviceAddressModuleDic = new Dictionary<string, string>();
        #endregion
        /// <summary>
        /// 初始化
        /// </summary>
        public void Initialize()
        {
            bool isSimulate = SC.GetValue<bool>("System.IsSimulatorMode");
            string xmlPath = "";
            try
            {
                if (isSimulate)
                {
                    xmlPath = PathManager.GetCfgDir() + "Devices\\PowerSupplierCfg-Simulator.xml";
                }
                else
                {
                    xmlPath = PathManager.GetCfgDir() + "Devices\\PowerSupplierCfg.xml";
                }
                PowerSupplierDeviceConfigCfg cfg = CustomXmlSerializer.Deserialize<PowerSupplierDeviceConfigCfg>(new FileInfo(xmlPath));
                if (cfg != null)
                {
                    foreach (PowerSupplierDeviceConfig config in cfg.PowerSupplierDeviceConfigs)
                    {
                        PowerSupplierModbusDevice modbusDevice = new PowerSupplierModbusDevice(config.Name, config.IpAddress, config.Port);
                        modbusDevice.ReceiveTimeout = config.RecvTimeout;
                        modbusDevice.SendTimeout = config.SendTimeout;
                        InitialDeviceConfig(config, modbusDevice);
                    }
                }
            }
            catch
            {
                LOG.WriteLog(eEvent.ERR_POWERSUPPLIER, "PowerSupplier", "Load power supplier xml failed");
            }
        }
        /// <summary>
        /// 启动设备
        /// </summary>
        /// <param name="name"></param>
        public void StartConnectDevice(string name)
        {
            if(_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].Start();
            }
        }
        /// <summary>
        /// 中止
        /// </summary>
        /// <param name="name"></param>
        public void Stop(string name)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].Stop();
            }
        }

        /// <summary>
        /// 电源控制模式
        /// </summary>
        /// <param name="name"></param>
        public bool SetChannelPowerControl(string name,byte channel,byte remoteControl)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                return _nameModbusDeviceDic[name].SetChannelPowerControl(channel,remoteControl);
            }
            return false;   
        }
        /// <summary>
        /// 初始化设备
        /// </summary>
        /// <param name="config"></param>
        private void InitialDeviceConfig(PowerSupplierDeviceConfig config,PowerSupplierModbusDevice modbusDevice)
        {
            foreach (PowerSupplierDevice item in config.Devices)
            {
                _nameModbusDeviceDic[item.Name] = modbusDevice;
                _namePowerSupplierDic[item.Name] = item;
                _powerSupplierDeviceAddressModuleDic[$"{config.Name}.{item.Address}"] = item.Name;
            }
        }
        /// <summary>
        /// 获取PowerSupplier对象
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public PowerSupplierDevice GetPowerSupplierDeviceByName(string name)
        {
            return _namePowerSupplierDic.ContainsKey(name) ? _namePowerSupplierDic[name] : null;
        }
        /// <summary>
        /// 获取当前电压电流
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        public void GetChannelCurrentAndVoltage(string name,byte channel)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].GetChannelVoltageAndCurrent(channel);
            }
        }
        /// <summary>
        /// 获取通道输出开关控制
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        public void GetChannelOutputSwitch(string name,byte channel)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].GetChannelOutput(channel);
            }
        }
        /// <summary>
        /// 获取通道电流设置数值
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        public void GetChannelCurrentSetting(string name, byte channel)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].GetChannelCurrentSetting(channel);
            }
        }
        /// <summary>
        /// 设置通道输出开关控制
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <param name="enabled"></param>
        public bool SetChannelOutputSwitchControl(string name, byte channel, bool enabled)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                return _nameModbusDeviceDic[name].SetChannelOutputSwitchControl(channel, enabled);
            }
            return false;
        }

        /// <summary>
        /// 设置通道输出开关控制
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        public void GetChannelPowerControl(string name, byte channel)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].GetChannelPowerControl(channel);
            }
        }
        /// <summary>
        /// 设置通道输出开关控制
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <param name="enabled"></param>
        public bool SetChannelCurrent(string name, byte channel, ushort current)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                return _nameModbusDeviceDic[name].SetCurrentValue(channel, current);
            }
            return false;
        }
        /// <summary>
        /// 启动步阶
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <param name="stepPeriodDatas"></param>
        public bool SetStepPeriod(string name,byte channel,List<PowerSupplierStepPeriodData> stepPeriodDatas,int scale)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                return _nameModbusDeviceDic[name].SetStepPeriod(channel, stepPeriodDatas,scale);
            }
            return false;
        }
        /// <summary>
        /// 启动步阶
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <param name="startStep"></param>
        /// <param name="endStep"></param>
        /// <param name="cycle"></param>
        public bool StartStepPeriod(string name,byte channel,ushort startStep,ushort endStep,ushort cycle)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                return _nameModbusDeviceDic[name].StartStepPeriod(channel,startStep,endStep, cycle);
            }
            return false;
        }
        /// <summary>
        /// 设置电源运行模式
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <param name="model"></param>
        public bool SetPowerRunmodelControl(string name,byte channel,byte model)
        {
            if(_nameModbusDeviceDic.ContainsKey(name))
            {
                return _nameModbusDeviceDic[name].SetChannelPowerRunmodelControl(channel, model);
            }
            return false;
        }

        /// <summary>
        /// 设置电源运行模式
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <param name="model"></param>
        public void GetPowerRunmodelControl(string name, byte channel)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].GetChannelPowerRunModel(channel);
            }
        }
        /// <summary>
        /// 获取通道电源状态
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        public bool SetChannelPowerStatus(string name, byte channel,byte powerstatus)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                return _nameModbusDeviceDic[name].SetChannelPowerStatus(channel,powerstatus);
            }
            return false;
        }
        /// <summary>
        /// 获取通道电源状态
        /// </summary>
        /// <param name="name"></param>
        /// <param name="channel"></param>
        /// <returns></returns>
        public void GetChannelPowerStatus(string name, byte channel)
        {
            if (_nameModbusDeviceDic.ContainsKey(name))
            {
                _nameModbusDeviceDic[name].GetChannelPowerStatus(channel);
            }
        }
        /// <summary>
        /// 注册变量数值发生变化回调
        /// </summary>
        /// <param name="moduleName"></param>
        /// <param name="variable"></param>
        /// <param name="onUpdateModuleVariableValue"></param>
        public void SubscribeModuleVariable(string moduleName, string variable, BeckhoffDelegate.OnUpdateModuleVariableValue onUpdateModuleVariableValue)
        {
            _moduleVariableActionDic[$"{moduleName}.{variable}"] = onUpdateModuleVariableValue;
        }
        /// <summary>
        /// 更新模块变量数值
        /// </summary>
        /// <param name="module"></param>
        /// <param name="channel"></param>
        /// <param name="variable"></param>
        /// <param name="value"></param>
        public void UpdateModuleVariable(string module,byte channel,string variable,object value)
        {
            string itemModulaName = GetModuleNameByAddress(module, channel);
            if(!string.IsNullOrEmpty(itemModulaName))
            {
                string key = $"{itemModulaName}.{variable}";
                if(_moduleVariableActionDic.ContainsKey(key))
                {
                    _moduleVariableActionDic[key].Invoke(variable, value);
                }
            }
        }
        /// <summary>
        /// 获取模块连接状态
        /// </summary>
        /// <param name="module"></param>
        /// <returns></returns>
        public bool GetModuleConnected(string module)
        {
            return _nameModbusDeviceDic.ContainsKey(module) ? _nameModbusDeviceDic[module].Connected : false;
        }

        /// <summary>
        /// 根据地址获取模块名称
        /// </summary>
        /// <param name="name"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public string GetModuleNameByAddress(string name, byte id)
        {
            if (_powerSupplierDeviceAddressModuleDic.ContainsKey($"{name}.{id}"))
            {
                return _powerSupplierDeviceAddressModuleDic[$"{name}.{id}"];
            }
            return "";
        }
    }
}