using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using NexusShell.Services;

namespace NexusShell.ViewModels;

public sealed class LoginViewModel : INotifyPropertyChanged
{
    private readonly AuthService _authService;
    private readonly Func<string, string, Task<(bool Success, string? Error)>> _loginHandler;
    private string _email = "user@nexus.local";
    private string _password = string.Empty;
    private string? _errorMessage;
    private bool _isBusy;
    private bool _loginSucceeded;

    public LoginViewModel(
        AuthService authService,
        Func<string, string, Task<(bool Success, string? Error)>>? loginHandler = null)
    {
        _authService = authService;
        _loginHandler = loginHandler ?? _authService.LoginAsync;
        LoginCommand = new RelayCommand(async _ => await LoginAsync(), _ => !IsBusy && CanSubmit);
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    public event EventHandler? LoginSucceeded;

    public string Email
    {
        get => _email;
        set
        {
            _email = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(CanSubmit));
            OnPropertyChanged(nameof(WelcomeLabel));
            OnPropertyChanged(nameof(UserInitials));
            CommandManager.InvalidateRequerySuggested();
        }
    }

    public string Password
    {
        get => _password;
        set
        {
            _password = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(CanSubmit));
            CommandManager.InvalidateRequerySuggested();
        }
    }

    public string? ErrorMessage
    {
        get => _errorMessage;
        set
        {
            _errorMessage = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(HasError));
            OnPropertyChanged(nameof(LoginStatusLabel));
            OnPropertyChanged(nameof(LoginStatusDetail));
        }
    }

    public bool HasError => !string.IsNullOrWhiteSpace(ErrorMessage);

    public bool IsBusy
    {
        get => _isBusy;
        set
        {
            _isBusy = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(IsNotBusy));
            OnPropertyChanged(nameof(CanSubmit));
            OnPropertyChanged(nameof(LoginButtonLabel));
            OnPropertyChanged(nameof(LoginStatusLabel));
            OnPropertyChanged(nameof(LoginStatusDetail));
            CommandManager.InvalidateRequerySuggested();
        }
    }

    public bool IsNotBusy => !IsBusy;

    public bool LoginSucceededState
    {
        get => _loginSucceeded;
        private set
        {
            _loginSucceeded = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(LoginStatusLabel));
            OnPropertyChanged(nameof(LoginStatusDetail));
        }
    }

    public bool CanSubmit => !IsBusy && Email.Contains('@') && Password.Length > 0;

    public string LoginButtonLabel => IsBusy ? "Åbner session..." : "Log ind i Nexus";
    public string OrganizationLabel => "Ninja Nexus POC Identity";
    public string DeviceLabel => Environment.MachineName;
    public string SessionModeLabel => "Lokal Nexus OS-shell session";
    public string IdentityRealmLabel => "Identity realm: poc.local";
    public string WorkstationLabel => $"Nexus Workstation · {Environment.MachineName}";
    public string SessionHintLabel => "Identity, app-host og workspace er samlet i en lokal POC-session. Lås op for at fortsætte direkte ind i Nexus.";
    public string WorkspaceSignalLabel => "Workspace ready";
    public string IdentityHandshakeLabel => "Identity API handshake";
    public string LocalApiLabel => "localhost:5050 aktiv";
    public string PolicyModeLabel => "Policy guard";
    public string PolicyModeDetail => "Desktop escape blokeret";
    public string AppSurfaceLabel => "Nexus app surface";
    public string AppSurfaceDetail => "Browser · Files · Store · Console";
    public string AccessFooterLabel => "Lokalt provisioneret profil. Ingen eksterne credentials vises på loginfladen.";
    public string AuthGateLabel => "IDENTITY GATE";
    public string PasswordHelperLabel => "Indtast den lokale POC-adgang for at åbne workspace.";
    public string LoginStatusLabel =>
        LoginSucceededState ? "Session godkendt" :
        IsBusy ? "Forbinder til Identity API" :
        HasError ? "Login kræver opmærksomhed" :
        "Klar til login";
    public string LoginStatusDetail =>
        LoginSucceededState ? "Workspace åbnes nu" :
        IsBusy ? "Validerer credentials og henter profil" :
        HasError ? ErrorMessage ?? "Prøv igen" :
        "Passwordfeltet er aktivt";

    public string WelcomeLabel => string.IsNullOrWhiteSpace(Email)
        ? "Klar til Nexus-session"
        : $"Fortsæt som {Email}";

    public string UserInitials
    {
        get
        {
            var source = string.IsNullOrWhiteSpace(Email) ? "N" : Email.Trim();
            return source[..1].ToUpperInvariant();
        }
    }

    public string PocCredentialsLabel => "POC-adgang er provisioneret lokalt via setup.";
    public string SwitchUserLabel => "Skift bruger";
    public string ForgotAccessLabel => "Glemt adgang?";

    public ICommand LoginCommand { get; }

    private async Task LoginAsync()
    {
        ErrorMessage = null;
        LoginSucceededState = false;
        IsBusy = true;
        try
        {
            var (success, error) = await _loginHandler(Email, Password);
            if (success)
            {
                LoginSucceededState = true;
                LoginSucceeded?.Invoke(this, EventArgs.Empty);
            }
            else
            {
                ErrorMessage = error;
            }
        }
        finally
        {
            IsBusy = false;
        }
    }

    private void OnPropertyChanged([CallerMemberName] string? name = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
