using FoxTube.Controls;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using Microsoft.AppCenter.Analytics;
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.ApplicationModel.DataTransfer;
using Windows.ApplicationModel.Resources;
using Windows.Foundation;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

namespace FoxTube.Pages
{
    /// <summary>
    /// Playlist page
    /// </summary>
    public sealed partial class PlaylistPage : Page, INavigationPage
    {
        public object Parameter { get; set; } = null;
        public string playlistId;
        Playlist item;

        PlaylistItemsResource.ListRequest request;
        string token;
        int page = 1;

        public PlaylistPage()
        {
            InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            Parameter = e.Parameter;

            if (e.Parameter as string == "WL")
                LoadWL();
            else
                Initialize(e.Parameter as string);
        }

        public async void Initialize(string id)
        {
            try
            {
                playlistId = id;

                PlaylistsResource.ListRequest infoRequest = SecretsVault.Service.Playlists.List("snippet,contentDetails");
                infoRequest.Id = id;
                infoRequest.Hl = SettingsStorage.RelevanceLanguage;

                item = (await infoRequest.ExecuteAsync()).Items[0];

                title.Text = item.Snippet.Localized.Title;
                info.Text = $"{item.ContentDetails.ItemCount} {ResourceLoader.GetForCurrentView("Playlist").GetString("/Playlist/videos")}";
                description.Text = item.Snippet.Localized.Description;

                channelName.Text = Methods.GuardFromNull(item.Snippet.ChannelTitle);

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

                request = SecretsVault.Service.PlaylistItems.List("contentDetails");
                request.PlaylistId = id;
                request.MaxResults = 25;

                PlaylistItemListResponse response = await request.ExecuteAsync();
                token = response.NextPageToken;
                if (string.IsNullOrWhiteSpace(token))
                    more.Visibility = Visibility.Collapsed;
                
                foreach (PlaylistItem i in response.Items)
                    list.Add(new VideoCard(i.ContentDetails.VideoId, playlistId));

                Methods.MainPage.PageContent.LoadingPage.Close();
            }
            catch (System.Net.Http.HttpRequestException)
            {
                Methods.MainPage.PageContent.LoadingPage.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
            }
            catch (Exception e)
            {
                Methods.MainPage.PageContent.LoadingPage.Error(e.GetType().ToString(), e.Message);
                Analytics.TrackEvent("Playlist loading error", new Dictionary<string, string>()
                {
                    { "Exception", e.GetType().ToString() },
                    { "Message", e.Message },
                    { "Playlist ID", playlistId },
                    { "StackTrace", e.StackTrace }
                });
            }
        }

        public async void LoadWL()
        {
            try
            {
                playlistId = "WL";
                share.Visibility = Visibility.Collapsed;
                wlAlert.Visibility = Visibility.Visible;

                SecretsVault.WatchLater = await Methods.GetLater();

                title.Text = ResourceLoader.GetForCurrentView("Main").GetString("/Main/later/Content");
                info.Text = $"{SecretsVault.WatchLater.Count} {ResourceLoader.GetForCurrentView("Playlist").GetString("/Playlist/videos")}";
                description.Text = "";

                channelName.Text = SecretsVault.UserChannel.Snippet.Title;

                avatar.ProfilePicture = new BitmapImage(SecretsVault.UserChannel.Snippet.Thumbnails.Medium.Url.ToUri()) { DecodePixelWidth = 50, DecodePixelHeight = 50 };
                thumbnail.Source = new BitmapImage((await new YoutubeExplode.YoutubeClient().GetVideoAsync(SecretsVault.WatchLater.First())).Thumbnails.HighResUrl.ToUri());

                for (int k = 0; k < 25 && k < SecretsVault.WatchLater.Count; k++)
                    list.Add(new VideoCard(SecretsVault.WatchLater[k], "WL"));

                if (list.Count >= SecretsVault.WatchLater.Count)
                    more.Visibility = Visibility.Collapsed;

                Methods.MainPage.PageContent.LoadingPage.Close();
            }
            catch (Exception e)
            {
                if (item == null)
                {
                    Methods.MainPage.PageContent.LoadingPage.Error("PlaylistNotFound", "Such playlist doesn't exist");
                    return;
                }
                Methods.MainPage.PageContent.LoadingPage.Error(e.GetType().ToString(), e.Message);
                Analytics.TrackEvent("WL playlist loading error", new Dictionary<string, string>()
                {
                    { "Exception", e.GetType().ToString() },
                    { "Message", e.Message },
                    { "StackTrace", e.StackTrace }
                });
            }
        }

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

        private async void inBrowser_Click(object sender, RoutedEventArgs e)
        {
            await Launcher.LaunchUriAsync(new Uri($"https://www.youtube.com/playlist?list={item.Id}"));
        }

        private void refresh_Click(object sender, RoutedEventArgs e)
        {
            Methods.MainPage.PageContent.Refresh();
        }

        private void share_Click(object sender, RoutedEventArgs e)
        {
            DataTransferManager.GetForCurrentView().DataRequested += new TypedEventHandler<DataTransferManager, DataRequestedEventArgs>(Share);
            DataTransferManager.ShowShareUI();
        }

        private void Share(DataTransferManager sender, DataRequestedEventArgs args)
        {
            Methods.Share(args,
                item.Snippet.Thumbnails.Medium.Url,
                item.Snippet.Title,
                $"https://www.youtube.com/playlist?list={item.Id}",
                ResourceLoader.GetForCurrentView("Cards").GetString("/Cards/playlistShare"));
        }

        private async void ShowMore_Clicked()
        {
            if(playlistId == "WL")
            {
                MoreWL();
                return;
            }

            request.PageToken = token;
            PlaylistItemListResponse response = await request.ExecuteAsync();

            if (string.IsNullOrWhiteSpace(request.PageToken))
                more.Visibility = Visibility.Collapsed;
            else
            {
                token = response.NextPageToken;
                more.Complete();
            }

            foreach (PlaylistItem i in response.Items)
                list.Add(new VideoCard(i.ContentDetails.VideoId, playlistId));
        }

        private void MoreWL()
        {
            for (int k = 25 * page++; k < 25 * page && k < SecretsVault.WatchLater.Count; k++)
                list.Add(new VideoCard(SecretsVault.WatchLater[k], "WL"));

            if (list.Count >= SecretsVault.WatchLater.Count)
                more.Visibility = Visibility.Collapsed;
            else
                more.Complete();
        }

        public void DeleteItem(FrameworkElement card)
        {
            list.DeleteItem(card);
        }
    }
}
