using AuthorBuddy.Web.Models;
using System.Text.Json;
using System.Web;

namespace AuthorBuddy.Web.Services;

public class WikipediaService : IWikipediaService
{
    private readonly HttpClient _http;
    private readonly string[] _languages = { "de", "en" };

    public WikipediaService()
    {
        _http = new HttpClient { Timeout = TimeSpan.FromSeconds(15) };
        _http.DefaultRequestHeaders.UserAgent.ParseAdd("AuthorBuddy/1.0 (writing-assistant)");
    }

    public async Task<List<WikipediaResult>> SearchAsync(string query, int maxResults = 3)
    {
        return await SearchAsync(new WikipediaSearchRequest
        {
            Query = query,
            MaxResults = maxResults
        });
    }

    public async Task<List<WikipediaResult>> SearchAsync(WikipediaSearchRequest request)
    {
        var results = new List<WikipediaResult>();

        foreach (var lang in _languages)
        {
            if (lang == "de" && !request.SearchGerman) continue;
            if (lang == "en" && !request.SearchEnglish) continue;

            try
            {
                var langResults = await SearchLanguageAsync(lang, request.Query, request.MaxResults);
                results.AddRange(langResults);
            }
            catch
            {
                // Sprache überspringen bei Fehler
            }
        }

        return results;
    }

    public async Task<string?> GetExtractAsync(string title, string language = "de")
    {
        try
        {
            var url = $"https://{language}.wikipedia.org/w/api.php" +
                      "?action=query" +
                      "&prop=extracts" +
                      "&exintro&explaintext" +
                      $"&titles={HttpUtility.UrlEncode(title)}" +
                      "&format=json&utf8=1";

            var response = await _http.GetStringAsync(url);
            using var doc = JsonDocument.Parse(response);
            var pages = doc.RootElement.GetProperty("query").GetProperty("pages");

            foreach (var page in pages.EnumerateObject())
            {
                if (page.Value.TryGetProperty("extract", out var extract))
                    return extract.GetString();
            }
        }
        catch { }

        return null;
    }

    public async Task<string?> GetFullArticleAsync(string title, string language = "de")
    {
        try
        {
            var url = $"https://{language}.wikipedia.org/w/api.php" +
                      "?action=query" +
                      "&prop=extracts" +
                      "&explaintext" +
                      $"&titles={HttpUtility.UrlEncode(title)}" +
                      "&format=json&utf8=1";

            var response = await _http.GetStringAsync(url);
            using var doc = JsonDocument.Parse(response);
            var pages = doc.RootElement.GetProperty("query").GetProperty("pages");

            foreach (var page in pages.EnumerateObject())
            {
                if (page.Value.TryGetProperty("extract", out var extract))
                    return extract.GetString();
            }
        }
        catch { }

        return null;
    }

    private async Task<List<WikipediaResult>> SearchLanguageAsync(string lang, string query, int maxResults)
    {
        var results = new List<WikipediaResult>();

        var url = $"https://{lang}.wikipedia.org/w/api.php" +
                  "?action=query" +
                  "&list=search" +
                  $"&srsearch={HttpUtility.UrlEncode(query)}" +
                  $"&srlimit={maxResults}" +
                  "&format=json&utf8=1";

        var response = await _http.GetStringAsync(url);
        using var doc = JsonDocument.Parse(response);
        var search = doc.RootElement.GetProperty("query").GetProperty("search");

        foreach (var item in search.EnumerateArray())
        {
            var title = item.GetProperty("title").GetString() ?? "";
            results.Add(new WikipediaResult
            {
                Title = title,
                Snippet = StripHtml(item.GetProperty("snippet").GetString() ?? ""),
                Url = $"https://{lang}.wikipedia.org/wiki/{HttpUtility.UrlEncode(title)}",
                Language = lang
            });
        }

        return results;
    }

    private static string StripHtml(string html)
    {
        return System.Text.RegularExpressions.Regex.Replace(html, "<[^>]*>", "");
    }
}
