using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Pixiview.Resources;
using Pixiview.UI;
using Pixiview.UI.Theme;
using Pixiview.Utils;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Pixiview.Illust
{
    public abstract class IllustDataCollectionPage : IllustCollectionPage<IllustData> { }
    public abstract class IllustRankingDataCollectionPage : IllustScrollableCollectionPage<IllustRankingData> { }
    public abstract class IllustRecommendsCollectionPage : IllustScrollableCollectionPage<IllustRecommendsData> { }
    public abstract class IllustUserDataCollectionPage : IllustScrollableCollectionPage<IllustUserData> { }
    public abstract class FavoriteIllustCollectionPage : IllustScrollableCollectionPage<IllustItem[]> { }

    public interface IIllustCollectionPage
    {
        IllustCollection IllustCollection { get; set; }
    }
    public abstract class IllustCollectionPage<T> : AdaptedPage, IIllustCollectionPage
    {
        protected const double loadingOffset = -40;

        #region - Properties -

        public static readonly BindableProperty IllustsProperty = BindableProperty.Create(
            nameof(Illusts), typeof(IllustCollection), typeof(IllustCollectionPage<T>));
        public static readonly BindableProperty ColumnsProperty = BindableProperty.Create(
            nameof(Columns), typeof(int), typeof(IllustCollectionPage<T>), 2);
        public static readonly BindableProperty IsLoadingProperty = BindableProperty.Create(
            nameof(IsLoading), typeof(bool), typeof(IllustCollectionPage<T>), true);
        public static readonly BindableProperty IsBottomLoadingProperty = BindableProperty.Create(
            nameof(IsBottomLoading), typeof(bool), typeof(IllustCollectionPage<T>), false);

        public IllustCollection Illusts
        {
            get => (IllustCollection)GetValue(IllustsProperty);
            set => SetValue(IllustsProperty, value);
        }
        public int Columns
        {
            get => (int)GetValue(ColumnsProperty);
            set => SetValue(ColumnsProperty, value);
        }
        public bool IsLoading
        {
            get => (bool)GetValue(IsLoadingProperty);
            set => SetValue(IsLoadingProperty, value);
        }
        public bool IsBottomLoading
        {
            get => (bool)GetValue(IsBottomLoadingProperty);
            set => SetValue(IsBottomLoadingProperty, value);
        }

        #endregion

        protected static DateTime LastUpdated { get; private set; } = DateTime.Now;

        public IllustCollection IllustCollection { get; set; }

        protected virtual bool IsFavoriteVisible => true;
        protected virtual bool IsAutoReload => true;
        protected virtual bool IsRedirectLogin => false;
        protected virtual ActivityIndicator LoadingIndicator => null;
        protected virtual double IndicatorMarginTop => 16;

        protected readonly Command<IllustItem> commandIllustImageTapped;
        protected DateTime lastUpdated;
        protected double topOffset;
        protected string lastError;

        private T illustData;
        private ParallelTask task;

        public IllustCollectionPage()
        {
            commandIllustImageTapped = new Command<IllustItem>(IllustImageTapped);
            BindingContext = this;
        }

        private void IllustImageTapped(IllustItem illust)
        {
            if (illust == null)
            {
                return;
            }
            Start(() => OnIllustImageTapped(illust));
        }

        #region - Overrides -

        public override void OnUnload()
        {
            if (task != null)
            {
                task.Dispose();
                task = null;
            }
            InvalidateCollection();
            Illusts = null;
            lastUpdated = default;
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            if (lastUpdated == default || (IsAutoReload && lastUpdated != LastUpdated))
            {
                StartLoad();
            }
            else if (IllustCollection != null)
            {
                var favorites = Stores.Favorites;
                foreach (var item in IllustCollection)
                {
                    item.IsFavorite =
                        item.BookmarkId != null ||
                        favorites.Any(i => i.Id == item.Id);
                }
            }
        }

#if __IOS__
        public override void OnOrientationChanged(bool landscape)
        {
            base.OnOrientationChanged(landscape);
            if (StyleDefinition.IsFullscreenDevice)
            {
                topOffset = landscape ?
                    AppShell.NavigationBarOffset.Top :
                    AppShell.TotalBarOffset.Top;
            }
            else if (isPhone)
            {
                topOffset = landscape ?
                    StyleDefinition.TopOffset32.Top :
                    AppShell.TotalBarOffset.Top;
            }
            else
            {
                // iPad
                topOffset = AppShell.TotalBarOffset.Top;
            }
        }
#endif

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

        #endregion

        protected abstract T DoLoadIllustData(bool force);
        protected abstract IEnumerable<IllustItem> DoGetIllustList(T data);
        protected virtual void OnIllustImageTapped(IllustItem illust)
        {
            var page = new ViewIllustPage(illust);
            Navigation.PushAsync(page);
        }
        protected virtual IllustCollection GetIllustsLoadedCollection(IllustCollection collection, bool bottom)
        {
            IllustCollection = collection;
            return collection;
        }

        protected void InvalidateCollection()
        {
            var collection = IllustCollection;
            if (collection != null)
            {
                collection.Running = false;
                IllustCollection = null;
            }
        }

        protected virtual void StartLoad(bool force = false, bool isBottom = false)
        {
            if (force || lastUpdated != LastUpdated)
            {
                lastUpdated = LastUpdated;

                var indicator = LoadingIndicator;
                if (indicator == null || isBottom)
                {
                    if (isBottom)
                    {
                        IsBottomLoading = true;
                    }
                    else
                    {
                        InvalidateCollection();
                        IsLoading = true;
                    }
#if __IOS__
                    Device.StartTimer(TimeSpan.FromMilliseconds(48), () =>
#else
                    Device.StartTimer(TimeSpan.FromMilliseconds(150), () =>
#endif
                    {
                        Task.Run(() => DoLoadIllusts(force, isBottom));
                        return false;
                    });
                }
                else
                {
                    InvalidateCollection();
                    IsLoading = true;

                    var offset = 16 - IndicatorMarginTop;
                    indicator.Animate("margin", top =>
                    {
                        indicator.Margin = new Thickness(0, top, 0, offset);
                    },
                    loadingOffset - offset, 16 - offset, easing: Easing.CubicOut, finished: (v, r) =>
                    {
                        _ = Task.Run(() => DoLoadIllusts(force, isBottom));
                    });
                }
            }
        }

        protected virtual void DoIllustsLoaded(IllustCollection collection, bool bottom)
        {
            collection = GetIllustsLoadedCollection(collection, bottom);

            var indicator = LoadingIndicator;
            if (indicator == null || bottom)
            {
                IsLoading = false;
                IsBottomLoading = false;
#if __IOS__
                Device.StartTimer(TimeSpan.FromMilliseconds(48), () =>
#else
                Device.StartTimer(TimeSpan.FromMilliseconds(150), () =>
#endif
                {
                    Illusts = collection;
                    return false;
                });
            }
            else
            {
                var offset = 16 - IndicatorMarginTop;
                indicator.Animate("margin", top =>
                {
                    indicator.Margin = new Thickness(0, top, 0, offset);
                },
                16 - offset, loadingOffset - offset, easing: Easing.CubicIn, finished: (v, r) =>
                {
                    indicator.Margin = new Thickness(0, v, 0, offset);
                    IsLoading = false;
                    IsBottomLoading = false;
#if __IOS__
                    Device.StartTimer(TimeSpan.FromMilliseconds(48), () =>
#else
                    Device.StartTimer(TimeSpan.FromMilliseconds(150), () =>
#endif
                    {
                        Illusts = collection;
                        return false;
                    });
                });
            }
        }

        protected async Task ScrollToTopAsync(ScrollView scrollView)
        {
            if (scrollView.ScrollY > -topOffset)
            {
#if __IOS__
                await scrollView.ScrollToAsync(scrollView.ScrollX, -topOffset, true);
#else
                await scrollView.ScrollToAsync(0, -topOffset, false);
#endif
            }
        }

        protected DataTemplate GetCardViewTemplate(bool hideUser = false)
        {
            return new DataTemplate(() =>
            {
                #region - components -

                // image
                var image = new RoundImage
                {
                    BackgroundColor = StyleDefinition.ColorDownloadBackground,
                    CornerRadius = 10,
                    CornerMasks = CornerMask.Top,
                    HorizontalOptions = LayoutOptions.Fill,
                    Aspect = Aspect.AspectFill,
                    GestureRecognizers =
                    {
                        new TapGestureRecognizer
                        {
                            Command = commandIllustImageTapped
                        }
                        .Binding(TapGestureRecognizer.CommandParameterProperty, ".")
                    }
                }
                .Binding(Image.SourceProperty, nameof(IllustItem.Image));

                // label: r-18
                var r18 = new RoundLabel
                {
                    Text = ResourceHelper.R18,
                    BackgroundColor = StyleDefinition.ColorRedBackground,
                    Margin = new Thickness(6, 6, 0, 0),
                    Padding = new Thickness(6, 2),
                    CornerRadius = 4,
                    HorizontalOptions = LayoutOptions.Start,
                    VerticalOptions = LayoutOptions.Start,
                    FontSize = StyleDefinition.FontSizeMicro,
                    TextColor = Color.White
                }
                .Binding(IsVisibleProperty, nameof(IllustItem.IsRestrict));

                // label: pages
                var pages = new RoundLabel
                {
                    BackgroundColor = StyleDefinition.ColorDeepShadow,
                    Margin = new Thickness(0, 6, 6, 0),
                    Padding = new Thickness(6, 4),
                    CornerRadius = 6,
                    HorizontalOptions = LayoutOptions.End,
                    VerticalOptions = LayoutOptions.Start,
                    FontSize = StyleDefinition.FontSizeMicro,
                    TextColor = Color.White
                }
                .Binding(Label.TextProperty, nameof(IllustItem.PageCountText))
                .Binding(IsVisibleProperty, nameof(IllustItem.IsPageVisible))
                .DynamicResource(Label.FontFamilyProperty, ThemeBase.IconSolidFontFamily);

                // label: is anime
                var anime = new RoundLabel
                {
                    Text = StyleDefinition.IconPlay,
                    BackgroundColor = StyleDefinition.ColorDeepShadow,
                    Margin = new Thickness(0, 0, 6, 6),
                    Padding = new Thickness(12, 9, 0, 0),
                    WidthRequest = 36,
                    HeightRequest = 36,
                    CornerRadius = 18,
                    HorizontalOptions = LayoutOptions.End,
                    VerticalOptions = LayoutOptions.End,
                    FontSize = StyleDefinition.FontSizeTitle,
                    TextColor = Color.White
                }
                .Binding(IsVisibleProperty, nameof(IllustItem.IsAnimeVisible))
                .DynamicResource(Label.FontFamilyProperty, ThemeBase.IconSolidFontFamily);

                // label: title
                var title = new Label
                {
                    Padding = new Thickness(8, 2),
                    HorizontalOptions = LayoutOptions.FillAndExpand,
                    VerticalOptions = LayoutOptions.Center,
                    LineBreakMode = LineBreakMode.TailTruncation,
                    FontSize = StyleDefinition.FontSizeSmall
                }.DynamicResource(Label.TextColorProperty, ThemeBase.TextColor);

                // label: favorite
                var favorite = new Label
                {
                    WidthRequest = 26,
                    HorizontalOptions = LayoutOptions.End,
                    HorizontalTextAlignment = TextAlignment.End,
                    VerticalOptions = LayoutOptions.Center,
                    FontSize = StyleDefinition.FontSizeSmall,
                    TextColor = StyleDefinition.ColorRedBackground,
                    IsVisible = false
                }
                .Binding(Label.TextProperty, nameof(IllustItem.BookmarkId), converter: new FavoriteIconConverter(IsFavoriteVisible))
                .Binding(IsVisibleProperty, nameof(IllustItem.IsFavorite))
                .DynamicResource(Label.FontFamilyProperty, ThemeBase.IconSolidFontFamily);

                #endregion

                if (hideUser)
                {
                    return new CardView
                    {
                        Padding = 0,
                        Margin = 0,
                        CornerRadius = 10,
                        ShadowColor = StyleDefinition.ColorLightShadow,
                        ShadowOffset = new Size(1, 1),
                        Content = new Grid
                        {
                            HorizontalOptions = LayoutOptions.Fill,
                            RowSpacing = 0,
                            RowDefinitions =
                            {
                                new RowDefinition().Binding(RowDefinition.HeightProperty, nameof(IllustItem.ImageHeight)),
                                new RowDefinition { Height = 30 }
                            },
                            Children =
                            {
                                image,
                                r18,
                                pages,
                                anime,

                                // stacklayout: title
                                new Grid
                                {
                                    ColumnDefinitions =
                                    {
                                        new ColumnDefinition(),
                                        new ColumnDefinition { Width = 20 }
                                    },
                                    VerticalOptions = LayoutOptions.Center,
                                    Padding = new Thickness(0, 0, 8, 0),
                                    Children =
                                    {
                                        title.Binding(Label.TextProperty, nameof(IllustItem.Title)),
                                        favorite.GridColumn(1)
                                    }
                                }
                                .GridRow(1)
                            }
                        }
                    }
                    .DynamicResource(BackgroundColorProperty, ThemeBase.CardBackgroundColor);
                }

                return new CardView
                {
                    Padding = 0,
                    Margin = 0,
                    CornerRadius = 10,
                    ShadowColor = StyleDefinition.ColorLightShadow,
                    ShadowOffset = new Size(1, 1),
                    Content = new Grid
                    {
                        HorizontalOptions = LayoutOptions.Fill,
                        RowSpacing = 0,
                        RowDefinitions =
                        {
                            new RowDefinition().Binding(RowDefinition.HeightProperty, nameof(IllustItem.ImageHeight)),
                            new RowDefinition { Height = 30 },
                            new RowDefinition { Height = 40 }
                        },
                        Children =
                        {
                            image,
                            r18,
                            pages,
                            anime,

                            title.Binding(Label.TextProperty, nameof(IllustItem.RankTitle)).GridRow(1),

                            // stacklayout: user
                            new Grid
                            {
                                ColumnDefinitions =
                                {
                                    new ColumnDefinition { Width = 30 },
                                    new ColumnDefinition(),
                                    new ColumnDefinition { Width = 20 }
                                },
                                Padding = new Thickness(8, 0, 8, 8),
                                Children =
                                {
                                    // user icon
                                    new CircleImage
                                    {
                                        WidthRequest = 30,
                                        HeightRequest = 30,
                                        Aspect = Aspect.AspectFill
                                    }
                                    .Binding(Image.SourceProperty, nameof(IIllustItem.ProfileImage)),

                                    // user name
                                    new Label
                                    {
                                        HorizontalOptions = LayoutOptions.FillAndExpand,
                                        VerticalOptions = LayoutOptions.Center,
                                        LineBreakMode = LineBreakMode.TailTruncation,
                                        FontSize = StyleDefinition.FontSizeMicro
                                    }
                                    .Binding(Label.TextProperty, nameof(IIllustItem.UserName))
                                    .DynamicResource(Label.TextColorProperty, ThemeBase.SubTextColor)
                                    .GridColumn(1),

                                    // label: favorite
                                    favorite.GridColumn(2)
                                }
                            }
                            .GridRow(2)
                        }
                    }
                }
                .DynamicResource(BackgroundColorProperty, ThemeBase.CardBackgroundColor);
            });
        }

        #region - Illust Tasks -

        protected void DoLoadIllusts(bool force = false, bool bottom = false)
        {
#if DEBUG
            App.DebugPrint($"start loading data, force: {force}");
#endif
            illustData = DoLoadIllustData(force);
            if (illustData == null)
            {
                MainThread.BeginInvokeOnMainThread(async () =>
                {
                    if (!IsRedirectLogin)
                    {
                        string extra;
                        if (lastError != null)
                        {
                            if (lastError.Length > 40)
                            {
                                extra = $"\n{lastError.Substring(0, 40)}...";
                            }
                            else
                            {
                                extra = $"\n{lastError}";
                            }
                        }
                        else
                        {
                            extra = string.Empty;
                        }
                        _ = DisplayAlert(ResourceHelper.Title,
                            ResourceHelper.FailedResponse + extra,
                            ResourceHelper.Ok);
                    }
                    else
                    {
                        var result = await DisplayAlert(
                            ResourceHelper.Title,
                            ResourceHelper.ConfirmLogin,
                            ResourceHelper.Yes, ResourceHelper.No);
                        if (result)
                        {
                            AppShell.Current.PushToLogin(() =>
                            {
                                Task.Run(() => AppShell.Current.DoLoginInformation(true));
                                StartLoad(true);
                            });
                        }
                    }
                });
                //App.DebugError("illusts.load", "failed to load illusts data.");
                IsLoading = false;
                IsBottomLoading = false;
                return;
            }
            if (force && IsFavoriteVisible)
            {
                var now = DateTime.Now;
                LastUpdated = now;
                lastUpdated = now;
            }

            var r18 = Configs.IsOnR18;
            var data = DoGetIllustList(illustData).Where(i => i != null && (r18 || !i.IsRestrict));

            var collection = new IllustCollection(data);
            var favorites = Stores.Favorites;
            foreach (var item in collection)
            {
                if (item.Image == null)
                {
                    item.Image = StyleDefinition.DownloadBackground;
                }
                item.IsFavorite =
                    item.BookmarkId != null ||
                    favorites.Any(i => i.Id == item.Id);
            }
            DoIllustsLoaded(collection, bottom);

            DoLoadImages(collection);
        }

        void DoLoadImages(IllustCollection collection)
        {
            if (task != null)
            {
                task.Dispose();
                task = null;
            }
            task = ParallelTask.Start("collection.load", 0, collection.Count, Configs.MaxThreads, i =>
            {
                if (!collection.Running)
                {
                    return false;
                }
                var illust = collection[i];
                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;
                    }
                }

                if (illust.ProfileUrl != null)
                {
                    var userImage = Stores.LoadUserProfileImage(illust.ProfileUrl);
                    if (userImage != null)
                    {
                        illust.ProfileImage = userImage;
                    }
                }
                return true;
            });
        }

        #endregion
    }

    public abstract class IllustScrollableCollectionPage<T> : IllustCollectionPage<T>
    {
        protected const int SCROLL_OFFSET = 33;
        protected ScrollDirection scrollDirection = ScrollDirection.Stop;

        private double lastScrollY = double.MinValue;
        private double lastRefreshY = double.MinValue;
        private double offset;

        protected bool IsScrollingDown(double y)
        {
            if (y > lastScrollY)
            {
                if (scrollDirection != ScrollDirection.Down)
                {
                    scrollDirection = ScrollDirection.Down;
                }
                return true;
            }
            else
            {
                if (scrollDirection != ScrollDirection.Up)
                {
                    scrollDirection = ScrollDirection.Up;
                }
                return false;
            }
        }
        protected void SetOffset(double off)
        {
            offset = off;
        }

        protected abstract bool CheckRefresh();

        protected override void StartLoad(bool force = false, bool isBottom = false)
        {
            if (!isBottom)
            {
                lastRefreshY = double.MinValue;
            }
            base.StartLoad(force, isBottom);
        }

        protected override IllustCollection GetIllustsLoadedCollection(IllustCollection collection, bool bottom)
        {
            var now = IllustCollection;
            if (now == null)
            {
                now = collection;
                IllustCollection = now;
            }
            else
            {
                //now = new IllustCollection(now.Concat(collection));
                now.AddRange(collection);
            }
            return now;
        }

        protected void OnScrolled(double y)
        {
            lastScrollY = y;

            if (y > 0 && offset > 0 && y - topOffset > offset)
            {
                if (IsLoading || IsBottomLoading)
                {
                    return;
                }
                if (y - lastRefreshY > 200)
                {
                    if (CheckRefresh())
                    {
                        lastRefreshY = y;
#if DEBUG
                        App.DebugPrint("start to load next page");
#endif
                        StartLoad(true, true);
                    }
                }
            }
        }
    }

    public enum ScrollDirection
    {
        Stop,
        Up,
        Down
    }

    public class IllustCollection : List<IllustItem>, IIllustCollectionChanged
    {
        private static IllustCollection empty;

        public static IllustCollection Empty
        {
            get
            {
                if (empty == null)
                {
                    empty = new IllustCollection();
                }
                return empty;
            }
        }

        public event EventHandler<CollectionChangedEventArgs> CollectionChanged;

        public IllustCollection() : base()
        {
            Running = true;
        }
        public IllustCollection(IEnumerable<IllustItem> illusts) : base(illusts)
        {
            Running = true;
        }

        public void AddRange(List<IllustItem> items)
        {
            var e = new CollectionChangedEventArgs
            {
                NewStartingIndex = Count,
                NewItems = items
            };
            base.AddRange(items);
            if (MainThread.IsMainThread)
            {
                CollectionChanged?.Invoke(this, e);
            }
            else
            {
                MainThread.BeginInvokeOnMainThread(() =>
                    CollectionChanged?.Invoke(this, e));
            }
        }

        public bool Running { get; set; }
    }

    public enum IllustType
    {
        Illust = 0,
        Manga = 1,
        Anime = 2
    }

    public interface IIllustItem
    {
        string UserId { get; }
        string UserName { get; }
        ImageSource ProfileImage { get; }
    }

    [JsonObject(MemberSerialization.OptIn)]
    public class IllustItem : BindableObject, IIllustItem
    {
        private static IllustItem empty;
        public static IllustItem Empty
        {
            get
            {
                if (empty == null)
                {
                    empty = new IllustItem();
                }
                return empty;
            }
        }

        public static readonly BindableProperty ImageProperty = BindableProperty.Create(
            nameof(Image), typeof(ImageSource), typeof(IllustItem));
        public static readonly BindableProperty ProfileImageProperty = BindableProperty.Create(
            nameof(ProfileImage), typeof(ImageSource), typeof(IllustItem));
        public static readonly BindableProperty ImageHeightProperty = BindableProperty.Create(
            nameof(ImageHeight), typeof(GridLength), typeof(IllustItem), GridLength.Auto);
        public static readonly BindableProperty IsFavoriteProperty = BindableProperty.Create(
            nameof(IsFavorite), typeof(bool), typeof(IllustItem));
        public static readonly BindableProperty BookmarkIdProperty = BindableProperty.Create(
            nameof(BookmarkId), typeof(string), typeof(IllustItem));

        [JsonProperty]
        public string Title { get; set; }
        public int Rank { get; set; }
        public string RankTitle => Rank > 0 ? $"#{Rank}  {Title}" : Title;
        public ImageSource Image
        {
            get => (ImageSource)GetValue(ImageProperty);
            set => SetValue(ImageProperty, value);
        }
        public ImageSource ProfileImage
        {
            get => (ImageSource)GetValue(ProfileImageProperty);
            set => SetValue(ProfileImageProperty, value);
        }
        public GridLength ImageHeight
        {
            get => (GridLength)GetValue(ImageHeightProperty);
            set => SetValue(ImageHeightProperty, value);
        }
        public bool IsFavorite
        {
            get => (bool)GetValue(IsFavoriteProperty);
            set => SetValue(IsFavoriteProperty, value);
        }
        public bool IsPlaying { get; set; }

        [JsonProperty]
        public string Id { get; set; }
        [JsonProperty]
        public string BookmarkId
        {
            get => (string)GetValue(BookmarkIdProperty);
            set => SetValue(BookmarkIdProperty, value);
        }
        [JsonProperty]
        public DateTime FavoriteDateUtc { get; set; }
        [JsonProperty]
        public string ImageUrl { get; set; }
        [JsonProperty]
        public bool IsRestrict { get; set; }
        [JsonProperty]
        public string[] Tags { get; set; }
        [JsonProperty]
        public string ProfileUrl { get; set; }
        [JsonProperty]
        public string UserId { get; set; }
        [JsonProperty]
        public string UserName { get; set; }
        [JsonProperty]
        public int Width { get; set; }
        [JsonProperty]
        public int Height { get; set; }
        [JsonProperty]
        public int PageCount { get; set; }
        [JsonProperty]
        public double ImageHeightValue
        {
            get => ImageHeight.IsAuto ? -1 : ImageHeight.Value;
            set => ImageHeight = value > 0 ? value : GridLength.Auto;
        }
        [JsonProperty]
        public int YesRank { get; set; }
        [JsonProperty]
        public int RatingCount { get; set; }
        [JsonProperty]
        public int ViewCount { get; set; }
        [JsonProperty]
        public long UploadTimestamp { get; set; }
        [JsonProperty]
        public IllustType IllustType { get; set; }

        public string PageCountText => $"{StyleDefinition.IconLayer} {PageCount}";
        public bool IsPageVisible => PageCount > 1;
        public bool IsAnimeVisible => IllustType == IllustType.Anime;
    }
}
