using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using NexusInstaller.Models;

namespace NexusInstaller.Converters;

public sealed class RequirementStatusBrushConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is not RequirementStatus status)
        {
            return Brushes.Gray;
        }

        return status switch
        {
            RequirementStatus.Ok => new SolidColorBrush(Color.FromRgb(0x22, 0xC5, 0x5E)),
            RequirementStatus.Installing => new SolidColorBrush(Color.FromRgb(0x2D, 0x9C, 0xFF)),
            RequirementStatus.Warning => new SolidColorBrush(Color.FromRgb(0xF5, 0x9E, 0x0B)),
            RequirementStatus.Missing or RequirementStatus.Error => new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44)),
            RequirementStatus.NotChecked => new SolidColorBrush(Color.FromRgb(0x8B, 0x9C, 0xB8)),
            _ => Brushes.Gray,
        };
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public class InstallStepStatusBrushConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is not InstallStepStatus status)
        {
            return new SolidColorBrush(Color.FromRgb(0x33, 0x44, 0x55));
        }

        return status switch
        {
            InstallStepStatus.Completed => new SolidColorBrush(Color.FromRgb(0x22, 0xC5, 0x5E)),
            InstallStepStatus.Running => new SolidColorBrush(Color.FromRgb(0x2D, 0x9C, 0xFF)),
            InstallStepStatus.Retrying => new SolidColorBrush(Color.FromRgb(0xF5, 0x9E, 0x0B)),
            InstallStepStatus.Skipped => new SolidColorBrush(Color.FromRgb(0x8B, 0x9C, 0xB8)),
            InstallStepStatus.Failed => new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44)),
            InstallStepStatus.Blocked => new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44)),
            _ => new SolidColorBrush(Color.FromRgb(0x33, 0x44, 0x55)),
        };
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class InstallStepStatusBorderBrushConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is not InstallStepStatus status)
        {
            return new SolidColorBrush(Color.FromRgb(0x28, 0xFF, 0xFF));
        }

        return status switch
        {
            InstallStepStatus.Running => new SolidColorBrush(Color.FromRgb(0x88, 0x00, 0xD9)),
            InstallStepStatus.Retrying => new SolidColorBrush(Color.FromRgb(0x88, 0xF5, 0x9E)),
            InstallStepStatus.Completed => new SolidColorBrush(Color.FromRgb(0x66, 0x22, 0xC5)),
            InstallStepStatus.Failed or InstallStepStatus.Blocked => new SolidColorBrush(Color.FromRgb(0x88, 0xEF, 0x44)),
            InstallStepStatus.Skipped => new SolidColorBrush(Color.FromRgb(0x44, 0x8B, 0x9C)),
            _ => new SolidColorBrush(Color.FromRgb(0x28, 0xFF, 0xFF)),
        };
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class InstallStepStatusPillBrushConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        var pill = value as string ?? string.Empty;
        return pill switch
        {
            "Færdig" => new SolidColorBrush(Color.FromRgb(0x22, 0xC5, 0x5E)),
            "Fejl" => new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44)),
            "Timeout" => new SolidColorBrush(Color.FromRgb(0xF5, 0x9E, 0x0B)),
            "Installerer" => new SolidColorBrush(Color.FromRgb(0x2D, 0x9C, 0xFF)),
            _ => new SolidColorBrush(Color.FromRgb(0x8B, 0x9C, 0xB8)),
        };
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class InstallProgressEventKindBrushConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is not InstallProgressEventKind kind)
        {
            return new SolidColorBrush(Color.FromRgb(0x8B, 0x9C, 0xB8));
        }

        return kind switch
        {
            InstallProgressEventKind.Error or InstallProgressEventKind.StepFailed => new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44)),
            InstallProgressEventKind.Warning or InstallProgressEventKind.Timeout or InstallProgressEventKind.FileLock => new SolidColorBrush(Color.FromRgb(0xF5, 0x9E, 0x0B)),
            InstallProgressEventKind.StepCompleted => new SolidColorBrush(Color.FromRgb(0x22, 0xC5, 0x5E)),
            InstallProgressEventKind.StepRetrying => new SolidColorBrush(Color.FromRgb(0x2D, 0x9C, 0xFF)),
            _ => new SolidColorBrush(Color.FromRgb(0x00, 0xD9, 0xFF)),
        };
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class InstallStepActiveOpacityConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is InstallStepStatus status &&
            status is InstallStepStatus.Running or InstallStepStatus.Retrying)
        {
            return 1.0;
        }

        return 0.72;
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class InstallStepRowBackgroundConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is not InstallStepStatus status)
        {
            return new SolidColorBrush(Color.FromArgb(0x18, 0x08, 0x14, 0x28));
        }

        return status switch
        {
            InstallStepStatus.Running => new SolidColorBrush(Color.FromArgb(0x28, 0x2D, 0x9C, 0xFF)),
            InstallStepStatus.Retrying => new SolidColorBrush(Color.FromArgb(0x28, 0xF5, 0x9E, 0x0B)),
            InstallStepStatus.Completed => new SolidColorBrush(Color.FromArgb(0x20, 0x22, 0xC5, 0x5E)),
            InstallStepStatus.Failed or InstallStepStatus.Blocked => new SolidColorBrush(Color.FromArgb(0x28, 0xEF, 0x44, 0x44)),
            _ => new SolidColorBrush(Color.FromArgb(0x18, 0x08, 0x14, 0x28)),
        };
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

// Legacy aliases used by existing XAML keys until fully migrated.
public sealed class InstallPhaseBrushConverter : InstallStepStatusBrushConverter;
public sealed class InstallPhaseLabelConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        if (value is InstallStepStatus status)
        {
            return status switch
            {
                InstallStepStatus.Pending => "Afventer",
                InstallStepStatus.Running => "Kører",
                InstallStepStatus.Completed => "Færdig",
                InstallStepStatus.Failed => "Fejl",
                InstallStepStatus.Blocked => "Blokeret",
                InstallStepStatus.Skipped => "Sprunget over",
                InstallStepStatus.Retrying => "Genprøver",
                _ => string.Empty,
            };
        }

        return string.Empty;
    }

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        value is true ? Visibility.Visible : Visibility.Collapsed;

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class InverseBoolToVisibilityConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        value is true ? Visibility.Collapsed : Visibility.Visible;

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

public sealed class StringToVisibilityConverter : IValueConverter
{
    public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        string.IsNullOrWhiteSpace(value as string)
            ? Visibility.Collapsed
            : Visibility.Visible;

    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}
