using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Remote.Shared.Abstractions;
using Insight.Remote.Shared.Extensions;
using Insight.Remote.Shared.Network;
using Insight.Remote.Shared.Network.Handlers;
using Insight.Remote.Windows.Services;
using Insight.Remote.Windows.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Vaitr.Network;
using Vaitr.Network.Hosting;

namespace Insight.Remote.Windows;

internal class Program
{
    public static async Task Main(string[] args)
    {
        var builder = Host.CreateDefaultBuilder(args);
        builder.UseWindowsService();

        builder.ConfigureLogging(logger =>
        {
            logger.ClearProviders();
            logger.SetMinimumLevel(LogLevel.Trace);
            logger.AddSimpleConsole(options =>
            {
                options.IncludeScopes = false;
                options.SingleLine = true;
                options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
            });

            logger.AddFilter("Microsoft", LogLevel.None);
        });

        builder.ConfigureServices(services =>
        {
            // CORE
            services.AddRemoteControlServices(options =>
            {
                options.Server = new Uri("https://localhost:7024");
            });

            services.AddSingleton<IDesktopApp, WinApp>();
            services.AddSingleton<IDispatcher, WinDispatcher>();
            services.AddSingleton<MainViewModel>();

            services.AddSingleton<IScreenProvider, WinScreenCapturer>();
            services.AddSingleton<IInputProvider, WinInputProvider>();
            services.AddSingleton<ICursorProvider, WinCursorProvider>();
            services.AddSingleton<IAudioProvider, WinAudioProvider>();
            services.AddSingleton<IClipboardProvider, WinClipboardProvider>();
            services.AddSingleton<IFileProvider, WinFileProvider>();

            // NETWORKING
            services.UseHostedClient<RemoteSession, IMessage>(options =>
            {
                options.Host = "127.0.0.1";
                options.Port = 3003;
                options.Keepalive = 10000;
                options.Timeout = 30000;
                options.Encryption = Encryption.Tls12;
                options.Compression = true;

                options.UseSerializer<RemoteSession, IMessage, MemPackSerializer<IMessage>>();
            });

            services.AddSingleton<RemoteHandler>();
            services.AddSingleton<IMessageHandler<RemoteSession>, RemoteHandler>();
        });

        var host = builder.Build();
        await host.RunAsync();
    }
}