using Harmonia.Core.Models;
using Harmonia.Core.Player;
using Harmonia.WinUI.Caching;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Harmonia.WinUI.ViewModels;

public partial class PlayingSongViewModel : ViewModelBase
{
    private readonly IAudioPlayer _audioPlayer;
    private readonly IAudioBitmapImageCache _audioBitmapImageCache;
    private readonly DispatcherQueue _dispatcherQueue;

    private CancellationTokenSource? _songImageCancellationTokenSource;

    private Song? _song;
    public Song? Song
    {
        get
        {
            return _song;
        }
        private set
        {
            SetProperty(ref _song, value);
        }
    }

    private BitmapImage? _songImageSource;
    public BitmapImage? SongImageSource
    {
        get
        {
            return _songImageSource;
        }
        private set
        {
            SetProperty(ref _songImageSource, value);
        }
    }

    public PlayingSongViewModel(IAudioPlayer audioPlayer, IAudioBitmapImageCache audioBitmapImageCache)
    {
        _audioPlayer = audioPlayer;
        _audioPlayer.PlayingSongChanged += OnAudioPlayerPlayingSongChanged;

        _audioBitmapImageCache = audioBitmapImageCache;
        _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
    }

    private void OnAudioPlayerPlayingSongChanged(object? sender, EventArgs e)
    {
        Song = _audioPlayer.PlayingSong?.Song;
        Task.Run(UpdateImage);
    }

    private async Task UpdateImage()
    {
        // TODO: Show default picture
        if (Song == null)
            return;

        if (_songImageCancellationTokenSource != null)
            await _songImageCancellationTokenSource.CancelAsync();

        _songImageCancellationTokenSource = new();
        CancellationToken cancellationToken = _songImageCancellationTokenSource.Token;

        _dispatcherQueue.TryEnqueue(async () =>
        {
            BitmapImage? bitmapImage = await _audioBitmapImageCache.GetAsync(Song, cancellationToken);
            SongImageSource = bitmapImage;
        });
    }
}