using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Windows.UI.Xaml.Media.Imaging;
using Windows.System;
using Windows.ApplicationModel.DataTransfer;
using Windows.ApplicationModel.Resources;
using Microsoft.AppCenter.Analytics;
using System.Collections.Generic;
using YoutubeExplode;
using Windows.UI.Popups;

namespace FoxTube.Controls
{
    /// <summary>
    /// Video item card
    /// </summary>
    public sealed partial class VideoCard : UserControl
    {
        ResourceLoader resources = ResourceLoader.GetForCurrentView("Cards");

        public string playlistId;
        public string videoId;
        Video item;

        public VideoCard(string id, string playlist = null)
        {
            InitializeComponent();
            Initialize(id, playlist);
        }

        public VideoCard(Video meta, string playlist = null)
        {
            InitializeComponent();
            item = meta;
            playlistId = playlist;
            LoadMeta();
        }

        public async void Initialize(string id, string playlist = null)
        {
            try
            {
                videoId = id;
                playlistId = playlist;

                VideosResource.ListRequest request = SecretsVault.Service.Videos.List("snippet,contentDetails,statistics,liveStreamingDetails");
                request.Id = id;
                item = (await request.ExecuteAsync()).Items[0];
                
                title.Text = item.Snippet.Title;
                channelName.Text = item.Snippet.ChannelTitle;

                if (item.Snippet.LiveBroadcastContent == "live")
                {
                    views.Text = $"{item.LiveStreamingDetails.ConcurrentViewers:0,0} {resources.GetString("/Cards/viewers")}";
                    if (item.LiveStreamingDetails.ScheduledStartTime.HasValue && item.LiveStreamingDetails.ScheduledEndTime.HasValue)
                        info.Text = $"{item.LiveStreamingDetails.ScheduledEndTime - item.LiveStreamingDetails.ActualStartTime} | {Methods.GetAgo(item.LiveStreamingDetails.ActualStartTime.Value)}";
                    else
                        info.Text = Methods.GetAgo(item.LiveStreamingDetails.ActualStartTime.Value);
                    liveTag.Visibility = Visibility.Visible;
                }
                else if (item.Snippet.LiveBroadcastContent == "upcoming")
                {
                    views.Text = "";
                    if (item.LiveStreamingDetails.ScheduledStartTime.HasValue && item.LiveStreamingDetails.ScheduledEndTime.HasValue)
                        info.Text = $"{item.LiveStreamingDetails.ScheduledEndTime - item.LiveStreamingDetails.ScheduledStartTime} | {item.LiveStreamingDetails.ScheduledStartTime}";
                    else
                        info.Text = $"{Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
                    liveTag.Visibility = Visibility.Visible;

                    if (item.LiveStreamingDetails.ScheduledStartTime.HasValue)
                        liveContent.Text = $"{resources.GetString("/Cards/goesLive")} {(item.LiveStreamingDetails.ScheduledStartTime.Value - DateTime.Now).ToString(@"hh\:mm\:ss")}";
                    else liveContent.Text = resources.GetString("/Cards/upcoming");
                }
                else
                {
                    views.Text = $"{item.Statistics.ViewCount:0,0} {resources.GetString("/Cards/views")}";
                    info.Text = $"{item.ContentDetails.Duration.GetDuration()} | {Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
                }

                try { thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); }
                catch { }
                try { avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()); }
                catch { }

                if(SecretsVault.History.Contains(videoId))
                    watched.Visibility = Visibility.Visible;

                Opacity = 1;
            }
            catch (Exception e)
            {
                Visibility = Visibility.Collapsed;
                Analytics.TrackEvent("VideoCard loading failed", new Dictionary<string, string>()
                {
                    { "Exception", e.GetType().ToString() },
                    { "Message", e.Message },
                    { "Video ID", videoId }
                });
            }
        }

        public async void LoadMeta()
        {
            videoId = item.Id;
            title.Text = item.Snippet.Title;
            channelName.Text = item.Snippet.ChannelTitle;

            if (item.Snippet.LiveBroadcastContent == "live")
            {
                views.Text = $"{item.LiveStreamingDetails.ConcurrentViewers:0,0} {resources.GetString("/Cards/viewers")}";
                if (item.LiveStreamingDetails.ScheduledStartTime.HasValue && item.LiveStreamingDetails.ScheduledEndTime.HasValue)
                    info.Text = $"{item.LiveStreamingDetails.ScheduledEndTime - item.LiveStreamingDetails.ActualStartTime} | {Methods.GetAgo(item.LiveStreamingDetails.ActualStartTime.Value)}";
                else
                    info.Text = Methods.GetAgo(item.LiveStreamingDetails.ActualStartTime.Value);
                liveTag.Visibility = Visibility.Visible;
            }
            else if (item.Snippet.LiveBroadcastContent == "upcoming")
            {
                views.Text = "";
                if (item.LiveStreamingDetails.ScheduledStartTime.HasValue && item.LiveStreamingDetails.ScheduledEndTime.HasValue)
                    info.Text = $"{item.LiveStreamingDetails.ScheduledEndTime - item.LiveStreamingDetails.ScheduledStartTime} | {item.LiveStreamingDetails.ScheduledStartTime}";
                else
                    info.Text = $"{Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
                liveTag.Visibility = Visibility.Visible;

                if (item.LiveStreamingDetails.ScheduledStartTime.HasValue)
                    liveContent.Text = $"{resources.GetString("/Cards/goesLive")} {item.LiveStreamingDetails.ScheduledStartTime - DateTime.Now}";
                else liveContent.Text = resources.GetString("/Cards/upcoming");
            }
            else
            {
                views.Text = $"{item.Statistics.ViewCount:0,0} {resources.GetString("/Cards/views")}";
                info.Text = $"{item.ContentDetails.Duration.GetDuration()} | {Methods.GetAgo(item.Snippet.PublishedAt.Value)}";
            }

            try { thumbnail.Source = new BitmapImage(item.Snippet.Thumbnails.Medium.Url.ToUri()); }
            catch { }
            try { avatar.ProfilePicture = new BitmapImage((await new YoutubeClient().GetChannelAsync(item.Snippet.ChannelId)).LogoUrl.ToUri()) { DecodePixelHeight = 50, DecodePixelWidth = 50 }; }
            catch { }

            if (SecretsVault.History.Contains(videoId))
                watched.Visibility = Visibility.Visible;

            Opacity = 1;
        }

        public async void Button_Click(object sender, RoutedEventArgs e)
        {
            if (item.ContentDetails.ContentRating != null)
            {
                if (SecretsVault.IsAuthorized)
                {
                    if (SettingsStorage.Mature == MatureState.Blocked)
                    {
                        MessageDialog dialog = new MessageDialog(resources.GetString("/VideoPage/matureText"), resources.GetString("/VideoPage/wantContinue"));
                        dialog.Commands.Add(new UICommand(resources.GetString("/VideoPage/yes"), null, true));
                        dialog.Commands.Add(new UICommand(resources.GetString("/VideoPage/always"), (command) => SettingsStorage.Mature = MatureState.Allowed, true));
                        dialog.Commands.Add(new UICommand(resources.GetString("/VideoPage/no"), null, false));

                        dialog.CancelCommandIndex = 2;
                        dialog.DefaultCommandIndex = 0;

                        if (!(bool)(await dialog.ShowAsync()).Id)
                            return;
                    }
                }
                else
                {
                    MessageDialog dialog = new MessageDialog(resources.GetString("/VideoPage/matureText"), resources.GetString("/VideoPage/signRequired"));
                    dialog.Commands.Add(new UICommand(resources.GetString("/VideoPage/signin"), (command) => SecretsVault.Authorize()));
                    dialog.Commands.Add(new UICommand(resources.GetString("/VideoPage/cancel")));

                    dialog.CancelCommandIndex = 1;
                    dialog.DefaultCommandIndex = 0;

                    await dialog.ShowAsync();
                    return;
                }
            }

            Methods.MainPage.GoToVideo(videoId, playlistId);
        }

        private void ViewChannel_Click(object sender, RoutedEventArgs e)
        {
            Methods.MainPage.GoToChannel(item.Snippet.ChannelId);
        }

        private void GetLink_Click(object sender, RoutedEventArgs e)
        {
            DataPackage data = new DataPackage();
            data.SetText($"https://www.youtube.com/watch?v={videoId}");
            Clipboard.SetContent(data);
        }

        private async void InBrowser_Click(object sender, RoutedEventArgs e)
        {
            await Launcher.LaunchUriAsync($"https://www.youtube.com/watch?v={videoId}".ToUri());
        }

        private void Thumbnail_ImageOpened(object sender, RoutedEventArgs e)
        {
            thumbnail.Opacity = 1;
        }
    }
}
