using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using CommunityToolkit.Mvvm.DependencyInjection;
using Dock.Model.Controls;
using Dock.Model.Core;
using PSCHelpdesk.Events;
using PSCHelpdesk.Services;
using PSCHelpdesk.Shared.Menu;
using PSCHelpdesk.Shared.Service;
using PSCHelpdesk.Shared.ViewModels;
using ReactiveUI;

namespace PSCHelpdesk.ViewModels;

public class MainDockWindowViewModel : ViewModelBase, IViewModelBase
{
    private readonly IFactory? _factory;
    private IRootDock? _layout;
    public IRootDock? Layout
    {
        get => _layout;
        set => SetAndRaisePropertyChanged(ref _layout, value);
    }
    
    private MenuService MenuService;
    
    private List<Item> _menuItems;
    public List<Item> MenuItems
    {
        get => _menuItems;
        set => SetAndRaisePropertyChanged(ref _menuItems, value);
    }
    
    public ReactiveCommand<string, Unit> ClickMenu { get; }
    public ReactiveCommand<Unit,Unit> OpenPlugins { get; }
    public ReactiveCommand<Unit,Unit> SaveLayout { get; }
    public ReactiveCommand<Unit,Unit> LoadLayout { get; }

    public EventHandler<OpenEventArg> openTab;
    public EventHandler LoadHandler;
    public EventHandler SaveHandler;
    
    public MainDockWindowViewModel()
    {
        ClickMenu = ReactiveCommand.Create<string>(SelectMenu);
        OpenPlugins = ReactiveCommand.Create(openPlugins);
        SaveLayout = ReactiveCommand.Create(saveLayout);
        LoadLayout = ReactiveCommand.Create(loadLayout);
            
        this.MenuItems = new List<Item>();
        MenuService = (MenuService)Ioc.Default.GetService(typeof(IMenuService));
        MenuService.MenuChanged += delegate(object? sender, EventArgs args)
        {
            foreach (var menuServiceMenuItem in MenuService.MenuItems)
            {
                if (!this.MenuItems.Contains(menuServiceMenuItem))
                {
                    menuServiceMenuItem.Command = this.ClickMenu;
                    this.MenuItems.Add(menuServiceMenuItem);
                }
            }
            
            foreach (var menuServiceMenuItem in MenuService.MenuOptionItems)
            {
                if (!this.MenuItems.Contains(menuServiceMenuItem))
                {
                    menuServiceMenuItem.Command = this.ClickMenu;
                    this.MenuItems.Add(menuServiceMenuItem);
                }
            }
        };
            
        _factory = new DockFactory();
        this.InitializeClient();
    }
    
    private void InitializeClient()
    {
        Layout = _factory?.CreateLayout();
        if (Layout is { })
        {
            _factory?.InitLayout(Layout);
        }
        
        this.MenuService.CreateMenu();
    }
    
    public void SelectMenu(string parameter)
    {
        var obj = MenuItems.FirstOrDefault(menuItem => menuItem.Header == parameter.ToString(), null);
        if (obj != null)
        {
            var files = _factory?.GetDockable<IDocumentDock>("Files");
            if (Layout is { } && files is { })
            {
                _factory?.AddDockable(files, (IDocument)obj.CommandParameter);
                _factory?.SetActiveDockable((IDocument)obj.CommandParameter);
                _factory?.SetFocusedDockable(Layout, (IDocument)obj.CommandParameter);
            }
        }
    }

    void openPlugins()
    {
        var pluginM = new PluginListViewModel()
        {
            Title = "Plugins",
        };
        var files = _factory?.GetDockable<IDocumentDock>("Files");
        if (Layout is { } && files is { })
        {
            _factory?.AddDockable(files, pluginM);
            _factory?.SetActiveDockable(pluginM);
            _factory?.SetFocusedDockable(Layout, pluginM);
        }
    }
    
    void loadLayout()
    {
        this.LoadHandler?.Invoke(this, EventArgs.Empty);
    }
    
    void saveLayout()
    {
        this.SaveHandler?.Invoke(this, EventArgs.Empty);
    }
}