using System.Net;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Text.Json;
using System.Threading.Tasks;

namespace Dacryptero.Data.Generator
{
    public class WikiMarkow
    {
        public string Source { get; }

        public Markow<string> Markow { get; }

        public WikiMarkow(string source, Markow<string> markow)
        {
            Source = source;
            Markow = markow;
        }

        private static Regex splitter = new Regex("\\w+\\s*|\\W+", RegexOptions.Compiled);

        public static async Task<WikiMarkow> GetWikiMarkowAsync(string title)
        {
            Serilog.Log.Verbose("Build Wiki Markow for {title}", title);
            var url = $"https://en.wikipedia.org/w/api.php?action=query&format=json&titles={System.Web.HttpUtility.UrlEncode(title)}&prop=extracts&exintro&explaintext";
            var dlContent = await new WebClient().DownloadDataTaskAsync(url).ConfigureAwait(false);
            var json = JsonDocument.Parse(dlContent);
            var rawContent = json.RootElement.GetProperty("query")
                .GetProperty("pages")
                .EnumerateObject()
                .First()
                .Value
                .GetProperty("extract")
                .GetString();
            var match = splitter.Matches(rawContent ?? "");
            var markow = new Markow<string>(match.Select(x => x.Value));
            return new WikiMarkow(title, markow);
        }
    
        public string Generate(int length, System.Random? rng = null)
        {
            // Serilog.Log.Verbose("Generate Markow-Chain result from {title} with {length} chars", Source, length);
            var sb = new StringBuilder(length);
            foreach (var next in Markow.Generate(rng))
            {
                if (sb.Length + next.Length > length)
                    break;
                sb.Append(next);
            }
            return sb.ToString();
        }
    }
}