using BOB.Services;
using CAN驱动;
using Castle.DynamicProxy;
using DeviceCommand.Base;
using DeviceCommand.Device;
using Logger;
using Model;
using Npgsql.TypeHandlers;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace BOB.Singleton
{
    public class Devices
    {
        public Devices(IContainerProvider containerProvider)
        {
            _containerProvider=containerProvider;
        }
        private IContainerProvider _containerProvider;
        private CancellationTokenSource _appCancellationTokenSource = new();
        public CancellationToken AppCancellationToken => _appCancellationTokenSource.Token;

        public Dictionary<string, object> DeviceDic { get; private set; } = new Dictionary<string, object>();
        public Dictionary<string, PollingRead> PollingReadDic { get; private set; } = new Dictionary<string, PollingRead>();

        private readonly ProxyGenerator _proxyGen = new ProxyGenerator();
        private readonly IInterceptor _loggingInterceptor = new LoggingInterceptor();

        private ISerialPort IT6724CDevice { get; set; }
        private ITcp EAEL9080Device { get; set; }
        private IModbusDevice IOBoardevice { get; set; }
        private IModbusDevice LQ7500_DDevice { get; set; }
        private ITcp PSB11000Device { get; set; }
        private IModbusDevice WS_68030_380TDevice { get; set; }
        private ITcp SQ0030G1DTDevice { get; set; }
        private IModbusDevice ZXKSTDevice { get; set; }
        private Backfeed BackfeedDevice { get; set; }

        public void Init(List<DeviceConfigModel> deviceList)
        {
            foreach (var device in deviceList)
            {
                if (!device.IsEnabled) continue;
                switch (device.DeviceType)
                {
                    case "DeviceCommand.Device.E36233A":
                        if (device.CommunicationConfig is TcpConfig tcp1)
                        {
                            BackfeedDevice = _proxyGen.CreateClassProxy<Backfeed>(
                                new object[] { tcp1 },
                                _loggingInterceptor
                            );
                            DeviceDic["Backfeed"] = BackfeedDevice;
                        }
                        break;

                    case "DeviceCommand.Device.IT6724CReverse":
                        if (device.CommunicationConfig is SerialPortConfig sp3)
                        {
                            BackfeedDevice = _proxyGen.CreateClassProxy<Backfeed>(
                                new object[] { sp3 },
                                _loggingInterceptor
                            );
                            DeviceDic["Backfeed"] = BackfeedDevice;
                        }
                        break;

                    case "DeviceCommand.Device.IT6724C":
                        if (device.CommunicationConfig is SerialPortConfig sp1)
                        {
                            var IT6724CDevice = _proxyGen.CreateClassProxy<IT6724C>(
                                new object[] { sp1.COMPort, sp1.BaudRate, sp1.DataBit, sp1.StopBit, sp1.ParityBit, sp1.ReadTimeout, sp1.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["IT6724C"] = IT6724CDevice;
                        }
                        else throw new InvalidOperationException("IT6724C 必须使用 SerialPortConfig");
                        break;

                    case "DeviceCommand.Device.LQ7500_D":
                        if (device.CommunicationConfig is SerialPortConfig sp2)
                        {
                            var LQ7500_DDevice = _proxyGen.CreateClassProxy<LQ7500_D>(
                                new object[] { sp2.COMPort, sp2.BaudRate, sp2.DataBit, sp2.StopBit, sp2.ParityBit, sp2.ReadTimeout, sp2.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["LQ7500_D"] = LQ7500_DDevice;
                        }
                        else throw new InvalidOperationException("LQ7500D 必须使用 SerialPortConfig");
                        break;

                    case "DeviceCommand.Device.EAEL9080":
                        if (device.CommunicationConfig is TcpConfig tcp2)
                        {
                            var EAEL9080Device = _proxyGen.CreateClassProxy<EAEL9080>(
                                new object[] { tcp2.IPAddress, tcp2.Port, tcp2.ReadTimeout, tcp2.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["EAEL9080"] = EAEL9080Device;
                        }
                        else throw new InvalidOperationException("EAEL9080 必须使用 TcpConfig");
                        break;

                    case "DeviceCommand.Device.IOBoard":
                        if (device.CommunicationConfig is TcpConfig tcp3)
                        {
                            var IOBoardevice = _proxyGen.CreateClassProxy<IOBoard>(
                                new object[] { tcp3.IPAddress, tcp3.Port, tcp3.ReadTimeout, tcp3.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["IOBoard"] = IOBoardevice;
                        }
                        else throw new InvalidOperationException("IOBoard 必须使用 TcpConfig");
                        break;

                    case "DeviceCommand.Device.PSB11000":
                        if (device.CommunicationConfig is TcpConfig tcp4)
                        {
                            var PSB11000Device = _proxyGen.CreateClassProxy<PSB11000>(
                                new object[] { tcp4.IPAddress, tcp4.Port, tcp4.ReadTimeout, tcp4.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["PSB11000"] = PSB11000Device;
                        }
                        else throw new InvalidOperationException("PSB11000 必须使用 TcpConfig");
                        break;

                    case "DeviceCommand.Device.WS_68030_380T":
                        if (device.CommunicationConfig is TcpConfig tcp5)
                        {
                            var WS_68030_380TDevice = _proxyGen.CreateClassProxy<WS_68030_380T>(
                                new object[] { tcp5.IPAddress, tcp5.Port, tcp5.ReadTimeout, tcp5.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["WS_68030_380T"] = WS_68030_380TDevice;
                        }
                        else throw new InvalidOperationException("WS_68030_380T 必须使用 TcpConfig");
                        break;

                    case "DeviceCommand.Device.SQ0030G1D":
                        if (device.CommunicationConfig is TcpConfig tcp7)
                        {
                            var SQ0030G1DTDevice = _proxyGen.CreateClassProxy<SQ0030G1D>(
                                new object[] { tcp7.IPAddress, tcp7.Port, tcp7.ReadTimeout, tcp7.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["SQ0030G1D"] = SQ0030G1DTDevice;
                        }
                        else throw new InvalidOperationException("SQ0030G1D 必须使用 TcpConfig");
                        break;

                    case "DeviceCommand.Device.ZXKS":
                        if (device.CommunicationConfig is TcpConfig tcp6)
                        {
                            var ZXKSTDevice = _proxyGen.CreateClassProxy<ZXKS>(
                                new object[] { tcp6.IPAddress, tcp6.Port, tcp6.ReadTimeout, tcp6.WriteTimeout },
                                _loggingInterceptor
                            );
                            DeviceDic["ZXKS"] = ZXKSTDevice;
                        }
                        else throw new InvalidOperationException("ZXKS 必须使用 TcpConfig");
                        break;

                    default:
                        throw new NotSupportedException($"未知设备类型：{device.DeviceType}");
                }


            }
        }

        public void InitCan()
        {
            同星驱动类.DisConnect();
            var re1 = 同星驱动类.Init("ATS测试系统");
            var re2 = 同星驱动类.Connect();
            if (re1 == 0  && re2 == 0)
            {
                
            }
            else
            {
               
            }
          
        }
        public async Task ConnectAllDevicesAsync()
        {
            if (DeviceDic.Count == 0)
            {
                await Task.CompletedTask;
            }

            foreach (var kvp in DeviceDic)
            {
                var name = kvp.Key;
                var device = kvp.Value;

                if (device == null)
                {
                    LoggerHelper.WarnWithNotify($"{name} 实例为空，跳过连接");
                    continue;
                }
                await Task.Delay(10);
                try
                {
                    // 检查并处理 ITcp 接口
                    if (device is ITcp itcpDevice)
                    {
                        bool result = await itcpDevice.ConnectAsync(CancellationToken.None);
                        LoggerHelper.SuccessWithNotify($"{name} 连接成功 (ITcp)");
                    }
                    // 检查并处理 IModbusDevice 接口
                    else if (device is IModbusDevice imodbusDevice)
                    {
                        bool result = await imodbusDevice.ConnectAsync(CancellationToken.None);
                        LoggerHelper.SuccessWithNotify($"{name} 连接成功 (IModbusDevice)");
                    }
                    // 检查并处理 ISerialPort 接口
                    else if (device is ISerialPort iserialPortDevice)
                    {
                        bool result = await iserialPortDevice.ConnectAsync(CancellationToken.None);
                        LoggerHelper.SuccessWithNotify($"{name} 连接成功 (ISerialPort)");
                    }
                    // 检查并处理 Backfeed  类型
                    else if (device is Backfeed backfeedDevice)
                    {
                        if(backfeedDevice.CurrentInstance is ITcp itcpDevice1)
                        {
                            bool result = await itcpDevice1.ConnectAsync(CancellationToken.None);
                        }
                        else if (backfeedDevice.CurrentInstance is ISerialPort iserialPortDevice1)
                        {
                            bool result = await iserialPortDevice1.ConnectAsync(CancellationToken.None);
                        }
                        LoggerHelper.SuccessWithNotify($"{name} 连接成功 (Backfeed)");
                    }
                    else
                    {
                        LoggerHelper.WarnWithNotify($"{name} 不是有效的设备类型");
                    }
                }
                catch(InvalidCastException ex)
                {

                }
                catch (Exception ex)
                {
                    LoggerHelper.ErrorWithNotify($"{name} 连接失败: {ex.Message}", ex.StackTrace);
                }

            }
        }
        public void StartPollingCollectionAsync()
        {
            foreach (var dc in DeviceDic)
            {
                var name = dc.Key;

                switch (name)
                {
                    case "Backfeed":
                        {
                            var polling = new BackfeedPollingRead(_containerProvider);
                            PollingReadDic.Add("Backfeed", polling);
                            polling.StartPolling();
                            break;
                        }

                    case "IT6724C":
                        {
                            var polling = new IT6724CPollingRead(_containerProvider);
                            PollingReadDic.Add("IT6724C", polling);
                            polling.StartPolling();
                            break;
                        }

                    case "LQ7500_D":
                        {
                            var polling = new LQ7500_DPollingRead(_containerProvider);
                            PollingReadDic.Add("LQ7500_D", polling);
                            polling.StartPolling();
                            break;
                        }

                    case "EAEL9080":
                        {
                            var polling = new EAEL9080PollingRead(_containerProvider);
                            PollingReadDic.Add("EAEL9080", polling);
                            polling.StartPolling();
                            break;
                        }

                    case "IOBoard":
                        {
                            
                            break;
                        }

                    case "PSB11000":
                        {
                            var polling = new PSB11000PollingRead(_containerProvider);
                            PollingReadDic.Add("PSB11000", polling);
                            polling.StartPolling();
                            break;
                        }

                    case "WS_68030_380T":
                        {
                          
                            break;
                        }

                    case "SQ0030G1D":
                        {
                           
                            break;
                        }

                    case "ZXKS":
                        {
                            var polling = new ZXKSPollingRead(_containerProvider);
                            PollingReadDic.Add("ZXKS", polling);
                            polling.StartPolling();
                            break;
                        }

                    default:
                        LoggerHelper.Warn($"未定义 {name} 的轮询处理器");
                        break;
                }
            }
        }

        public void Dispose()
        {
            _appCancellationTokenSource.Cancel();
            _appCancellationTokenSource.Dispose();
        }
    }
}
