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.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Entities.TV
{
    /// 
    /// Class Series
    /// 
    public class Series : Folder, IHasSoundtracks, IHasTrailers, IHasDisplayOrder, IHasLookupInfo, IHasSpecialFeatures, IMetadataContainer, IHasOriginalTitle
    {
        public List SpecialFeatureIds { get; set; }
        public List SoundtrackIds { get; set; }
        public string OriginalTitle { get; set; }
        public int SeasonCount { get; set; }
        public int? AnimeSeriesIndex { get; set; }
        public Series()
        {
            AirDays = new List();
            SpecialFeatureIds = new List();
            SoundtrackIds = new List();
            RemoteTrailers = new List();
            LocalTrailerIds = new List();
            RemoteTrailerIds = new List();
            DisplaySpecialsWithSeasons = true;
        }
        [IgnoreDataMember]
        public override bool SupportsAddingToPlaylist
        {
            get { return true; }
        }
        [IgnoreDataMember]
        public override bool IsPreSorted
        {
            get
            {
                return true;
            }
        }
        public bool DisplaySpecialsWithSeasons { get; set; }
        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 GetRecursiveChildren(i => i is Episode)
                        .Select(i => i.DateCreated)
                        .OrderByDescending(i => i)
                        .FirstOrDefault();
            }
        }
        /// 
        /// Series aren't included directly in indices - Their Episodes will roll up to them
        /// 
        /// true if [include in index]; otherwise, false.
        [IgnoreDataMember]
        public override bool IncludeInIndex
        {
            get
            {
                return false;
            }
        }
        /// 
        /// Gets the user data key.
        /// 
        /// System.String.
        protected override string CreateUserDataKey()
        {
            return this.GetProviderId(MetadataProviders.Tvdb) ?? this.GetProviderId(MetadataProviders.Tvcom) ?? base.CreateUserDataKey();
        }
        /// 
        /// 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