using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using ServiceStack.ServiceHost;
using ServiceStack.Text.Controller;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Api.UserLibrary
{
    /// 
    /// Class MarkItemByNameFavorite
    /// 
    [Route("/Users/{UserId}/Favorites/Artists/{Name}", "POST")]
    [Route("/Users/{UserId}/Favorites/Persons/{Name}", "POST")]
    [Route("/Users/{UserId}/Favorites/Studios/{Name}", "POST")]
    [Route("/Users/{UserId}/Favorites/Genres/{Name}", "POST")]
    [Api(Description = "Marks something as a favorite")]
    public class MarkItemByNameFavorite : IReturnVoid
    {
        /// 
        /// Gets or sets the user id.
        /// 
        /// The user id.
        [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
        public Guid UserId { get; set; }
        /// 
        /// Gets or sets the name.
        /// 
        /// The name.
        [ApiMember(Name = "Name", Description = "The name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
        public string Name { get; set; }
    }
    /// 
    /// Class UnmarkItemByNameFavorite
    /// 
    [Route("/Users/{UserId}/Favorites/Artists/{Name}", "DELETE")]
    [Route("/Users/{UserId}/Favorites/Persons/{Name}", "DELETE")]
    [Route("/Users/{UserId}/Favorites/Studios/{Name}", "DELETE")]
    [Route("/Users/{UserId}/Favorites/Genres/{Name}", "DELETE")]
    [Api(Description = "Unmarks something as a favorite")]
    public class UnmarkItemByNameFavorite : IReturnVoid
    {
        /// 
        /// Gets or sets the user id.
        /// 
        /// The user id.
        [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
        public Guid UserId { get; set; }
        /// 
        /// Gets or sets the name.
        /// 
        /// The name.
        [ApiMember(Name = "Name", Description = "The name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
        public string Name { get; set; }
    }
    /// 
    /// Class UpdateItemByNameRating
    /// 
    [Route("/Users/{UserId}/Ratings/Artists/{Name}", "POST")]
    [Route("/Users/{UserId}/Ratings/Persons/{Name}", "POST")]
    [Route("/Users/{UserId}/Ratings/Studios/{Name}", "POST")]
    [Route("/Users/{UserId}/Ratings/Genres/{Name}", "POST")]
    [Api(Description = "Updates a user's rating for an item")]
    public class UpdateItemByNameRating : IReturnVoid
    {
        /// 
        /// Gets or sets the user id.
        /// 
        /// The user id.
        [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
        public Guid UserId { get; set; }
        /// 
        /// Gets or sets the name.
        /// 
        /// The name.
        [ApiMember(Name = "Name", Description = "The name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
        public string Name { get; set; }
        /// 
        /// Gets or sets a value indicating whether this  is likes.
        /// 
        /// true if likes; otherwise, false.
        [ApiMember(Name = "Likes", Description = "Whether the user likes the item or not. true/false", IsRequired = true, DataType = "boolean", ParameterType = "query", Verb = "POST")]
        public bool Likes { get; set; }
    }
    /// 
    /// Class DeleteItemByNameRating
    /// 
    [Route("/Users/{UserId}/Ratings/Artists/{Name}", "DELETE")]
    [Route("/Users/{UserId}/Ratings/Persons/{Name}", "DELETE")]
    [Route("/Users/{UserId}/Ratings/Studios/{Name}", "DELETE")]
    [Route("/Users/{UserId}/Ratings/Genres/{Name}", "DELETE")]
    [Api(Description = "Deletes a user's saved personal rating for an item")]
    public class DeleteItemByNameRating : IReturnVoid
    {
        /// 
        /// Gets or sets the user id.
        /// 
        /// The user id.
        [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
        public Guid UserId { get; set; }
        /// 
        /// Gets or sets the name.
        /// 
        /// The name.
        [ApiMember(Name = "Name", Description = "The item name (genre, person, year, studio, artist)", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
        public string Name { get; set; }
    }
    /// 
    /// Class ItemByNameUserDataService
    /// 
    public class ItemByNameUserDataService : BaseApiService
    {
        /// 
        /// The user data repository
        /// 
        protected readonly IUserDataRepository UserDataRepository;
        /// 
        /// The library manager
        /// 
        protected readonly ILibraryManager LibraryManager;
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The user data repository.
        /// The library manager.
        public ItemByNameUserDataService(IUserDataRepository userDataRepository, ILibraryManager libraryManager)
        {
            UserDataRepository = userDataRepository;
            LibraryManager = libraryManager;
        }
        /// 
        /// Posts the specified request.
        /// 
        /// The request.
        public void Post(MarkItemByNameFavorite request)
        {
            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
            var type = pathInfo.GetArgumentValue(3);
            var task = MarkFavorite(request.UserId, type, request.Name, true);
            Task.WaitAll(task);
        }
        /// 
        /// Posts the specified request.
        /// 
        /// The request.
        public void Post(UpdateItemByNameRating request)
        {
            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
            var type = pathInfo.GetArgumentValue(3);
            var task = MarkLike(request.UserId, type, request.Name, request.Likes);
            Task.WaitAll(task);
        }
        /// 
        /// Deletes the specified request.
        /// 
        /// The request.
        public void Delete(UnmarkItemByNameFavorite request)
        {
            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
            var type = pathInfo.GetArgumentValue(3);
            var task = MarkFavorite(request.UserId, type, request.Name, false);
            Task.WaitAll(task);
        }
        /// 
        /// Deletes the specified request.
        /// 
        /// The request.
        public void Delete(DeleteItemByNameRating request)
        {
            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
            var type = pathInfo.GetArgumentValue(3);
            var task = MarkLike(request.UserId, type, request.Name, null);
            Task.WaitAll(task);
        }
        /// 
        /// Marks the favorite.
        /// 
        /// The user id.
        /// The type.
        /// The name.
        /// if set to true [is favorite].
        /// Task.
        protected async Task MarkFavorite(Guid userId, string type, string name, bool isFavorite)
        {
            BaseItem item;
            if (string.Equals(type, "Persons"))
            {
                item = await LibraryManager.GetPerson(name).ConfigureAwait(false);
            }
            else if (string.Equals(type, "Artists"))
            {
                item = await LibraryManager.GetArtist(name).ConfigureAwait(false);
            }
            else if (string.Equals(type, "Genres"))
            {
                item = await LibraryManager.GetGenre(name).ConfigureAwait(false);
            }
            else if (string.Equals(type, "Studios"))
            {
                item = await LibraryManager.GetStudio(name).ConfigureAwait(false);
            }
            else
            {
                throw new ArgumentException();
            }
            var key = item.GetUserDataKey();
            
            // Get the user data for this item
            var data = await UserDataRepository.GetUserData(userId, key).ConfigureAwait(false);
            // Set favorite status
            data.IsFavorite = isFavorite;
            await UserDataRepository.SaveUserData(userId, key, data, CancellationToken.None).ConfigureAwait(false);
        }
        /// 
        /// Marks the like.
        /// 
        /// The user id.
        /// The type.
        /// The name.
        /// if set to true [likes].
        /// Task.
        protected async Task MarkLike(Guid userId, string type, string name, bool? likes)
        {
            BaseItem item;
            if (string.Equals(type, "Persons"))
            {
                item = await LibraryManager.GetPerson(name).ConfigureAwait(false);
            }
            else if (string.Equals(type, "Artists"))
            {
                item = await LibraryManager.GetArtist(name).ConfigureAwait(false);
            }
            else if (string.Equals(type, "Genres"))
            {
                item = await LibraryManager.GetGenre(name).ConfigureAwait(false);
            }
            else if (string.Equals(type, "Studios"))
            {
                item = await LibraryManager.GetStudio(name).ConfigureAwait(false);
            }
            else
            {
                throw new ArgumentException();
            }
            var key = item.GetUserDataKey();
            
            // Get the user data for this item
            var data = await UserDataRepository.GetUserData(userId, key).ConfigureAwait(false);
            data.Likes = likes;
            await UserDataRepository.SaveUserData(userId, key, data, CancellationToken.None).ConfigureAwait(false);
        }
    }
}