using System;
using System.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core;
using Avalonia.Data.Core.Plugins;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using MarkdownEditor.ViewModels;
using MarkdownEditor.Views;

namespace MarkdownEditor;

/// <summary>
/// Main application class.
/// Handles application initialization and lifetime management.
/// </summary>
public partial class App : Application
{
    /// <inheritdoc/>
    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
        SetupNativeMenu();
    }

    /// <summary>
    /// Sets up the native macOS menu with About dialog.
    /// </summary>
    private void SetupNativeMenu()
    {
        var appMenu = NativeMenu.GetMenu(this);
        if (appMenu != null)
        {
            // About Markle
            var aboutItem = new NativeMenuItem { Header = "About Markle" };
            aboutItem.Click += AboutMarkle_Click;
            appMenu.Items.Add(aboutItem);

            // Separator
            appMenu.Items.Add(new NativeMenuItemSeparator());

            // Services
            appMenu.Items.Add(new NativeMenuItem { Header = "Services" });

            // Separator
            appMenu.Items.Add(new NativeMenuItemSeparator());

            // Hide Ormentia Markle
            appMenu.Items.Add(new NativeMenuItem
            {
                Header = "Hide Ormentia Markle",
                Gesture = KeyGesture.Parse("Cmd+H")
            });

            // Hide Others
            appMenu.Items.Add(new NativeMenuItem
            {
                Header = "Hide Others",
                Gesture = KeyGesture.Parse("Cmd+Alt+H")
            });

            // Show All
            appMenu.Items.Add(new NativeMenuItem { Header = "Show All" });

            // Separator
            appMenu.Items.Add(new NativeMenuItemSeparator());

            // Quit
            appMenu.Items.Add(new NativeMenuItem
            {
                Header = "Quit Ormentia Markle",
                Gesture = KeyGesture.Parse("Cmd+Q")
            });
        }
    }

    /// <inheritdoc/>
    public override void OnFrameworkInitializationCompleted()
    {
        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            // Avoid duplicate validations from both Avalonia and the CommunityToolkit.
            // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
            DisableAvaloniaDataAnnotationValidation();

            // Check for file path in command line arguments
            string? initialFilePath = null;
            if (desktop.Args?.Length > 0)
            {
                // Get the first argument as potential file path
                var arg = desktop.Args[0];
                // Ensure it's a valid file path (not a flag/option)
                if (!arg.StartsWith("-") && System.IO.File.Exists(arg))
                {
                    initialFilePath = arg;
                }
            }

            desktop.MainWindow = new MainWindow
            {
                DataContext = new MainWindowViewModel(initialFilePath: initialFilePath),
            };
        }

        base.OnFrameworkInitializationCompleted();
    }

    /// <summary>
    /// Disables Avalonia's built-in data annotation validation to prevent conflicts with CommunityToolkit.
    /// </summary>
    private void DisableAvaloniaDataAnnotationValidation()
    {
        // Get an array of plugins to remove
        var dataValidationPluginsToRemove =
            BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();

        // remove each entry found
        foreach (var plugin in dataValidationPluginsToRemove)
        {
            BindingPlugins.DataValidators.Remove(plugin);
        }
    }

    /// <summary>
    /// Handles the About Markle menu item click event.
    /// </summary>
    private void AboutMarkle_Click(object? sender, EventArgs e)
    {
        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop &&
            desktop.MainWindow != null)
        {
            var aboutWindow = new AboutWindow();
            aboutWindow.ShowDialog(desktop.MainWindow);
        }
    }
}