using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Pixiview.UI;
using Pixiview.UI.Theme;
using Pixiview.Utils;
using Xamarin.Forms;

namespace Pixiview.Illust
{
    public partial class RecommendsPage : IllustDataCollectionPage
    {
        public static readonly BindableProperty UsersProperty = BindableProperty.Create(
            nameof(Users), typeof(List<IllustUserItem>), typeof(RecommendsPage));
        public static readonly BindableProperty UserColumnsProperty = BindableProperty.Create(
            nameof(UserColumns), typeof(int), typeof(RecommendsPage), 1);
        public static readonly BindableProperty UserRecommendsVisibleProperty = BindableProperty.Create(
            nameof(UserRecommendsVisible), typeof(bool), typeof(RecommendsPage));

        public List<IllustUserItem> Users
        {
            get => (List<IllustUserItem>)GetValue(UsersProperty);
            set => SetValue(UsersProperty, value);
        }
        public int UserColumns
        {
            get => (int)GetValue(UserColumnsProperty);
            set => SetValue(UserColumnsProperty, value);
        }
        public bool UserRecommendsVisible
        {
            get => (bool)GetValue(UserRecommendsVisibleProperty);
            set => SetValue(UserRecommendsVisibleProperty, value);
        }

        private readonly Command<IllustUserItem> commandUserTapped;

        private IllustData illustData;

        public RecommendsPage()
        {
            Resources.Add("cardView", GetCardViewTemplate());
            Resources.Add("userCardView", GetUserCardViewTemplate());
            InitializeComponent();

            commandUserTapped = new Command<IllustUserItem>(OnIllustUserItemTapped);
        }

        protected override ActivityIndicator LoadingIndicator => activityLoading;

        public override void OnUnload()
        {
            base.OnUnload();
            Users = null;
        }

        private void OnIllustUserItemTapped(IllustUserItem item)
        {
            Start(async () =>
            {
                var page = new UserIllustPage(item);
                await Navigation.PushAsync(page);
            });
        }

        private Image GetUserCardViewImage(int column, CornerMask masks, string source, string parameter)
        {
            Image image;
            if (masks == CornerMask.None)
            {
                image = new Image();
            }
            else
            {
                image = new RoundImage
                {
                    CornerRadius = 10,
                    CornerMasks = masks
                };
            }
            image.HorizontalOptions = LayoutOptions.Fill;
            image.Aspect = Aspect.AspectFill;
            image.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = commandIllustImageTapped
            }
            .Binding(TapGestureRecognizer.CommandParameterProperty, parameter));
            image.SetBinding(Image.SourceProperty, source);
            if (column > 0)
            {
                Grid.SetColumn(image, column);
            }
            Grid.SetRow(image, 1);
            return image;
        }

        private DataTemplate GetUserCardViewTemplate()
        {
            return new DataTemplate(() =>
            {
                return new Grid
                {
                    RowSpacing = 0,
                    ColumnSpacing = 0,
                    RowDefinitions =
                    {
                        new RowDefinition { Height = 40 },
                        new RowDefinition { Height = 120 }
                    },
                    ColumnDefinitions =
                    {
                        new ColumnDefinition(),
                        new ColumnDefinition(),
                        new ColumnDefinition()
                    },
                    Children =
                    {
                        // stacklayout: user
                        new Grid
                        {
                            ColumnDefinitions =
                            {
                                new ColumnDefinition { Width = 30 },
                                new ColumnDefinition()
                            },
                            Padding = new Thickness(8, 0, 8, 8),
                            Children =
                            {
                                // user icon
                                new CircleImage
                                {
                                    WidthRequest = 30,
                                    HeightRequest = 30,
                                    Aspect = Aspect.AspectFill
                                }
                                .Binding(Image.SourceProperty, nameof(IllustUserItem.ProfileImage)),

                                // user name
                                new Label
                                {
                                    HorizontalOptions = LayoutOptions.FillAndExpand,
                                    VerticalOptions = LayoutOptions.Center,
                                    LineBreakMode = LineBreakMode.TailTruncation,
                                    FontSize = StyleDefinition.FontSizeSmall
                                }
                                .Binding(Label.TextProperty, nameof(IllustUserItem.UserName))
                                .DynamicResource(Label.TextColorProperty, ThemeBase.SubTextColor)
                                .GridColumn(1),
                            },
                            GestureRecognizers =
                            {
                                new TapGestureRecognizer
                                {
                                    Command = commandUserTapped
                                }
                                .Binding(TapGestureRecognizer.CommandParameterProperty, ".")
                            }
                        }
                        .GridColumnSpan(3),

                        GetUserCardViewImage(0, CornerMask.Left,
                            $"{nameof(IllustUserItem.Image1Item)}.{nameof(IllustItem.Image)}",
                            nameof(IllustUserItem.Image1Item)),

                        GetUserCardViewImage(1, CornerMask.None,
                            $"{nameof(IllustUserItem.Image2Item)}.{nameof(IllustItem.Image)}",
                            nameof(IllustUserItem.Image2Item)),

                        GetUserCardViewImage(2, CornerMask.Right,
                            $"{nameof(IllustUserItem.Image3Item)}.{nameof(IllustItem.Image)}",
                            nameof(IllustUserItem.Image3Item))
                    }
                };
            });
        }

        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);
            int columns;
            if (width > height)
            {
                columns = isPhone ? 2 : 3;
            }
            else
            {
                columns = isPhone ? 1 : 2;
            }
            if (UserColumns != columns)
            {
                UserColumns = columns;
#if DEBUG
                App.DebugPrint($"change user columns to {columns}");
#endif
            }
        }

        protected override void DoIllustsLoaded(IllustCollection collection, bool bottom)
        {
            //IsLoading = false;
            if (illustData != null)
            {
                IllustCollection = collection;
                Task.Run(() => DoLoadUserRecommendsData(illustData));
            }
            else
            {
                base.DoIllustsLoaded(collection, bottom);
            }
        }

        protected override IEnumerable<IllustItem> DoGetIllustList(IllustData data)
        {
            if (data.body == null)
            {
                return null;
            }
            return data.body.page.recommend.Select(id =>
                data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem());
        }

        protected override IllustData DoLoadIllustData(bool force)
        {
            illustData = Stores.LoadIllustData(force);
            return illustData;
        }

        private void DoLoadUserRecommendsData(IllustData data)
        {
            var r18 = Configs.IsOnR18;
            var defaultImage = StyleDefinition.DownloadBackground;
            var users = data.body.page.recommendUser.Select(u =>
            {
                var usrId = u.id.ToString();
                var usr = data.body.users.FirstOrDefault(r => r.userId == usrId);
                if (usr == null)
                {
                    return null;
                }
                IllustItem item1 = null, item2 = null, item3 = null;
                if (u.illustIds != null)
                {
                    var length = u.illustIds.Length;
                    if (length > 0)
                    {
                        var id = u.illustIds[0];
                        item1 = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem(defaultImage);
                    }
                    if (length > 1)
                    {
                        var id = u.illustIds[1];
                        item2 = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem(defaultImage);
                    }
                    if (length > 2)
                    {
                        var id = u.illustIds[2];
                        item3 = data.body.thumbnails.illust.FirstOrDefault(l => l.illustId == id)?.ConvertToItem(defaultImage);
                    }
                }
                if (!r18)
                {
                    if (item1?.IsRestrict == true ||
                        item2?.IsRestrict == true ||
                        item3?.IsRestrict == true)
                    {
                        return null;
                    }
                }
                return new IllustUserItem
                {
                    UserId = usrId,
                    UserName = usr.name,
                    ProfileUrl = usr.image,
                    Image1Item = item1,
                    Image2Item = item2,
                    Image3Item = item3
                };
            }).Where(u => u != null);

            var list = new List<IllustUserItem>(users);
            activityLoading.Animate("margin", top =>
            {
                activityLoading.Margin = new Thickness(0, top, 0, 0);
            },
            16, -40, easing: Easing.CubicIn, finished: (v, r) =>
            {
                IsLoading = false;
                UserRecommendsVisible = list.Count > 0;
#if __IOS__
                Device.StartTimer(TimeSpan.FromMilliseconds(48), () =>
#else
                Device.StartTimer(TimeSpan.FromMilliseconds(150), () =>
#endif
                {
                    Users = list;
                    Illusts = IllustCollection;
                    return false;
                });
            });

            DoLoadUserRecommendsImages(list);
        }

        private void DoLoadUserRecommendsImages(List<IllustUserItem> users)
        {
            foreach (var user in users)
            {
                if (user.ProfileUrl != null)
                {
                    var userImage = Stores.LoadUserProfileImage(user.ProfileUrl);
                    if (userImage != null)
                    {
                        user.ProfileImage = userImage;
                    }
                }
                Task.WaitAll(
                    Task.Run(() => DoLoadUserRecommendsImage(user.Image1Item)),
                    Task.Run(() => DoLoadUserRecommendsImage(user.Image2Item)),
                    Task.Run(() => DoLoadUserRecommendsImage(user.Image3Item)));
            }
        }

        private void DoLoadUserRecommendsImage(IllustItem illust)
        {
            if (illust.ImageUrl != null)
            {
                var url = Configs.GetThumbnailUrl(illust.ImageUrl);
                var image = Stores.LoadPreviewImage(url, false);
                if (image == null)
                {
                    image = Stores.LoadThumbnailImage(url);
                }
                if (image != null)
                {
                    illust.Image = image;
                }
            }
        }

        private async void Refresh_Clicked(object sender, EventArgs e)
        {
            if (IsLoading)
            {
                return;
            }
            await ScrollToTopAsync(scrollView);
            StartLoad(true);
        }
    }

    public class IllustUserItem : BindableObject, IIllustItem
    {
        //public static readonly BindableProperty Image1Property = BindableProperty.Create(
        //    nameof(Image1), typeof(ImageSource), typeof(IllustUserItem));
        public static readonly BindableProperty ProfileImageProperty = BindableProperty.Create(
            nameof(ProfileImage), typeof(ImageSource), typeof(IllustUserItem));

        //public ImageSource Image1
        //{
        //    get => (ImageSource)GetValue(Image1Property);
        //    set => SetValue(Image1Property, value);
        //}
        public ImageSource ProfileImage
        {
            get => (ImageSource)GetValue(ProfileImageProperty);
            set => SetValue(ProfileImageProperty, value);
        }

        public string UserId { get; set; }
        public string UserName { get; set; }
        public IllustItem Image1Item { get; set; }
        public IllustItem Image2Item { get; set; }
        public IllustItem Image3Item { get; set; }
        public string ProfileUrl { get; set; }

        public bool IsFavorite { get; }
        public string BookmarkId { get; }
    }
}
