using System.ComponentModel;

namespace NexusInstaller.Models;

public enum InstallerStep
{
    Welcome = 1,
    Requirements = 2,
    InstallPath = 3,
    Identity = 4,
    Security = 5,
    Install = 6,
}

public enum RequirementStatus
{
    NotChecked,
    Ok,
    Warning,
    Missing,
    Installing,
    Error,
}

public enum PrerequisiteKind
{
    DotNet8Desktop,
    DotNet10Desktop,
    WebView2,
    VcRedist,
    Network,
    DiskSpace,
    WriteInstallPath,
    WriteLocalAppData,
    UpdateChannel,
    WindowsVersion,
    AdminElevation,
}

public sealed class RequirementCheck
{
    public required string Label { get; init; }
    public RequirementStatus Status { get; set; }
    public required string Detail { get; init; }
    public PrerequisiteKind? Kind { get; init; }

    public bool IsAutoInstallable => Kind is PrerequisiteKind.DotNet8Desktop
        or PrerequisiteKind.DotNet10Desktop
        or PrerequisiteKind.WebView2
        or PrerequisiteKind.VcRedist;

    public string StatusDisplay => Status switch
    {
        RequirementStatus.NotChecked => "Ikke kontrolleret",
        RequirementStatus.Ok => "Installeret",
        RequirementStatus.Installing => "Installeres automatisk",
        RequirementStatus.Missing when IsAutoInstallable => "Mangler — installeres automatisk",
        RequirementStatus.Missing => "Mangler",
        RequirementStatus.Error => "Fejl",
        RequirementStatus.Warning => "Advarsel",
        _ => Status.ToString(),
    };
}

public sealed class OrganizationOption
{
    public required string Id { get; init; }
    public required string Name { get; init; }
    public string DisplayName => Name;
    public override string ToString() => DisplayName;
}

public static class OrganizationCatalog
{
    public static IReadOnlyList<OrganizationOption> All { get; } =
    [
        new() { Id = "ORG-NINJA-PLATFORME", Name = "Ninja Platforme ApS" },
        new() { Id = "ORG-NINJAKERNEN", Name = "Ninjakernen Holding ApS" },
        new() { Id = "ORG-RENNINJA", Name = "Renninja ApS" },
    ];
}

public sealed class RoleOption
{
    public required string Id { get; init; }
    public required string Name { get; init; }
    public string DisplayName => Name;
    public override string ToString() => DisplayName;
}

public static class InstallerBuildInfo
{
    public const int Build = 100;
    public const string Version = "0.1.0-storefix1";
    public const string Channel = "POC";

    public static string DisplayLabel => $"Build {Build} / {Version} / {Channel}";
}

public static class RoleCatalog
{
    public static IReadOnlyList<RoleOption> All { get; } =
    [
        new() { Id = "User", Name = "User" },
        new() { Id = "Administrator", Name = "Administrator" },
        new() { Id = "MasterDeveloper", Name = "MasterDeveloper" },
    ];
}

public enum IdentityReadinessState
{
    Pending,
    Running,
    Ready,
    Failed,
    Blocked,
}

public sealed class IdentityReadinessItem : INotifyPropertyChanged
{
    public required string Key { get; init; }
    public required string Label { get; init; }

    private IdentityReadinessState _state = IdentityReadinessState.Pending;
    private string? _detail;

    public IdentityReadinessState State
    {
        get => _state;
        set
        {
            _state = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(StatusDisplay)));
        }
    }

    public string? Detail
    {
        get => _detail;
        set
        {
            _detail = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Detail)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(StatusDisplay)));
        }
    }

    public string StatusDisplay => State switch
    {
        IdentityReadinessState.Ready => string.IsNullOrWhiteSpace(Detail) ? "Klar" : Detail,
        IdentityReadinessState.Running => string.IsNullOrWhiteSpace(Detail) ? "Kører…" : Detail,
        IdentityReadinessState.Failed => Detail ?? "Fejlet",
        IdentityReadinessState.Blocked => Detail ?? "Blokeret",
        _ => "Afventer",
    };

    public event PropertyChangedEventHandler? PropertyChanged;
}

