using Bit.BlazorUI;
using JSMR.Application.Creators.Queries.Search;
using JSMR.Application.Creators.Queries.Search.Contracts;
using JSMR.Application.Enums;
using JSMR.Application.Tags.Queries.Search;
using JSMR.Application.Tags.Queries.Search.Contracts;
using JSMR.Application.VoiceWorks.Queries.Search;
using JSMR.Domain.Enums;
using JSMR.UI.Blazor.Enums;

namespace JSMR.UI.Blazor.Services;

public sealed class LookupDataService(VoiceWorksClient client) : ILookupDataService
{
    // simple in-memory caches for WASM
    private List<BitDropdownItem<int>>? _tags;
    private List<BitDropdownItem<int>>? _creators;

    public List<BitDropdownItem<Locale>> GetLocales() =>
    [
        new() { Text = "Japanese", Value = Locale.Japanese },
        new() { Text = "English",  Value = Locale.English  }
    ];

    public List<BitDropdownItem<SaleStatus?>> GetSaleStatuses() =>
    [
        new() { Text = "Available", Value = SaleStatus.Available },
        new() { Text = "Upcoming",  Value = SaleStatus.Upcoming  },
        new() { Text = "All",       Value = null                 }
    ];

    public List<SelectOption<SaleStatus?>> GetSaleStatuses2() =>
    [
        new() { Label = "Available", Value = SaleStatus.Available },
        new() { Label = "Upcoming",  Value = SaleStatus.Upcoming  },
        new() { Label = "All",       Value = null                 }
    ];

    public List<BitDropdownItem<CircleStatus?>> GetCircleStatuses() =>
    [
        new() { Text = "Not Blacklisted", Value = CircleStatus.NotBlacklisted },
        new() { Text = "Favorites",       Value = CircleStatus.Favorited      },
        new() { Text = "Blacklisted",     Value = CircleStatus.Blacklisted    },
        new() { Text = "All",             Value = null                        }
    ];

    public List<BitDropdownItem<TagStatus?>> GetTagStatuses() =>
    [
        new() { Text = "Not Blacklisted",              Value = TagStatus.NotBlacklisted          },
        new() { Text = "Favorites (Exclude Blacklisted)", Value = TagStatus.FavoriteExcludeBlacklist },
        new() { Text = "Favorites (Include Blacklisted)", Value = TagStatus.FavoriteIncludeBlacklist },
        new() { Text = "Blacklisted",                  Value = TagStatus.Blacklisted             },
        new() { Text = "All",                          Value = null                              }
    ];

    public List<BitDropdownItem<CreatorStatus?>> GetCreatorStatuses() =>
    [
        new() { Text = "Not Blacklisted",              Value = CreatorStatus.NotBlacklisted          },
        new() { Text = "Favorites (Exclude Blacklisted)", Value = CreatorStatus.FavoriteExcludeBlacklist },
        new() { Text = "Favorites (Include Blacklisted)", Value = CreatorStatus.FavoriteIncludeBlacklist },
        new() { Text = "Blacklisted",                  Value = CreatorStatus.Blacklisted             },
        new() { Text = "All",                          Value = null                                 }
    ];

    public List<BitDropdownItem<Language>> GetLanguages() =>
    [
        new() { Text = "Japanese",             Value = Language.Japanese           },
        new() { Text = "English",              Value = Language.English            },
        new() { Text = "Chinese (Traditional)",Value = Language.ChineseTraditional },
        new() { Text = "Chinese (Simplified)", Value = Language.ChineseSimplified  },
        new() { Text = "Korean",               Value = Language.Korean             }
    ];

    public List<BitDropdownItem<AgeRating>> GetAgeRatings() =>
    [
        new() { Text = "All Ages", Value = AgeRating.AllAges },
        new() { Text = "R15",      Value = AgeRating.R15     },
        new() { Text = "R18",      Value = AgeRating.R18     }
    ];

    public List<BitDropdownItem<VoiceWorkSort>> GetSortOptions() =>
    [
        new()
        {
            Text = "Release Date - New to Old",
            Value = VoiceWorkSort.ReleaseDateNewToOld
        },
        new()
        {
            Text = "Release Date - Old to New",
            Value = VoiceWorkSort.ReleaseDateOldToNew
        },
        new()
        {
            Text = "Best Selling",
            Value = VoiceWorkSort.BestSelling
        },
        new()
        {
            Text = "Most Favorited",
            Value = VoiceWorkSort.MostFavorited
        }
    ];

    public async Task<List<BitDropdownItem<int>>> GetTagsAsync(CancellationToken ct = default)
    {
        if (_tags is not null) return _tags;

        var resp = await client.SearchAsync(new SearchTagsRequest(new()
        {
            PageNumber = 1,
            PageSize = 99999
        }), ct);

        _tags = (resp?.Results.Items ?? Array.Empty<TagSearchItem>())
            .OrderByDescending(x => x.Favorite)
            .ThenBy(x => x.EnglishName ?? x.Name, StringComparer.Ordinal)
            .Select(x => new BitDropdownItem<int> { Text = x.EnglishName ?? x.Name, Value = x.TagId })
            .ToList();

        return _tags;
    }

    public async Task<List<BitDropdownItem<int>>> GetCreatorsAsync(CancellationToken ct = default)
    {
        if (_creators is not null) return _creators;

        var resp = await client.SearchAsync(new SearchCreatorsRequest(new()
        {
            PageNumber = 1,
            PageSize = 99999
        }), ct);

        _creators = (resp?.Results.Items ?? Array.Empty<CreatorSearchItem>())
            .OrderBy(x => x.Name, StringComparer.Ordinal)
            .Select(x => new BitDropdownItem<int> { Text = x.Name, Value = x.CreatorId })
            .ToList();

        return _creators;
    }
}

public class SelectOption<T>
{
    public string? Label { get; set; }
    public T? Value { get; set; }
}