using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Users;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Controller.Entities.TV
{
    /// 
    /// Class Series
    /// 
    public class Series : Folder, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IMetadataContainer
    {
        public Series()
        {
            AirDays = new List();
            RemoteTrailers = new List();
            LocalTrailerIds = new List();
            RemoteTrailerIds = new List();
        }
        [IgnoreDataMember]
        public override bool SupportsAddingToPlaylist
        {
            get { return true; }
        }
        [IgnoreDataMember]
        public override bool IsPreSorted
        {
            get
            {
                return true;
            }
        }
        [IgnoreDataMember]
        public override bool SupportsDateLastMediaAdded
        {
            get
            {
                return true;
            }
        }
        public List LocalTrailerIds { get; set; }
        public List RemoteTrailerIds { get; set; }
        public List RemoteTrailers { get; set; }
        /// 
        /// airdate, dvd or absolute
        /// 
        public string DisplayOrder { get; set; }
        /// 
        /// Gets or sets the status.
        /// 
        /// The status.
        public SeriesStatus? Status { get; set; }
        /// 
        /// Gets or sets the air days.
        /// 
        /// The air days.
        public List AirDays { get; set; }
        /// 
        /// Gets or sets the air time.
        /// 
        /// The air time.
        public string AirTime { get; set; }
        /// 
        /// Gets or sets the date last episode added.
        /// 
        /// The date last episode added.
        [IgnoreDataMember]
        public DateTime DateLastEpisodeAdded
        {
            get
            {
                return DateLastMediaAdded ?? DateTime.MinValue;
            }
        }
        public override double? GetDefaultPrimaryImageAspectRatio()
        {
            double value = 2;
            value /= 3;
            return value;
        }
        public override string CreatePresentationUniqueKey()
        {
            if (LibraryManager.GetLibraryOptions(this).EnableAutomaticSeriesGrouping)
            {
                var userdatakeys = GetUserDataKeys();
                if (userdatakeys.Count > 1)
                {
                    return AddLibrariesToPresentationUniqueKey(userdatakeys[0]);
                }
            }
            return base.CreatePresentationUniqueKey();
        }
        private string AddLibrariesToPresentationUniqueKey(string key)
        {
            var lang = GetPreferredMetadataLanguage();
            if (!string.IsNullOrWhiteSpace(lang))
            {
                key += "-" + lang;
            }
            var folders = LibraryManager.GetCollectionFolders(this)
                .Select(i => i.Id.ToString("N"))
                .ToArray();
            if (folders.Length == 0)
            {
                return key;
            }
            return key + "-" + string.Join("-", folders);
        }
        private static string GetUniqueSeriesKey(BaseItem series)
        {
            return series.GetPresentationUniqueKey();
        }
        public override int GetChildCount(User user)
        {
            var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey;
            var seriesKey = GetUniqueSeriesKey(this);
            var result = LibraryManager.GetCount(new InternalItemsQuery(user)
            {
                AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey,
                SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null,
                IncludeItemTypes = new[] { typeof(Season).Name },
                IsVirtualItem = false,
                Limit = 0,
                DtoOptions = new Dto.DtoOptions
                {
                    Fields = new List
                    {
                    },
                    EnableImages = false
                }
            });
            return result;
        }
        public override int GetRecursiveChildCount(User user)
        {
            var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey;
            var seriesKey = GetUniqueSeriesKey(this);
            var query = new InternalItemsQuery(user)
            {
                AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey,
                SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null,
                DtoOptions = new Dto.DtoOptions
                {
                    Fields = new List
                    {
                        
                    },
                    EnableImages = false
                }
            };
            if (query.IncludeItemTypes.Length == 0)
            {
                query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
            }
            query.IsVirtualItem = false;
            query.Limit = 0;
            var totalRecordCount = LibraryManager.GetCount(query);
            return totalRecordCount;
        }
        /// 
        /// Gets the user data key.
        /// 
        /// System.String.
        public override List GetUserDataKeys()
        {
            var list = base.GetUserDataKeys();
            var key = this.GetProviderId(MetadataProviders.Imdb);
            if (!string.IsNullOrWhiteSpace(key))
            {
                list.Insert(0, key);
            }
            key = this.GetProviderId(MetadataProviders.Tvdb);
            if (!string.IsNullOrWhiteSpace(key))
            {
                list.Insert(0, key);
            }
            return list;
        }
        /// 
        /// Gets the trailer ids.
        /// 
        /// List<Guid>.
        public List GetTrailerIds()
        {
            var list = LocalTrailerIds.ToList();
            list.AddRange(RemoteTrailerIds);
            return list;
        }
        // Studio, Genre and Rating will all be the same so makes no sense to index by these
        protected override IEnumerable GetIndexByOptions()
        {
            return new List {
                {"None"},
                {"Performer"},
                {"Director"},
                {"Year"},
            };
        }
        [IgnoreDataMember]
        public bool ContainsEpisodesWithoutSeasonFolders
        {
            get
            {
                return Children.OfType