#define A    //定义符号  //条件编译
using Common.Models;
using MegaRobo.Authentication;
using MegaRobo.C00225155.AppServer;
using MegaRobo.C00225155.ControlDevices;
using MegaRobo.C00225155.ControlDevices.Scanner;
using MegaRobo.C00225155.ControlDevices.USBScanner;
using MegaRobo.C00225155.ControlDevices.WeightDevice;
using MegaRobo.C00225155.DataAccess;
using MegaRobo.C00225155.Entities;
using MegaRobo.C00225155.Entities.Entity_DB;
using MegaRobo.C00225155.Entities.ToWeb;
using MegaRobo.Contract;
using MegaRobo.ControlDevices;
using MegaRobo.ControlDevices.Models;
using MegaRobo.Entities.ViewTT;
using MegaRobo.Logger;
using MegaRobo.WpfComponents.MegaWindows;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Pipette1ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices;
using Pipette1mlCan = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.HamiltonDevices.CanDevice;
using Pipette5ml = MegaRobo.PipetteTool.HamiltonConsole.PipetteDevices.Hamilton5mlDevices;

namespace MegaRobo.C00225155App
{
    public sealed class StartupService : StartupServiceBase
    {
        private LoggerService _loggerService;
        private AppConfigService appConfigService;
        private readonly IDataAccessService dataAccessService;

        public StartupService(ICoreService coreService) : base(coreService)
        {
            this._loggerService = this.CoreService.GetServiceInstance<LoggerService>();
            this.dataAccessService = this.CoreService.GetServiceInstance<IDataAccessService>();
            this.appConfigService = this.CoreService.GetServiceInstance<AppConfigService>();
        }

        protected override async Task LoadModulesAsync()
        {
            #region 创建数据库表
            //dataAccessService.CreateTable<SourcePowderBottleModel>();  //粉末加样需要写入数据库
            //dataAccessService.CreateTable<TipBoxModel>();  //tip需要写入数据库
            dataAccessService.CreateTable<WebApiUrl>();
            dataAccessService.CreateTable<Liquid_lml_Dose>();
            //dataAccessService.CreateTable<PlcPointDict>();
            #endregion

            #region 注册登录权限服务 
            AuthService authService = AuthService.Instance;
            await authService.Initialize(this.CoreService, "电解液配置与检测");
            this.CoreService.ServiceContainer.RegisterInstance(authService);
            #endregion

            IList<Setting> settingList = await dataAccessService.LoadEntitiesAsync<Setting>();
            this.appConfigService.SettingList = settingList;
            string pattern = @"^(\d{1,3}\.){3}\d{1,3}:\d{1,5}$";
            IPEndPoint hostpoint = new IPEndPoint(IPAddress.Any, 1000);
            Setting settingItem = new Setting();
            bool isMatch = false;

            #region 和BS连接
            {
                this.ShowBusyContent($"准备HTTP客户端中..");
                ////在依赖注入容器中注册 HttpClient 相关服务，支持配置超时、重试、消息处理等策略。
                ServiceProvider serviceProvider = new ServiceCollection().AddHttpClient().BuildServiceProvider();
                //IHttpClientFactory：是.NET 官方推荐的 HttpClient 管理方式，解决了传统HttpClient实例化带来的连接池、资源泄漏等问题，能高效创建可配置的 HttpClient 实例。
                IHttpClientFactory httpClientFactory = serviceProvider.GetService<IHttpClientFactory>();
                this.CoreService.RegisterInstance(httpClientFactory);
            }

            {
                //开服务端口
                //******************接口中不要含有中文 在都请求方 含中文的Content-Length计算不正常 会导致接收的正文不完整*******************
                //HttpListenerProvider：封装了HttpListener（.NET 用于创建 HTTP 服务的类），用于监听指定 IP 和端口的 HTTP 请求，实现自定义的 HTTP 服务逻辑。
                settingItem = settingList.FirstOrDefault(x => x.Key == "HttpWatchPort");
                int port = 10001;
                if (settingItem != null && int.TryParse(settingItem.Context,out int watchPort))
                {
                    port = watchPort;
                }
                this.ShowBusyContent($"打开对BS服务端口 {port} 中..");
                HttpListenerProvider httpListenerProvider = new HttpListenerProvider(this.Logger);
                httpListenerProvider.GetOrAdd(this.appConfigService.ProjectInfo.Code, new IPEndPoint(IPAddress.Any, port));
                this.CoreService.RegisterInstance(httpListenerProvider);
            }
            #endregion

            #region Labx软件注册
            LabxService labxService = new LabxService();
            this.CoreService.RegisterInstance<LabxService>(labxService);
            #endregion


            #region 扫码枪
            this.ShowBusyContent($"连接投料站粉末扫码枪中..");
            settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.Scanner_Powder.ToString());
            isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            if (settingItem != null && isMatch)
            {
                hostpoint = IPEndPoint.Parse(settingItem.Context);
            }
            ScannerService powderscannerService = new() { Name = DeviceNames.Scanner_Powder.ToString() };
            await powderscannerService.Initialize(this.CoreService, hostpoint);
            this.CoreService.RegisterInstance(powderscannerService, DeviceNames.Scanner_Powder.ToString());

            this.ShowBusyContent($"连接投料站扫码枪中..");
            settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.Scanner.ToString());
            isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            if (settingItem != null && isMatch)
            {
                hostpoint = IPEndPoint.Parse(settingItem.Context);
            }
            ScannerService scannerService = new() { Name = DeviceNames.Scanner.ToString() };
            await scannerService.Initialize(this.CoreService, hostpoint);
            this.CoreService.RegisterInstance(scannerService, DeviceNames.Scanner.ToString());

            //this.ShowBusyContent($"连接反应站扫码枪..");
            //settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.Scanner_React.ToString());
            //isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            //if (settingItem != null && isMatch)
            //{
            //    hostpoint = IPEndPoint.Parse(settingItem.Context);
            //}
            //ScannerService reactScanner = new() { Name = DeviceNames.Scanner_React.ToString() };
            //await reactScanner.Initialize(this.CoreService, hostpoint);
            //this.CoreService.RegisterInstance(reactScanner, DeviceNames.Scanner_React.ToString());

            //this.ShowBusyContent($"连接反应站料仓架扫码枪..");
            //settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.Scanner_ReactRack.ToString());
            //isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            //if (settingItem != null && isMatch)
            //{
            //    hostpoint = IPEndPoint.Parse(settingItem.Context);
            //}
            //ScannerService reactScannerService = new() { Name = DeviceNames.Scanner_ReactRack.ToString() };
            //await reactScannerService.Initialize(this.CoreService, hostpoint);
            //this.CoreService.RegisterInstance(reactScannerService, DeviceNames.Scanner_ReactRack.ToString());
            #endregion

            #region  投料站预称重  TS02称重仪
            this.ShowBusyContent($"连接投料站预称重仪中..");
            settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.PreWeight.ToString());
            isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            if (settingItem != null && isMatch)
            {
                hostpoint = IPEndPoint.Parse(settingItem.Context.Trim());
            }
            WeightService_Ts02 weightService_ts = new WeightService_Ts02() { Name = DeviceNames.PreWeight.ToString() };
            await weightService_ts.Initialize(this.CoreService, hostpoint);
            this.CoreService.RegisterInstance(weightService_ts, DeviceNames.PreWeight.ToString());
            #endregion
#if Aa
            #region 高温震荡模块
            //this.ShowBusyContent($"连接高温震荡模块中..");
            //settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.HightTemperatureShake.ToString());
            //isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            //if (settingItem != null && isMatch)
            //{
            //    hostpoint = IPEndPoint.Parse(settingItem.Context.Trim());
            //}
            //HighTemperatureShakeService highTempertureshake = new HighTemperatureShakeService() { Name = DeviceNames.HightTemperatureShake.ToString() };
            //await highTempertureshake.Initialize(this.CoreService, hostpoint);
            //this.CoreService.RegisterInstance(highTempertureshake, DeviceNames.HightTemperatureShake.ToString());

            //this.ShowBusyContent($"连接高温震荡模块电机中..");
            //settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.HightTemperatureMotor.ToString());
            //isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            //if (settingItem != null && isMatch)
            //{
            //    hostpoint = IPEndPoint.Parse(settingItem.Context.Trim());
            //}
            //HighTemperatureMotorControlService highTemperturemotor = new HighTemperatureMotorControlService() { Name = DeviceNames.HightTemperatureMotor.ToString() };
            //await highTemperturemotor.Initialize(this.CoreService, hostpoint);
            //this.CoreService.RegisterInstance(highTemperturemotor, DeviceNames.HightTemperatureMotor.ToString());
            #endregion

            #region 低温磁力搅拌模块
            //this.ShowBusyContent($"连接低温磁力搅拌模块中..");
            //settingItem = settingList.FirstOrDefault(x => x.Key == DeviceNames.LowTemperatureMagneticStir.ToString());
            //isMatch = Regex.IsMatch(settingItem?.Context, pattern);
            //if (settingItem != null && isMatch)
            //{
            //    hostpoint = IPEndPoint.Parse(settingItem.Context.Trim());
            //}
            //LowTemperatureMagneticStirService lowTempertureMagneticStir = new LowTemperatureMagneticStirService() { Name = DeviceNames.LowTemperatureMagneticStir.ToString() };
            //await lowTempertureMagneticStir.Initialize(this.CoreService, hostpoint);
            //this.CoreService.RegisterInstance(lowTempertureMagneticStir, DeviceNames.LowTemperatureMagneticStir.ToString());
            #endregion
#endif
            #region 移液枪服务注册
            try
            {
                //获取连接设备的 USBCAN的SN码集合 --盒背面 SN码，CanService能连接多个枪头
                var canService = new Pipette1mlCan.CanService();
                var serialNumberList = canService.LoadSerialNumberList();
                foreach (var strSN in serialNumberList)
                {
                    var setting = settingList.FirstOrDefault(x => x.Context == strSN.Value);
                    if (setting is null)
                        continue;
                    if (setting.Key.Contains("Dose_1ml"))
                    {
                        Pipette1ml.PipetteService pipetteService = null;
                        pipetteService = new Pipette1ml.PipetteService() { Name = DeviceNames.Pipette_Dose_1ml.ToString() };
                        var pipetteConfig = new Pipette1ml.PipetteServiceConfig
                        {
                            DeviceIndex = strSN.Key,
                            SerialNumber = strSN.Value,
                            Timeout = new TimeSpan(0, 3, 0),
                            IdList = new uint[] { 1, 2, 3, 4 } //枪的拨号 入多枪 IdList = new uint[] {1,2,3,4} 
                        };
                        await pipetteService.Initialize(this.CoreService, pipetteConfig);
                        this.CoreService.RegisterInstance(pipetteService, pipetteService.Name);
                    }
                    //else if (setting.Key.Contains("Dose_1ml_2"))
                    //{
                    //    Pipette1ml.PipetteService pipetteService = null;
                    //    pipetteService = new Pipette1ml.PipetteService() { Name = DeviceNames.Pipette_Dose_1ml_2.ToString() };
                    //    var pipetteConfig = new Pipette1ml.PipetteServiceConfig
                    //    {
                    //        DeviceIndex = strSN.Key,
                    //        SerialNumber = strSN.Value,
                    //        Timeout = new TimeSpan(0, 3, 0),
                    //        IdList = new uint[] { 2 }
                    //    };
                    //    await pipetteService.Initialize(this.CoreService, pipetteConfig);
                    //    this.CoreService.RegisterInstance(pipetteService, pipetteService.Name);
                    //}
                    //else if (setting.Key.Contains("Dose_1ml_3"))
                    //{
                    //    Pipette1ml.PipetteService pipetteService = null;
                    //    pipetteService = new Pipette1ml.PipetteService() { Name = DeviceNames.Pipette_Dose_1ml_3.ToString() };
                    //    var pipetteConfig = new Pipette1ml.PipetteServiceConfig
                    //    {
                    //        DeviceIndex = strSN.Key,
                    //        SerialNumber = strSN.Value,
                    //        Timeout = new TimeSpan(0, 3, 0),
                    //        IdList = new uint[] { 3 }
                    //    };
                    //    await pipetteService.Initialize(this.CoreService, pipetteConfig);
                    //    this.CoreService.RegisterInstance(pipetteService, pipetteService.Name);
                    //}
                    //else if (setting.Key.Contains("Dose_1ml_4"))
                    //{
                    //    Pipette1ml.PipetteService pipetteService = null;
                    //    pipetteService = new Pipette1ml.PipetteService() { Name = DeviceNames.Pipette_Dose_1ml_4.ToString() };
                    //    var pipetteConfig = new Pipette1ml.PipetteServiceConfig
                    //    {
                    //        DeviceIndex = strSN.Key,
                    //        SerialNumber = strSN.Value,
                    //        Timeout = new TimeSpan(0, 3, 0),
                    //        IdList = new uint[] { 4 }
                    //    };
                    //    await pipetteService.Initialize(this.CoreService, pipetteConfig);
                    //    this.CoreService.RegisterInstance(pipetteService, pipetteService.Name);
                    //}
                    //else if (setting.Key.Contains("React_1ml"))
                    //{
                    //    Pipette1ml.PipetteService pipetteService = null;
                    //    pipetteService = new Pipette1ml.PipetteService() { Name = DeviceNames.Pipette_React_1ml.ToString() };
                    //    var pipetteConfig = new Pipette1ml.PipetteServiceConfig
                    //    {
                    //        DeviceIndex = strSN.Key,
                    //        SerialNumber = strSN.Value,
                    //        Timeout = new TimeSpan(0, 3, 0),
                    //        IdList = new uint[] { 1 }
                    //    };
                    //    await pipetteService.Initialize(this.CoreService, pipetteConfig);
                    //    this.CoreService.RegisterInstance(pipetteService, pipetteService.Name);
                    //}
                }
            }
            catch (Exception)
            {
                throw;
            }
            #endregion

            #region 与PLC连接
            Dictionary<int, string> dictModbusHead = new Dictionary<int, string>();
            dictModbusHead.Add(1, "投料站PLC");
            //dictModbusHead.Add(2, "反应站PLC");

            Dictionary<int, DeviceNames> dictmodbusName = new Dictionary<int, DeviceNames>();
            dictmodbusName.Add(1, DeviceNames.Plc1);
            //dictmodbusName.Add(2, DeviceNames.Plc2);

            foreach (var deviceName in dictmodbusName.OrderBy(x => x.Key))
                await CreateModBusService(dictModbusHead[deviceName.Key], deviceName.Value, deviceName.Key);

            async Task CreateModBusService(string _header, DeviceNames _devicesName, int devierOrder)
            {
                string pattern = @"^(\d{1,3}\.){3}\d{1,3}:\d{1,5}$";
                var header = _header;
                this.ShowBusyContent($"连接{header}中..");
                var settingItem = settingList.FirstOrDefault(x => x.Key == _devicesName.ToString());
                bool isMatch = Regex.IsMatch(settingItem?.Context, pattern);
                IModbusClientExtend client = null;
                if (isMatch)
                {
                    var host = IPEndPoint.Parse("192.168.1.40:502"); 
                    if (settingItem != null)
                        host = IPEndPoint.Parse(settingItem.Context);

                    ModbusSocketConfig socketConfig = new ModbusTcpConfig()
                    {
                        RemoteHost = host,
                        ScannerInterval = TimeSpan.FromMilliseconds(200),
                    };
                    client = new HuichuanAc801Service() { Header = header, Name = _devicesName.ToString() };
                    var warnMessage = await client.Initialize(this.CoreService, socketConfig);
                    this.WarnMessageList.Add(warnMessage);
                }
                else if ((bool)settingItem?.Context.StartsWith("F"))
                {
                    client = null;
                    return;
                }
                else
                {
                    client = this.CoreService.GetServiceInstance<IModbusClientExtend>(settingItem.Context);
                    if (client is null)
                        return;
                }
                //var pointList = this.dataAccessService.LoadEntitiesAsync<PlcPoint>(x => x.Name == _devicesName.ToString()).Result;
                //foreach (var point in pointList)
                //    client.Register<Point>(point.Address, point.Descr, point.FunType);

                this.CoreService.RegisterInstance<IModbusClientExtend>(client, _devicesName.ToString());
            }
            #endregion


            #region 注册WorkService
            WorkService workService = new WorkService();
            workService.Initialize(this.CoreService);
            this.CoreService.RegisterInstance(workService);
            #endregion
        }
    }
}
