using MangaReader.Core.HttpService;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;

namespace MangaReader.Core.Sources.NatoManga.Api;

public partial class NatoMangaClient(IHttpService httpService) : INatoMangaClient
{
    [GeneratedRegex(@"[^a-z0-9]+")]
    private static partial Regex NonAlphaNumericCharactersRegex();

    [GeneratedRegex("_{2,}")]
    private static partial Regex ExtendedUnderscoresRegex();

    private static readonly JsonSerializerOptions _jsonSerializerOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    public async Task<NatoMangaSearchResult[]> SearchAsync(string searchWord, CancellationToken cancellationToken)
    {
        string url = GetSearchUrl(searchWord);

        string response = await httpService.GetStringAsync(url, cancellationToken);

        return JsonSerializer.Deserialize<NatoMangaSearchResult[]>(response, _jsonSerializerOptions) ?? [];
    }

    protected string GetSearchUrl(string searchWord)
    {
        string formattedSeachWord = GetFormattedSearchWord(searchWord);

        return $"https://www.natomanga.com/home/search/json?searchword={formattedSeachWord}";
    }

    private static string GetFormattedSearchWord(string searchWord)
    {
        if (string.IsNullOrWhiteSpace(searchWord))
            return string.Empty;

        // Convert to lowercase and normalize to decompose accents
        string normalized = searchWord.ToLowerInvariant()
            .Normalize(NormalizationForm.FormD);

        // Remove diacritics
        var sb = new StringBuilder();
        foreach (var c in normalized)
        {
            var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
            if (unicodeCategory != UnicodeCategory.NonSpacingMark)
                sb.Append(c);
        }

        // Replace non-alphanumeric characters with underscores
        string cleaned = NonAlphaNumericCharactersRegex().Replace(sb.ToString(), "_");

        // Trim and collapse underscores
        cleaned = ExtendedUnderscoresRegex().Replace(cleaned, "_").Trim('_');

        return cleaned;
    }
}