using System;
using System.Collections.Generic;

namespace Dacryptero.Data.Generator
{
    public abstract class DataGeneratorBase<T>
        where T : notnull
    {
        public ReadOnlyMemory<WikiMarkow> WikiGen { get; }

        public NameGenerator NameGenerator { get; }

        public CityGenerator CityGenerator { get; }

        public Random Random { get; }

        public DataGeneratorBase(ReadOnlyMemory<WikiMarkow> wikiGen, NameGenerator nameGen,
            CityGenerator cityGen, Random? random = null)
        {
            WikiGen = wikiGen;
            NameGenerator = nameGen;
            CityGenerator = cityGen;
            Random = random ?? new Random();
        }

        public abstract T Generate();

        public virtual IEnumerable<T> GenerateMulti(int length = -1)
        {
            while (length != 0)
            {
                if (length > 0)
                    length--;
                yield return Generate();
            }
        }

        protected virtual string GetName()
        {
            return NameGenerator.GenerateName(Random);
        }

        protected virtual string GetCity()
        {
            return CityGenerator.GenerateName(Random);
        }

        protected virtual string GetLongText(int length)
        {
            if (WikiGen.Length == 0)
                return "";
            var gen = WikiGen.Span[Random.Next(WikiGen.Length)];
            return gen.Generate(length, Random);
        }

        protected virtual DateTime GetDateTime(DateTime min, DateTime max)
        {
            var diff = (max-min).TotalMilliseconds;
            return min.AddMilliseconds(diff * Random.NextDouble());
        }

        protected virtual bool GetBool(double edge = 0.5)
        {
            return Random.NextDouble() < edge;
        }
    }
}