using System.Windows.Input;
using ytLive.Helpers;
using ytLive.Models;

namespace ytLive.ViewModels;

public class GoLiveViewModel : ViewModelBase
{
    private readonly Func<Task<YouTubeChannel?>> _signInProvider;
    private string _streamTitle = string.Empty;
    private string _streamDescription = string.Empty;
    private bool _isSignedIn;
    private string _accountDisplayName = string.Empty;
    private string _accountAvatarUrl = string.Empty;
    private bool _isBusy;

    /// <summary>Streams always start Private (ship step 7 — private-only by
    /// enforcement); the creator can change visibility on YouTube after going
    /// live. No dropdown — no dead-end option.</summary>
    public string Visibility => "Private";

    public GoLiveViewModel(Func<Task<YouTubeChannel?>> signInProvider, YouTubeChannel? account)
    {
        _signInProvider = signInProvider;

        SignInCommand = new RelayCommand(_ => _ = SignInAsync());
        StartCommand = new RelayCommand(_ => StartRequested?.Invoke(), _ => IsSignedIn && !IsBusy);
        CancelCommand = new RelayCommand(_ => CancelRequested?.Invoke(), _ => !IsBusy);

        if (account != null)
            ApplyAccount(account);
    }

    public string StreamTitle
    {
        get => _streamTitle;
        set => SetProperty(ref _streamTitle, value);
    }

    public string StreamDescription
    {
        get => _streamDescription;
        set => SetProperty(ref _streamDescription, value);
    }

    public bool IsSignedIn
    {
        get => _isSignedIn;
        private set
        {
            if (SetProperty(ref _isSignedIn, value))
                CommandManager.InvalidateRequerySuggested();
        }
    }

    public string AccountDisplayName
    {
        get => _accountDisplayName;
        private set => SetProperty(ref _accountDisplayName, value);
    }

    public string AccountAvatarUrl
    {
        get => _accountAvatarUrl;
        private set => SetProperty(ref _accountAvatarUrl, value);
    }

    public bool IsBusy
    {
        get => _isBusy;
        private set
        {
            if (SetProperty(ref _isBusy, value))
                CommandManager.InvalidateRequerySuggested();
        }
    }

    public ICommand SignInCommand { get; }
    public ICommand StartCommand { get; }
    public ICommand CancelCommand { get; }

    public event Action? StartRequested;
    public event Action? CancelRequested;

    private async Task SignInAsync()
    {
        if (IsBusy) return;
        IsBusy = true;
        try
        {
            var channel = await _signInProvider();
            if (channel != null)
                ApplyAccount(channel);
        }
        finally
        {
            IsBusy = false;
        }
    }

    private void ApplyAccount(YouTubeChannel channel)
    {
        AccountDisplayName = channel.DisplayName;
        AccountAvatarUrl = channel.ProfileImageUrl;
        IsSignedIn = true;
    }
}
