using System;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Google.Apis.YouTube.v3.Data;
using Windows.UI.Xaml.Media.Imaging;
using Windows.Media;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Media;

namespace FoxTube
{
    public sealed partial class VideoPlayer : UserControl
    {
        public Video item;
        public string avatar;
        public HistoryItem history;
        bool incognito = false;

        public event Event NextClicked;
        public event ObjectEventHandler MiniMode;

        public PlayerControls Controls => videoSource.TransportControls as PlayerControls;
        public MediaElement Player => videoSource;

        SystemMediaTransportControls systemControls;

        public VideoPlayer()
        {
            InitializeComponent();
        }

        public void Initialize(Video meta, string channelAvatar, bool privateMode = false)
        {
            incognito = privateMode;
            item = meta;
            avatar = channelAvatar;
            history = new HistoryItem
            {
                Id = item.Id
            };

            videoSource.PosterSource = new BitmapImage((meta.Snippet.Thumbnails.Maxres ?? meta.Snippet.Thumbnails.Medium).Url.ToUri());

            if (item.Snippet.LiveBroadcastContent == "none")
            {
                InitializeContols();
                Controls.Load(item);

                if (Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes > 5)
                    videoSource.Markers.Add(new TimelineMarker { Time = Methods.GetDuration(item.ContentDetails.Duration) - TimeSpan.FromMinutes(1) });
                if(Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes >= 60)
                    for (int k = 1; k < Methods.GetDuration(item.ContentDetails.Duration).TotalMinutes / 30; k++)
                        videoSource.Markers.Add(new TimelineMarker { Time = TimeSpan.FromMinutes(k * 30) });

                if (!privateMode)
                    HistorySet.Update(history);
            }
            else if (item.Snippet.LiveBroadcastContent == "live")
            {
                InitializeContols();
                Controls.Load(item);
            }
            else
                videoSource.AreTransportControlsEnabled = false;

            Visibility = Visibility.Visible;
        }

        public void InitializeContols()
        {
            videoSource.Volume = SettingsStorage.Volume;
            videoSource.AutoPlay = SettingsStorage.Autoplay;

            Controls.CloseRequested += Controls_CloseRequested;
            Controls.NextRequested += (s, e) => NextClicked?.Invoke();
            Controls.MiniModeChanged += Controls_MiniModeChanged;
            Controls.Player = videoSource;

            #region System Media Transport Controls
            systemControls = SystemMediaTransportControls.GetForCurrentView();
            systemControls.IsNextEnabled = true;
            systemControls.IsPauseEnabled = true;
            systemControls.IsPlayEnabled = true;

            systemControls.DisplayUpdater.Type = MediaPlaybackType.Video;
            systemControls.DisplayUpdater.VideoProperties.Title = item.Snippet.Title;
            systemControls.DisplayUpdater.VideoProperties.Subtitle = item.Snippet.ChannelTitle;
            systemControls.DisplayUpdater.Thumbnail = RandomAccessStreamReference.CreateFromUri(avatar.ToUri());
            systemControls.DisplayUpdater.Update();

            systemControls.ButtonPressed += SystemControls_Engaged;
            systemControls.IsEnabled = true;
            #endregion
        }

        private async void SystemControls_Engaged(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
        {
            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                switch (args.Button)
                {
                    case SystemMediaTransportControlsButton.Play:
                        videoSource.Play();
                        break;
                    case SystemMediaTransportControlsButton.Pause:
                        videoSource.Pause();
                        break;
                    case SystemMediaTransportControlsButton.Next:
                        NextClicked?.Invoke();
                        break;
                }
            });
        }

        public void Controls_MiniModeChanged(object sender, bool e)
        {
            videoSource.IsFullWindow = false;

            MiniMode?.Invoke(this, e);
        }

        public void Minimize()
        {
            Controls.Minimize();
        }

        public void Controls_CloseRequested(object sender, RoutedEventArgs e)
        {
            videoSource.Pause();
            systemControls.IsEnabled = false;
            videoSource.Source = null;
            
            if (!incognito && item.Snippet.LiveBroadcastContent == "none")
            {
                history.LeftOn = videoSource.Position;
                HistorySet.Update(history);
            }

            Methods.MainPage.CloseVideo();
        }

        public void Pause()
        {
            videoSource.Pause();
        }

        private void VideoSource_CurrentStateChanged(object sender, RoutedEventArgs e)
        {
            systemControls.PlaybackStatus = videoSource.CurrentState == MediaElementState.Playing ? MediaPlaybackStatus.Playing : MediaPlaybackStatus.Paused;

            if(videoSource.CurrentState == MediaElementState.Paused)
                if (!incognito && item.Snippet.LiveBroadcastContent == "none")
                {
                    history.LeftOn = videoSource.Position;
                    HistorySet.Update(history);
                }
        }

        private void VideoSource_VolumeChanged(object sender, RoutedEventArgs e)
        {
            if(videoSource.Volume != 0)
                SettingsStorage.Volume = videoSource.Volume;
            Controls.UpdateVolumeIcon();
        }

        private void VideoSource_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
        {
            Controls.PushAdvert();
        }
    }
}
