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

namespace FoxTube.Controls
{
    public class ChatMessage
    {
        public string Author => message.AuthorDetails.DisplayName;
        public TextBlock Message
        {
            get
            {
                TextBlock block = new TextBlock()
                {
                    IsTextSelectionEnabled = true,
                    VerticalAlignment = VerticalAlignment.Top,
                    TextWrapping = TextWrapping.WrapWholeWords
                };
                block.FormatText(message.Snippet.DisplayMessage);
                return block;                
            }
        }
        public string ChannelId => message.AuthorDetails.ChannelId;
        public string Avatar => message.AuthorDetails.ProfileImageUrl;

        public Visibility IsVerified => message.AuthorDetails.IsVerified.Value ? Visibility.Visible : Visibility.Collapsed;
        public Visibility IsOwner => message.AuthorDetails.IsChatOwner.Value ? Visibility.Visible : Visibility.Collapsed;
        public Visibility IsSponsor => message.AuthorDetails.IsChatSponsor.Value ? Visibility.Visible : Visibility.Collapsed;
        public Visibility IsModerator => message.AuthorDetails.IsChatModerator.Value ? Visibility.Visible : Visibility.Collapsed;

        public Brush Background
        {
            get
            {
                if (IsVerified == Visibility.Visible || IsOwner == Visibility.Visible || IsSponsor == Visibility.Visible || IsModerator == Visibility.Visible)
                    return new SolidColorBrush() { Color = Colors.Red, Opacity = .2 };
                else
                    return new SolidColorBrush();
            }
        }
        public Thickness BorderThickness
        {
            get
            {
                if (IsVerified == Visibility.Visible || IsOwner == Visibility.Visible || IsSponsor == Visibility.Visible || IsModerator == Visibility.Visible)
                    return new Thickness(2);
                else
                    return new Thickness(0);
            }
        }

        private LiveChatMessage message;

        public ChatMessage(LiveChatMessage item)
        {
            message = item;
        }
    }

    public sealed partial class Chat : UserControl
    {
        NativeAdsManagerV2 manager = new NativeAdsManagerV2(SecretsVault.AppId, SecretsVault.AdUnitId);
        public NativeAdV2 advert;
        string chatId;
        DateTime lastInsert;

        LiveChatMessagesResource.ListRequest request;
        LiveChatMessageListResponse response;

        DispatcherTimer timer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(1)
        };

        DispatcherTimer adTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromMinutes(5)
        };

        public Chat(string id)
        {
            InitializeComponent();
            if (!SecretsVault.IsAuthorized)
                inputField.Visibility = Visibility.Collapsed;
            chatId = id;

            request = SecretsVault.Service.LiveChatMessages.List(chatId, "snippet,authorDetails");

            timer.Tick += Update;
            timer.Start();

            if (SecretsVault.AdsDisabled)
                return;

            adTimer.Tick += (s, e) => manager.RequestAd();
            adTimer.Start();

            manager.AdReady += AdReady;
            manager.ErrorOccurred += ErrorOccurred;
        }

        private void ErrorOccurred(object sender, NativeAdErrorEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Error has occured while loading ad");
        }

        private void AdReady(object sender, NativeAdReadyEventArgs e)
        {
            advert = e.NativeAd;

            Grid grid = new Grid
            {
                Margin = new Thickness(0, 5, 5, 5),
            };

            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            StackPanel iconStack = new StackPanel
            {
                Orientation = Orientation.Horizontal,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(5, 0, 5, 0)
            };

            iconStack.Children.Add(new PersonPicture
            {
                Height = 20,
                ProfilePicture = advert.AdIcon == null ? null : advert.AdIcon.Source
            });
            FontIcon sponsor = new FontIcon
            {
                Glyph = "\xE735",
                Margin = new Thickness(2, 0, 2, 0)
            };
            ToolTipService.SetToolTip(sponsor, ResourceLoader.GetForCurrentView("Chat").GetString("/Chat/sponsor/Text"));
            iconStack.Children.Add(sponsor);

            StackPanel nameStack = new StackPanel
            {
                Orientation = Orientation.Horizontal,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(0, 0, 2, 0)
            };
            Grid.SetColumn(nameStack, 1);
            HyperlinkButton sponsorName = new HyperlinkButton
            {
                Margin = new Thickness(0, -6, 0, 0),
                FontWeight = Windows.UI.Text.FontWeights.Bold,
                Content = new TextBlock
                {
                    TextTrimming = TextTrimming.CharacterEllipsis,
                    MaxWidth = 150,
                    Text = Methods.GuardFromNull(advert.SponsoredBy)
                }
            };
            ToolTipService.SetToolTip(sponsorName, Methods.GuardFromNull(advert.SponsoredBy));
            nameStack.Children.Add(sponsorName);
            nameStack.Children.Add(new TextBlock { Text = ":" });

            StackPanel contentStack = new StackPanel
            {
                Padding = new Thickness(2, 0, 0, 0)
            };
            Grid.SetColumn(contentStack, 2);
            contentStack.Children.Add(new TextBlock
            {
                VerticalAlignment = VerticalAlignment.Top,
                TextWrapping = TextWrapping.WrapWholeWords,
                FontWeight = Windows.UI.Text.FontWeights.Bold,
                Text = advert.Title
            });
            if(!string.IsNullOrWhiteSpace(advert.Description))
                contentStack.Children.Add(new TextBlock
                {
                    VerticalAlignment = VerticalAlignment.Top,
                    TextWrapping = TextWrapping.WrapWholeWords,
                    Text = advert.Description
                });
            if (!string.IsNullOrWhiteSpace(advert.CallToActionText))
                contentStack.Children.Add(new HyperlinkButton
                {
                    VerticalAlignment = VerticalAlignment.Top,
                    Content = new TextBlock
                    {
                        TextWrapping = TextWrapping.WrapWholeWords,
                        Text = advert.CallToActionText
                    }
                });

            grid.Children.Add(iconStack);
            grid.Children.Add(nameStack);
            grid.Children.Add(contentStack);

            Grid mainGrid = new Grid();
            mainGrid.Children.Add(new Border
            {
                BorderBrush = new SolidColorBrush(Colors.Red),
                BorderThickness = new Thickness(2),
                CornerRadius = new CornerRadius(5),
                HorizontalAlignment = HorizontalAlignment.Stretch,
                Margin = new Thickness(0, 27, 0, 2),
                Background = new SolidColorBrush(Colors.Red) { Opacity = .2 },
                Child = grid
            });

            ListViewItem item = new ListViewItem
            {
                Content = mainGrid
            };

            list.Items.Insert(0, item);

            if (contentStack.Children.Last() is HyperlinkButton)
                advert.RegisterAdContainer(mainGrid, new List<FrameworkElement> { contentStack.Children.Last() as HyperlinkButton });
            else
                advert.RegisterAdContainer(mainGrid);
        }

        public async void Update(object sender, object e)
        {
            response = await request.ExecuteAsync();
            foreach (LiveChatMessage i in response.Items.FindAll(i => i.Snippet.PublishedAt >= lastInsert))
                list.Items.Insert(0, new ChatMessage(i));

            lastInsert = DateTime.Now;
            timer.Interval = TimeSpan.FromMilliseconds(response.PollingIntervalMillis.Value);
            timer.Start();
        }

        private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
        {
            Methods.MainPage.GoToChannel(((HyperlinkButton)sender).Tag as string);
        }

        private async void send_Click(object sender, RoutedEventArgs args)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(newMessage.Text))
                    return;

                newMessage.IsEnabled = false;
                send.IsEnabled = false;
                
                LiveChatMessage message = new LiveChatMessage()
                {
                    Snippet = new LiveChatMessageSnippet()
                    {
                        Type = "textMessageEvent",
                        LiveChatId = chatId,
                        TextMessageDetails = new LiveChatTextMessageDetails()
                        {
                            MessageText = newMessage.Text
                        }
                    }
                };

                LiveChatMessagesResource.InsertRequest request = SecretsVault.Service.LiveChatMessages.Insert(message, "snippet,authorDetails");
                LiveChatMessage response = await request.ExecuteAsync();

                if(response != null)
                {
                    newMessage.Text = string.Empty;
                    list.Items.Add(new ChatMessage(response));
                }
            }
            catch(Exception e)
            {
                await new MessageDialog(ResourceLoader.GetForCurrentView("Chat").GetString("/Chat/failed")).ShowAsync();
                Analytics.TrackEvent("Failed to send a chat message", new Dictionary<string, string>()
                {
                    { "Exception", e.GetType().ToString() },
                    { "Message", e.Message },
                    { "StackTrace", e.StackTrace }
                });
            }

            newMessage.IsEnabled = true;
            send.IsEnabled = true;
        }
    }
}
