using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Media;
using Avalonia.Threading;
using ReactiveUI;
using ReactiveUI.Validation.Helpers;
using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using VeloeMinecraftLauncher.MinecraftLauncher;
using VeloeMinecraftLauncher.Views;

namespace VeloeMinecraftLauncher.ViewModels;

public class ViewModelBase : ReactiveValidationObject
{
    public ViewModelBase()
    {
        this.RaisePropertyChanged(nameof(InterfaceColor));
        this.RaisePropertyChanged(nameof(MaterialOpacity));

    }
    public Color InterfaceColor
    {
        get => Color.Parse("Black");
        set => this.RaisePropertyChanged(nameof(InterfaceColor));
    }

    public float MaterialOpacity
    {
        get => 0.5F;
        set => this.RaisePropertyChanged(nameof(MaterialOpacity));
    }

    public static void OpenErrorWindow(Exception ex)
    {
        string message = "";
        string stackTrace = "";
        string logfile = "";
        Exception? innerException;
        switch (ex)
        {
            case WebException or Win32Exception or JavaProcessException or IOException:
                message = ex.Message;
                Settings.logger.Error(ex.Message);

                if (ex is JavaProcessException)
                {
                    if (Path.Exists(((JavaProcessException)ex).LogPath))
                        logfile = ((JavaProcessException)ex).LogPath;                   
                }

                if (ex.StackTrace is not null)
                    Settings.logger.Error(ex.StackTrace);
                innerException = ex.InnerException;
                while (innerException is not null)
                {
                    Settings.logger.Error(innerException.Message);
                    if (innerException.StackTrace is not null)
                        Settings.logger.Error(innerException.StackTrace);
                    innerException = innerException.InnerException;
                }
                break;
            default:
                message = ex.Message;
                stackTrace = ex.StackTrace ?? "";
                Settings.logger.Error(ex.Message);
                if (ex.StackTrace is not null)
                    Settings.logger.Error(ex.StackTrace);
                innerException = ex.InnerException;
                while (innerException is not null)
                {
                    message += "\n" + innerException.Message;
                    stackTrace += "\n" + innerException.StackTrace;
                    Settings.logger.Error(innerException.Message);
                    if (innerException.StackTrace is not null)
                        Settings.logger.Error(innerException.StackTrace);
                    innerException = innerException.InnerException;
                }
                break;
        }       

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        Dispatcher.UIThread.InvokeAsync(() =>
        {
        if (Application.Current is not null && Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
            {
                Dispatcher.UIThread.InvokeAsync(() =>
                {
                    var ErrorMessageViewModel = new ErrorWindowViewModel(message, stackTrace, logfile:logfile);
                    var ErrorMessage = new ErrorWindow()
                    {
                        DataContext = ErrorMessageViewModel
                    };
                    ErrorMessage.ShowDialog(desktop.MainWindow);
                });
            }
        });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
    }

    public static void OpenErrorWindow(string message, string logfile = "")
    {       
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        Dispatcher.UIThread.InvokeAsync(() =>
        {
            if (Application.Current is not null && Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
            {
                Dispatcher.UIThread.InvokeAsync(() =>
                {
                    var ErrorMessageViewModel = new ErrorWindowViewModel(message, logfile: logfile);
                    var ErrorMessage = new ErrorWindow()
                    {
                        DataContext = ErrorMessageViewModel
                    };
                    ErrorMessage.ShowDialog(desktop.MainWindow);
                });
            }
        });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
    }
}

