using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using System.Windows.Threading;
using Nexus.Contracts.Apps;
using NexusShell.Services;

namespace NexusShell.ViewModels;

public sealed class DashboardViewModel : INotifyPropertyChanged
{
    private readonly ProfileService _profileService;
    private readonly AppCatalogService _catalog;
    private readonly AppLaunchService _launcher;
    private readonly DispatcherTimer _clockTimer;
    private string _clockText = DateTime.Now.ToString("HH:mm:ss");
    private string _dateText = DateTime.Now.ToString("dddd, d. MMMM yyyy");
    private string _welcomeText = "Velkommen";
    private string _statusMessage = string.Empty;

    public DashboardViewModel(
        ProfileService profileService,
        AppCatalogService catalog,
        AppLaunchService launcher)
    {
        _profileService = profileService;
        _catalog = catalog;
        _launcher = launcher;

        LaunchAppCommand = new RelayCommand(p => LaunchApp(p as AppEntry));

        _clockTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
        _clockTimer.Tick += (_, _) => UpdateClock();
        _clockTimer.Start();

        Refresh();
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    public event EventHandler? OpenLauncherRequested;
    public event EventHandler? LogoutRequested;

    public string ClockText
    {
        get => _clockText;
        set { _clockText = value; OnPropertyChanged(); }
    }

    public string DateText
    {
        get => _dateText;
        set { _dateText = value; OnPropertyChanged(); }
    }

    public string WelcomeText
    {
        get => _welcomeText;
        set { _welcomeText = value; OnPropertyChanged(); }
    }

    public string UserDisplayName => _profileService.CurrentProfile?.DisplayName ?? "Bruger";

    public string StatusMessage
    {
        get => _statusMessage;
        set { _statusMessage = value; OnPropertyChanged(); }
    }

    public IEnumerable<AppEntry> PinnedApps => _catalog.GetPinned();

    public ICommand LaunchAppCommand { get; }
    public ICommand OpenLauncherCommand => new RelayCommand(_ => OpenLauncherRequested?.Invoke(this, EventArgs.Empty));
    public ICommand LogoutCommand => new RelayCommand(_ => LogoutRequested?.Invoke(this, EventArgs.Empty));

    public void Refresh()
    {
        _profileService.LoadProfile();
        WelcomeText = $"Velkommen, {UserDisplayName}";
        OnPropertyChanged(nameof(UserDisplayName));
        OnPropertyChanged(nameof(PinnedApps));
        UpdateClock();
    }

    private void UpdateClock()
    {
        ClockText = DateTime.Now.ToString("HH:mm");
        DateText = DateTime.Now.ToString("dddd, d. MMMM yyyy");
    }

    private void LaunchApp(AppEntry? app)
    {
        if (app is null)
        {
            return;
        }

        var (result, message) = _launcher.LaunchApp(app);
        StatusMessage = result switch
        {
            LaunchResult.Success => $"{app.Name} startet",
            _ => message ?? "Kunne ikke starte app",
        };
        Refresh();
    }

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