using System;
using Xamarin.Forms;
using Aurora.Frontend.Views;
using Aurora.Backend.Services.PlayerService;
using Aurora.Backend.Models.Media;

namespace Aurora.Frontend.Components.MediaPlayer
{
    public class PlayerViewModel : BaseViewModel
    {
        PlayerService _playerService;
        BaseMetadata _metadata;

        public PlayerViewModel()
        {
            _playerService = PlayerService.Instance;
            _playerService.PlaybackStateChanged += OnPlaybackStateChanged;
            _playerService.MediaChanged += OnMediaChanged;

            PlayCommand = new Command(OnPlayExecute, CanPlayExecute);
            PreviousCommand = new Command(OnPreviousExecute, CanPreviousExecute);
            NextCommand = new Command(OnNextExecute, CanNextExecute);
        }

        ~PlayerViewModel()
        {
            _playerService.PlaybackStateChanged -= OnPlaybackStateChanged;

        }

        #region Public Properties
        public Command PlayCommand { get; private set; }
        public Command NextCommand { get; private set; }
        public Command PreviousCommand { get; private set; }

        public string PlayButtonText
        {
            get { return _playerService.PlaybackState == PlaybackState.Buffering ? "Play" : "Pause"; }
        }

        /// <summary>
        /// TODO keep player view generic between audio and video.
        /// </summary>
        /// <value></value>
        public string ArtistName
        {
            get
            {
                if (_metadata == null)
                {
                    return "";
                }
                AudioMetadata metadata = _metadata as AudioMetadata;
                return metadata.Artist;
            }
        }

        /// <summary>
        /// TODO keep player view generic between audio and video.
        /// </summary>
        /// <value></value>
        public string SongTitle
        {
            get
            {
                if (_metadata == null)
                {
                    return "";
                }
                AudioMetadata metadata = _metadata as AudioMetadata;
                return metadata.Title;
            }
        }

        #endregion Public Properties

        #region Public Methods
        public bool CanPreviousExecute()
        {
            return true;
        }
        public void OnPreviousExecute()
        {

        }

        public bool CanPlayExecute()
        {
            switch (_playerService.PlaybackState)
            {
                case PlaybackState.Buffering:
                    {
                        return true;
                    }
                case PlaybackState.Playing:
                    {
                        return true;
                    }
                case PlaybackState.Stopped:
                    {
                        return false;
                    }
            }
            return false;
        }

        public void OnPlayExecute()
        {
            switch (_playerService.PlaybackState)
            {
                case PlaybackState.Buffering:
                    {
                        _playerService.Play();
                        break;
                    }
                case PlaybackState.Playing:
                    {
                        _playerService.Pause();
                        break;
                    }
            }
        }

        public bool CanNextExecute()
        {
            return true;
        }

        public void OnNextExecute()
        {

        }

        #endregion public Methods

        #region EventHandlers
        /// <summary>
        /// PlayerService playback state changed event handler.
        /// </summary>
        /// <param name="sender">The sending object.</param>
        /// <param name="args">Event arguments.</param>
        public void OnPlaybackStateChanged(object sender, PlaybackStateChangedEventArgs args)
        {
            OnPropertyChanged("PlayButtonText");
            PlayCommand.ChangeCanExecute();
            NextCommand.ChangeCanExecute();
            PreviousCommand.ChangeCanExecute();
        }

        /// <summary>
        /// PlayerService media changed event handler.
        /// </summary>
        /// <param name="sender">The sending object.</param>
        /// <param name="args">Event arguments.</param>
        public void OnMediaChanged(object sender, MediaChangedEventArgs args)
        {
            _metadata = args.NewMetadata;
            OnPropertyChanged("ArtistName");
            OnPropertyChanged("SongTitle");
        }
        #endregion EventHandlers
    }
}
