using System.Linq;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using PSCHelpdesk.Shared.Plugin;
using PSCHelpdesk.Shared.Service;

namespace PSCHelpdesk.Services;

using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Avalonia;
using Prise;

public class PluginService
{
    private List<string> toLoadPlugins = new List<string>();
    private Dictionary<string, Contract> loadedPlugins = new Dictionary<string, Contract>();
    private Dictionary<string, string> foundPlugins = new Dictionary<string, string>();
    
    public PluginService()
    {
        this.scanPlugins();
        this.LoadPlugin("HetznerServer");
    }
    public Dictionary<string, string> GetPlugins()
    {
        return this.foundPlugins;
    }
    async private void scanPlugins()
    {
        var pluginLoader = Ioc.Default.GetService<IPluginLoader>();
        var dist = getPluginPath();
        var pluginScanResults = await pluginLoader.FindPlugins<Contract>(dist);

        var menuService = Ioc.Default.GetService<MenuService>();
        
        //components = new Dictionary<string, IAppComponent>();
        foreach (var pluginScanResult in pluginScanResults)
        {
            this.foundPlugins.Add(Path.GetFileNameWithoutExtension(pluginScanResult.AssemblyName), pluginScanResult.AssemblyPath);
        }
    }
    private string getPluginPath()
    {
        var pathToThisProgram = Assembly.GetExecutingAssembly() // this assembly location (/bin/Debug/netcoreapp3.1)
            .Location;
        var pathToExecutingDir = Path.GetDirectoryName(pathToThisProgram);
        //return Path.GetFullPath(Path.Combine(pathToExecutingDir, "../../../../../_dist"));
        return pathToExecutingDir;
    }
    async public void LoadPlugin(string pluginName)
    {
        if(this.loadedPlugins.ContainsKey(pluginName))
        {
            return;
        }
        this.toLoadPlugins.Add(pluginName);

        var pluginLoader = Ioc.Default.GetService(typeof(IPluginLoader)) as IPluginLoader;
        var menuService = Ioc.Default.GetRequiredService<IMenuService>();
        var testService = Ioc.Default.GetRequiredService<ITestService>();
        var appService = Ioc.Default.GetService(typeof(AppService)) as AppService;
        //var settingsService = Ioc.Default.GetService<SettingsManager>();
        
        var pluginAssemblies = await pluginLoader.FindPlugins<Contract>(getPluginPath());
        var pluginToEnable = pluginAssemblies.FirstOrDefault(p => Path.GetFileNameWithoutExtension(p.AssemblyName) == pluginName);

        if (pluginToEnable != null)
        {
            var plugin = await pluginLoader.LoadPlugin<Contract>(pluginToEnable, configure: (context) =>
            {
                context
                    
                    .AddHostService<IMenuService>(menuService)
                    .AddHostService<ITestService>(testService)
                    //.AddHostService<SettingsManager>(settingsService)
                    
                    ;
            });


            if (!this.loadedPlugins.ContainsKey(pluginName))
            {
                loadedPlugins.Add(plugin.GetName(), plugin);
                plugin.addMenu();
                appService.AppIsStarted();
            }
        }
    }

}
