using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using JetBrains.Annotations;
using Kyoo.Controllers;
using Kyoo.Models.Attributes;
namespace Kyoo.Models
{
	/// 
	/// A class to represent a single show's episode.
	/// 
	public class Episode : IResource
	{
		/// 
		public int ID { get; set; }
		/// 
		[Computed] public string Slug
		{
			get
			{
				if (ShowSlug == null && Show == null)
					return GetSlug(ShowID.ToString(), SeasonNumber, EpisodeNumber, AbsoluteNumber);
				return GetSlug(ShowSlug ?? Show.Slug, SeasonNumber, EpisodeNumber, AbsoluteNumber);
			}
			[UsedImplicitly] [NotNull] private set
			{
				if (value == null)
					throw new ArgumentNullException(nameof(value));
				
				Match match = Regex.Match(value, @"(?.+)-s(?\d+)e(?\d+)");
				if (match.Success)
				{
					ShowSlug = match.Groups["show"].Value;
					SeasonNumber = int.Parse(match.Groups["season"].Value);
					EpisodeNumber = int.Parse(match.Groups["episode"].Value);
				}
				else
				{
					match = Regex.Match(value, @"(?.+)-(?\d+)");
					if (match.Success)
					{
						ShowSlug = match.Groups["show"].Value;
						AbsoluteNumber = int.Parse(match.Groups["absolute"].Value);
					}
					else
						ShowSlug = value;
					SeasonNumber = null;
					EpisodeNumber = null;
				}
			}
		}
		/// 
		/// The slug of the Show that contain this episode. If this is not set, this episode is ill-formed.
		/// 
		[SerializeIgnore] public string ShowSlug { private get; set; }
		
		/// 
		/// The ID of the Show containing this episode.
		/// 
		[SerializeIgnore] public int ShowID { get; set; }
		/// 
		/// The show that contains this episode. This must be explicitly loaded via a call to .
		/// 
		[LoadableRelation(nameof(ShowID))] public Show Show { get; set; }
		
		/// 
		/// The ID of the Season containing this episode.
		/// 
		[SerializeIgnore] public int? SeasonID { get; set; }
		/// 
		/// The season that contains this episode. This must be explicitly loaded via a call to .
		/// This can be null if the season is unknown and the episode is only identified by it's .
		/// 
		[LoadableRelation(nameof(SeasonID))] public Season Season { get; set; }
		/// 
		/// The season in witch this episode is in.
		/// 
		public int? SeasonNumber { get; set; }
		
		/// 
		/// The number of this episode is it's season.
		/// 
		public int? EpisodeNumber { get; set; }
		
		/// 
		/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
		/// 
		public int? AbsoluteNumber { get; set; }
		
		/// 
		/// The path of the video file for this episode. Any format supported by a  is allowed.
		/// 
		[SerializeIgnore] public string Path { get; set; }
		/// 
		/// The path of this episode's thumbnail.
		/// By default, the http path for the thumbnail is returned from the public API.
		/// This can be disabled using the internal query flag.
		/// 
		[SerializeAs("{HOST}/api/episodes/{Slug}/thumb")] public string Thumb { get; set; }
		
		/// 
		/// The title of this episode.
		/// 
		public string Title { get; set; }
		
		/// 
		/// The overview of this episode.
		/// 
		public string Overview { get; set; }
		
		/// 
		/// The release date of this episode. It can be null if unknown.
		/// 
		public DateTime? ReleaseDate { get; set; }
		/// 
		/// The link to metadata providers that this episode has. See  for more information.
		/// 
		[EditableRelation] [LoadableRelation] public ICollection> ExternalIDs { get; set; }
		/// 
		/// The list of tracks this episode has. This lists video, audio and subtitles available.
		/// 
		[EditableRelation] [LoadableRelation] public ICollection