using System;
using System.Collections.Generic;
using System.Linq;
using MPStudio;
using Random = UnityEngine.Random;

namespace MPStudioManagers
{
    public class Weight<T>
    {
        private readonly List<T> _items;
        private readonly Dictionary<int, int[]> _rangeDic;
        private readonly int _sum;
        private readonly List<int> _weights;

        public Weight(List<int> weights, List<T> items)
        {
            if (weights.Count != items.Count) throw new Exception("The count inequality.");

            _rangeDic = new Dictionary<int, int[]>();

            var first = 0;
            var second = 0;

            for (var i = 0; i < weights.Count; i++)
            {
                var arr = new int[2];

                first = second;
                second = weights[i] + first;

                arr[0] = first;
                arr[1] = second;

                _rangeDic[i] = arr;
            }

            _sum = _rangeDic[weights.Count - 1][1];

            _weights = weights;
            _items = items;
        }

        public string ShowPercentage()
        {
            var res = string.Empty;
            for (var i = 0; i < _rangeDic.Count; i++)
            {
                var kv = _rangeDic.ElementAt(i);
                var arr = kv.Value;
                var per = (float)(arr[1] - arr[0]) / _sum;
                res = $"{res}{_items[i]}probability:{ToolCollect.GetRatio(per, "f5")}weight:{_weights[i]}\r\n";
            }

            return res;
        }

        public static int GetWeightByDoubleString(string floatString, int w = 1000000)
        {
            double f = default;

            try
            {
                f = double.Parse(floatString);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }

            return (int)(f * w);
        }


        public T GetRandomItem()
        {
            var temp = Random.Range(1, _sum + 1);
            return GetItemByNumber(temp);
        }

        public T GetItemByNumber(int number)
        {
            var key = GetAccordWithKey(number);
            return _items[key];
        }

        private int GetAccordWithKey(int randomNumber)
        {
            foreach (var kv in _rangeDic)
            {
                var arr = kv.Value;

                if (randomNumber > arr[0] && randomNumber <= arr[1]) return kv.Key;
            }

            return -1;
        }
    }
}