using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
using System.Text.Json;

namespace Dacryptero.Data.Generator
{
    public class CityGenerator
    {
        public ReadOnlyMemory<string> Names { get; }

        public CityGenerator(ReadOnlyMemory<string> names)
        {
            Names = names;
        }

        public IEnumerable<string> GenerateNames(Random? rng = null, int limit = -1)
        {
            rng ??= new Random();
            while (limit != 0)
            {
                if (limit > 0)
                    limit--;
                yield return GenerateName(rng);
            }
        }

        public string GenerateName(Random? rng = null)
        {
            rng ??= new Random();
            return Names.Span[rng.Next(Names.Length)];
        }

        public static async Task<CityGenerator> GetNameGeneratorAsync()
        {
            var hc = new System.Net.Http.HttpClient();
            // var wc = new WebClient();
            var names = new List<string>();
            Serilog.Log.Verbose("Download big city names");
           names.AddRange(
                await GetNamesAsync(hc, "https://raw.githubusercontent.com/lutangar/cities.json/master/cities.json")
                .ConfigureAwait(false)
            );
            return new CityGenerator(names.ToArray());
        }

        private static async Task<IEnumerable<string>> GetNamesAsync(HttpClient httpClient, string url)
        {
            var content = await httpClient.GetByteArrayAsync(url).ConfigureAwait(false);
            // var content = await webClient.DownloadDataTaskAsync(url).ConfigureAwait(false);
            var json = JsonDocument.Parse(content);
            return json.RootElement.EnumerateArray()
                .Select(x => x.GetProperty("name").GetString() ?? "")
                .Where(x => x != "");
        }
    }
}