using System.Reflection;
using System.Text.Json;
using Fleck;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using Sln.IntelliBelt.Business;
using Sln.IntelliBelt.Business.@base;
using Sln.IntelliBelt.Common;
using Sln.IntelliBelt.Config;
using Sln.IntelliBelt.Model;
using Sln.IntelliBelt.Serilog;
using Sln.IntelliBelt.Socket;
using Sln.IntelliBelt.WebSocket;
using TouchSocket.Sockets;

namespace Sln.IntelliBelt;

class Program
{
    public static IServiceProvider? ServiceProvider = null;
    
    static async Task Main(string[] args)
    {
        var services = new ServiceCollection();

        ConfigureServices(services);
        ServiceProvider = services.BuildServiceProvider();
        ServiceProvider.UseSerilogExtensions();

        var appConfig = ServiceProvider.GetService<AppConfig>();
        var log = ServiceProvider.GetService<SerilogHelper>();
        log.Info($"系统启动成功,日志存放位置:{appConfig.logPath}");

        var _server = ServiceProvider.GetService<TcpServer>();
        _server.Init(appConfig.listernTcpPort);

        var _websocket = ServiceProvider.GetService<WebSocketHelper>();
        _websocket.Init(appConfig.listernWebSocketPort);

        
        _websocket.ReceivedMessageRequestInfoEvent += msg =>
        {
            log.Info($"收到服务端下发的设置信息：{msg}");
            var readerCommand = JsonSerializer.Deserialize<ReaderCommand>(msg);
            JObject obj = JObject.Parse(msg);
            if (readerCommand.identCode == 0x32)
            {
                var readerSetHandler = ServiceProvider.GetService<ReaderSetHandler>();
                readerSetHandler.SendSetBuffer(readerCommand);
            }else if (readerCommand.identCode == 0x70)
            {
                //获取设备信息
                var readerInfo = ServiceProvider.GetService<ReaderBufferHandler>();
                readerInfo.GetReaderParams(readerCommand);
            }
            
        };
        
        // var webSocketConnections = ServiceProvider.GetService<List<IWebSocketConnection>>();
        // while (true)
        // {
        //     
        //     log.Info($"实时打印 websocket 接入状态:{webSocketConnections.Count}");
        //     Thread.Sleep(3000);
        // }

        _server.ReceivedBufferRequestInfoEvent += (client, requestInfo) =>
        {
            BaseBusiness _business = null;
            switch (requestInfo.identCode)
            {
                case 0x32:  //暂定，实际根据终端指令
                    _business = ServiceProvider.GetService<ReaderSetHandler>();
                    break;
                case 0x30:  //设备状态
                    _business = ServiceProvider.GetService<ReaderStatusHandler>();
                    break;
                case 0x31:  //标签数据
                    _business = ServiceProvider.GetService<ReaderBufferHandler>();
                    break;
                default:
                    break;
            }
            
            if (_business != null)
            {
                Parallel.Invoke(
                    () => _business.ResponseHandle(client, requestInfo),
                    () => _business.BufferAnalysis(client, requestInfo,requestInfo.buffer.Length)
                );
            }
        };
        
        Task.Delay(-1).Wait();
    }

    private static void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<AppConfig>(provider =>
        {
            var configurationBuilder = new ConfigurationBuilder()
                .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
            IConfiguration configuration = configurationBuilder.Build();
            var ap = configuration.GetSection("AppConfig").Get<AppConfig>();
            return ap;
        });

        services.AddSingleton<List<IWebSocketConnection>>();

        Assembly[] assemblies =
        {
            Assembly.LoadFrom("Sln.IntelliBelt.Business.dll"),
            Assembly.LoadFrom("Sln.IntelliBelt.Socket.dll"),
            Assembly.LoadFrom("Sln.IntelliBelt.Common.dll"),
        };

        services.Scan(scan => scan.FromAssemblies(assemblies)
            .AddClasses()
            .AsImplementedInterfaces()
            .AsSelf()
            .WithSingletonLifetime());

        services.AddSingleton(typeof(TcpService));
        services.AddSingleton(typeof(SerilogHelper));
        services.AddSingleton(typeof(WebSocketHelper));
    }
}