using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Inspectron.Settings;
using Ninject;
using Ninject.Extensions.ChildKernel;
using VisionBuilder.UI.Common;
using VisionBuilder.UI.Common.Plugins;
using VisionBuilder.UI.Common.Processing;
using VisionBuilder.UI.Common.Services;
using VisionBuilder.UI.Common.ViewModel;
using VisionBuilder.UI.IOCommander;
using VisionBuilder.UI.Recipes.HawkeyeRecipe;
using VisionBuilder.UI.Ringbuffer;
using VisionBuilder.UI.Statistics;
using VisionBuilder.UI.Avalonia;
using VisionBuilder.UI.Avalonia.Uno.Views;
using Lindt.Colorballs.Duo.Utils;
using VisionBuilder.UI.Camera;

namespace VisionBuilder.UI.Avalonia.Uno;

public class App : Application
{
    private const string CAMERA1 = "Camera 1";

    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
    }

    public override void OnFrameworkInitializationCompleted()
    {
        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            var args = desktop.Args ?? [];
            var commandLineParser = new CommandLineParser(args);

            var settings = new InspectronSettings("../Data/Config");

            var mainKernel = Common.VisionBuilder.CreateMainKernel(settings);

            var profile = commandLineParser.GetStringArgument("profile", 'p');
            mainKernel.UsePlugins(profile);

            mainKernel
                .UseIOCommander([CAMERA1])
                .UseAvaloniaServices()
                .RegisterGlobalPlugins();

            mainKernel.Get<ILoadingService>().StartLoading("Camera initialization");

            // CAMERA 1
            ChildKernel kernelCamera1 = new ChildKernel(mainKernel);

            kernelCamera1
                .RegisterCamera(CAMERA1)
                .UseStatistics(CAMERA1)
                .UseRingbuffer(CAMERA1)
                .UseHawkeyeRecipes(CAMERA1)
                .UseCameraIOCommander(CAMERA1)
                .RegisterCameraPlugins(CAMERA1);

            // LOAD SETTINGS
            mainKernel.RegisterSettings();
            kernelCamera1.RegisterSettings();
            settings.LoadSettings();

            // Create camera and bind it (must be after settings load)
            kernelCamera1.UseCamera();

            // Initialize modules
            mainKernel.InitializeModules();
            kernelCamera1.InitializeModules();

            mainKernel.Get<ILoadingService>().StopLoading("Camera initialization");

            var mainWindowVm = mainKernel.Get<MainWindowVM>();
            mainWindowVm.SingleCameraVms = [
                kernelCamera1.Get<SingleCameraVM>()
            ];

            var avaloniaUiSettings = mainKernel.Get<AvaloniaUISettings>();
            var uiConfiguration = mainKernel.Get<UIConfiguration>();
            var passwordInputService = mainKernel.Get<IPasswordInputService>();

            settings.LoadSettings();

            desktop.MainWindow = new MainWindow(mainWindowVm, avaloniaUiSettings, uiConfiguration, passwordInputService);
        }

        base.OnFrameworkInitializationCompleted();
    }
}
