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

namespace ytLive.ViewModels;

public class CameraPickerCandidate
{
    public CameraDeviceInfo Device { get; }
    public string Name => Device.DisplayName;

    public CameraPickerCandidate(CameraDeviceInfo device)
    {
        Device = device;
    }
}

public class CameraPickerViewModel : ViewModelBase
{
    private readonly ICameraEnumerator _enumerator;
    private CameraPickerCandidate? _selectedCamera;
    private bool _isLoading = true;

    public ObservableCollection<CameraPickerCandidate> Cameras { get; } = new();

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

    public bool HasCameras => !IsLoading && Cameras.Count > 0;
    public bool NoCameras => !IsLoading && Cameras.Count == 0;

    public CameraPickerCandidate? SelectedCamera
    {
        get => _selectedCamera;
        set
        {
            if (SetProperty(ref _selectedCamera, value))
                CommandManager.InvalidateRequerySuggested();
        }
    }

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

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

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

    private async Task LoadAsync()
    {
        IsLoading = true;
        try
        {
            var devices = await _enumerator.GetCamerasAsync();
            Cameras.Clear();
            foreach (var device in devices)
                Cameras.Add(new CameraPickerCandidate(device));
            if (Cameras.Count > 0)
                SelectedCamera = Cameras[0];
        }
        catch (Exception ex)
        {
            AppLog.Write($"CameraPickerViewModel: enumerating cameras failed: {ex.Message}");
        }
        finally
        {
            IsLoading = false;
            OnPropertyChanged(nameof(HasCameras));
            OnPropertyChanged(nameof(NoCameras));
            CommandManager.InvalidateRequerySuggested();
        }
    }
}
