using System;
using System.Linq;
using Jellyfin.Api.Helpers;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using Microsoft.AspNetCore.Http;
namespace Jellyfin.Api.Extensions
{
    /// 
    /// Dto Extensions.
    /// 
    public static class DtoExtensions
    {
        /// 
        /// Add Dto Item fields.
        /// 
        /// 
        /// Converted from IHasItemFields.
        /// Legacy order: 1.
        /// 
        /// DtoOptions object.
        /// Comma delimited string of fields.
        /// Modified DtoOptions object.
        internal static DtoOptions AddItemFields(this DtoOptions dtoOptions, string fields)
        {
            if (string.IsNullOrEmpty(fields))
            {
                dtoOptions.Fields = Array.Empty();
            }
            else
            {
                dtoOptions.Fields = fields.Split(',')
                    .Select(v =>
                    {
                        if (Enum.TryParse(v, true, out ItemFields value))
                        {
                            return (ItemFields?)value;
                        }
                        return null;
                    })
                    .Where(i => i.HasValue)
                    .Select(i => i!.Value)
                    .ToArray();
            }
            return dtoOptions;
        }
        /// 
        /// Add additional fields depending on client.
        /// 
        /// 
        /// Use in place of GetDtoOptions.
        /// Legacy order: 2.
        /// 
        /// DtoOptions object.
        /// Current request.
        /// Modified DtoOptions object.
        internal static DtoOptions AddClientFields(
            this DtoOptions dtoOptions, HttpRequest request)
        {
            dtoOptions.Fields ??= Array.Empty();
            string? client = ClaimHelpers.GetClient(request.HttpContext.User);
            // No client in claim
            if (string.IsNullOrEmpty(client))
            {
                return dtoOptions;
            }
            if (!dtoOptions.ContainsField(ItemFields.RecursiveItemCount))
            {
                if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    int oldLen = dtoOptions.Fields.Length;
                    var arr = new ItemFields[oldLen + 1];
                    dtoOptions.Fields.CopyTo(arr, 0);
                    arr[oldLen] = ItemFields.RecursiveItemCount;
                    dtoOptions.Fields = arr;
                }
            }
            if (!dtoOptions.ContainsField(ItemFields.ChildCount))
            {
                if (client.IndexOf("kodi", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("wmc", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("media center", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("classic", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("roku", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("samsung", StringComparison.OrdinalIgnoreCase) != -1 ||
                    client.IndexOf("androidtv", StringComparison.OrdinalIgnoreCase) != -1)
                {
                    int oldLen = dtoOptions.Fields.Length;
                    var arr = new ItemFields[oldLen + 1];
                    dtoOptions.Fields.CopyTo(arr, 0);
                    arr[oldLen] = ItemFields.ChildCount;
                    dtoOptions.Fields = arr;
                }
            }
            return dtoOptions;
        }
        /// 
        /// Add additional DtoOptions.
        /// 
        /// 
        /// Converted from IHasDtoOptions.
        /// Legacy order: 3.
        /// 
        /// DtoOptions object.
        /// Enable images.
        /// Enable user data.
        /// Image type limit.
        /// Enable image types.
        /// Modified DtoOptions object.
        internal static DtoOptions AddAdditionalDtoOptions(
            this DtoOptions dtoOptions,
            bool? enableImages,
            bool? enableUserData,
            int? imageTypeLimit,
            string enableImageTypes)
        {
            dtoOptions.EnableImages = enableImages ?? true;
            if (imageTypeLimit.HasValue)
            {
                dtoOptions.ImageTypeLimit = imageTypeLimit.Value;
            }
            if (enableUserData.HasValue)
            {
                dtoOptions.EnableUserData = enableUserData.Value;
            }
            if (!string.IsNullOrWhiteSpace(enableImageTypes))
            {
                dtoOptions.ImageTypes = enableImageTypes.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true))
                    .ToArray();
            }
            return dtoOptions;
        }
        /// 
        /// Check if DtoOptions contains field.
        /// 
        /// DtoOptions object.
        /// Field to check.
        /// Field existence.
        internal static bool ContainsField(this DtoOptions dtoOptions, ItemFields field)
            => dtoOptions.Fields != null && dtoOptions.Fields.Contains(field);
    }
}