using System.Collections.ObjectModel;
using System.Windows.Input;
using ytLive.Helpers;
using ytLive.Services;

namespace ytLive.ViewModels;

public class MicPickerCandidate
{
    public MicrophoneDeviceInfo Device { get; }
    public string Name => Device.DisplayName;

    public MicPickerCandidate(MicrophoneDeviceInfo device)
    {
        Device = device;
    }
}

public class MicPickerViewModel : ViewModelBase
{
    private readonly IMicrophoneEnumerator _enumerator;
    private MicPickerCandidate? _selectedMic;
    private bool _isLoading = true;

    public ObservableCollection<MicPickerCandidate> Microphones { get; } = new();

    public bool IsLoading
    {
        get => _isLoading;
        private set => SetProperty(ref _isLoading, value);
    }

    public bool HasMicrophones => !IsLoading && Microphones.Count > 0;
    public bool NoMicrophones => !IsLoading && Microphones.Count == 0;

    public MicPickerCandidate? SelectedMic
    {
        get => _selectedMic;
        set
        {
            if (SetProperty(ref _selectedMic, value))
                CommandManager.InvalidateRequerySuggested();
        }
    }

    public ICommand UseSelectedCommand { get; }
    public ICommand CancelCommand { get; }

    public event Action<MicrophoneDeviceInfo>? UseRequested;
    public event Action? CancelRequested;

    public MicPickerViewModel(IMicrophoneEnumerator enumerator)
    {
        _enumerator = enumerator;
        UseSelectedCommand = new RelayCommand(
            _ => { if (SelectedMic != null) UseRequested?.Invoke(SelectedMic.Device); },
            _ => SelectedMic != null);
        CancelCommand = new RelayCommand(_ => CancelRequested?.Invoke());
        _ = LoadAsync();
    }

    private async Task LoadAsync()
    {
        IsLoading = true;
        try
        {
            var devices = await _enumerator.GetMicrophonesAsync();
            Microphones.Clear();
            foreach (var device in devices)
                Microphones.Add(new MicPickerCandidate(device));
            if (Microphones.Count > 0)
                SelectedMic = Microphones[0];
        }
        catch (Exception ex)
        {
            AppLog.Write($"MicPickerViewModel: enumerating microphones failed: {ex.Message}");
        }
        finally
        {
            IsLoading = false;
            OnPropertyChanged(nameof(HasMicrophones));
            OnPropertyChanged(nameof(NoMicrophones));
            CommandManager.InvalidateRequerySuggested();
        }
    }
}
