using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using FoxTube.Controls;
using System.Net.Http;
using System.Text.RegularExpressions;
using Microsoft.AppCenter.Analytics;

namespace FoxTube
{
    /// <summary>
    /// Home page
    /// </summary>
    public sealed partial class Home : Page, INavigationPage
    {
        public object Parameter { get; set; } = null;
        private bool trendLoaded = false, recLoaded = false, subsLoaded = false;
        
        List<string> homeList = new List<string>();
        List<string> subsList = new List<string>();

        VideosResource.ListRequest trendsRequest;

        public Home()
        {
            InitializeComponent();
            SecretsVault.RefreshToken();
            Initialize();
        }

        public void Initialize()
        {
            if(!SecretsVault.IsAuthorized)
            {
                pivot.Items.Remove(recommended);
                pivot.Items.Remove(subscriptions);
            }
        }

        private void pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Methods.MainPage.PageContent.LoadingPage.Close();

            if (pivot.SelectedItem == recommended && !recLoaded)
                LoadRecommendations();
            else if (pivot.SelectedItem == trending && !trendLoaded)
                LoadTrending();
            else if (pivot.SelectedItem == subscriptions && !subsLoaded)
                LoadSubscriptions();
        }

        #region Initializing tabs
        async void LoadRecommendations()
        {
            recLoaded = false;
            try
            {
                recsLoading.Refresh();

                string response = await SecretsVault.HttpClient.GetStringAsync("https://www.youtube.com/");

                foreach (Match match in Regex.Matches(response, @"\bdata-context-item-id=(\S*)\b", RegexOptions.IgnoreCase))
                    homeList.Add(match.Value.Split('"')[1]);

                for (int k = 0; k < 25 && k < homeList.Count; k++)
                    recGrid.Add(new VideoCard(homeList[k]));

                recommendedMore.Visibility = recGrid.Count >= homeList.Count ? Visibility.Collapsed : Visibility.Visible;

                recsLoading.Close();
                recLoaded = true;
            }
            catch (HttpRequestException)
            {
                recsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
            }
            catch (Exception e)
            {
                recsLoading.Error(e.GetType().ToString(), e.Message);

                Analytics.TrackEvent("Failed to load recommendations", new Dictionary<string, string>()
                {
                    { "Exception", e.GetType().ToString() },
                    { "Message", e.Message },
                    { "StackTrace", e.StackTrace }
                });
            }
        }
        async void LoadTrending()
        {
            trendLoaded = false;
            try
            {
                trendsLoading.Refresh();

                trendsRequest = SecretsVault.Service.Videos.List("snippet,contentDetails,statistics,liveStreamingDetails");
                trendsRequest.MaxResults = 25;

                trendsRequest.Chart = VideosResource.ListRequest.ChartEnum.MostPopular;
                trendsRequest.RegionCode = SettingsStorage.Region;

                VideoListResponse response = await trendsRequest.ExecuteAsync();

                trendsRequest.PageToken = response.NextPageToken;
                trendingMore.Visibility = string.IsNullOrWhiteSpace(response.NextPageToken) ? Visibility.Collapsed : Visibility.Visible;

                foreach (Video i in response.Items)
                    trendGrid.Add(new VideoCard(i));

                trendsLoading.Close();
                trendLoaded = true;
            }
            catch (HttpRequestException)
            {
                trendsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
            }
            catch(Exception e)
            {
                trendsLoading.Error(e.GetType().ToString(), e.Message);

                Analytics.TrackEvent("Failed to load trendings", new Dictionary<string, string>()
                {
                    { "Exception", e.GetType().ToString() },
                    { "Message", e.Message },
                    { "StackTrace", e.StackTrace }
                });
            }
        }
        async void LoadSubscriptions()
        {
            subsLoaded = false;
            try
            {
                subsLoading.Refresh();

                string response = await SecretsVault.HttpClient.GetStringAsync("https://www.youtube.com/feed/subscriptions");

                foreach (Match match in Regex.Matches(response, @"\bdata-context-item-id=(\S*)\b", RegexOptions.IgnoreCase))
                    subsList.Add(match.Value.Split('"')[1]);

                for (int k = 0; k < 25 && k < subsList.Count; k++)
                    subsGrid.Add(new VideoCard(subsList[k]));

                subscriptionsMore.Visibility = subsGrid.Count >= subsList.Count ? Visibility.Collapsed : Visibility.Visible;

                subsLoading.Close();
                subsLoaded = true;
            }
            catch (HttpRequestException)
            {
                subsLoading.Error("System.Net.Http.HttpRequestException", "Unable to connect to Google servers.", true);
            }
            catch (Exception e)
            {
                subsLoading.Error(e.GetType().ToString(), e.Message);

                Analytics.TrackEvent("Failed to load subscriptions", new Dictionary<string, string>()
                {
                    { "Exception", e.GetType().ToString() },
                    { "Message", e.Message },
                    { "StackTrace", e.StackTrace }
                });
            }
        }
        #endregion

        #region More requests
        private void Recommended_More()
        {
            int l = 25 + recGrid.Count;
            for (int k = recGrid.Count; k < l && k < homeList.Count; k++)
                recGrid.Add(new VideoCard(homeList[k]));

            recommendedMore.Visibility = recGrid.Count >= homeList.Count ? Visibility.Collapsed : Visibility.Visible;
            recommendedMore.Complete();
        }
        private async void Trending_More()
        {
            VideoListResponse response = await trendsRequest.ExecuteAsync();

            trendsRequest.PageToken = response.NextPageToken;
            trendingMore.Visibility = string.IsNullOrWhiteSpace(response.NextPageToken) ? Visibility.Collapsed : Visibility.Visible;

            foreach (Video i in response.Items)
                trendGrid.Add(new VideoCard(i));

            trendingMore.Complete();
        }
        private void Subscriptions_More()
        {
            int l = 25 + subsGrid.Count;
            for (int k = subsGrid.Count; k < l && k < subsList.Count; k++)
                subsGrid.Add(new VideoCard(subsList[k]));
            
            subscriptionsMore.Visibility = subsGrid.Count >= subsList.Count ? Visibility.Collapsed : Visibility.Visible;
            subscriptionsMore.Complete();
        }
        #endregion

        private void Refresh_Click(object sender, RoutedEventArgs e)
        {
            switch(pivot.SelectedIndex)
            {
                case 0:
                    recGrid.Clear();
                    LoadRecommendations();
                    break;
                case 1:
                    trendsRequest = null;
                    trendGrid.Clear();
                    LoadTrending();
                    break;
                case 2:
                    subsGrid.Clear();
                    LoadSubscriptions();
                    break;
            }
        }
    }
}
