﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using Random = UnityEngine.Random;

namespace MPStudio
{
    public static class ToolCollect
    {
        public const string LowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
        public const string Digits = "0123456789";


        public static float GoldRatio()
        {
            return (Mathf.Sqrt(5f) - 1f) / 2f;
        }
        
        
        public static T DeepCopy<T>(T originObj) where T : class
        {
            using (var ms = new MemoryStream())
            {
                var fm = new BinaryFormatter();
                fm.Serialize(ms, originObj);
                ms.Seek(0, SeekOrigin.Begin);
                return (T)fm.Deserialize(ms);
            }
        }
        
        
        
        public static T GetRuleItem<T>(List<T> list, ref int index)
        {
            return list[index++ % list.Count];
        }

        public static T ListRemoveHead<T>(List<T> lis)
        {
            int headIndex = 0;
            T res = lis[headIndex];
            lis.RemoveAt(headIndex);
            return res;
        }
        
        
        
        public static void CreateFileByStream(string path, string content)
        {
            if (File.Exists(path)) File.Delete(path);

            var file = new FileStream(path, FileMode.CreateNew);
            var fileW = new StreamWriter(file, Encoding.UTF8);
            fileW.Write(content);
            fileW.Flush();
            fileW.Close();
            file.Close();
        }

        public static void CreateDir(string path)
        {
            if (Directory.Exists(path))
            {
                return;
            }

            Directory.CreateDirectory(path);
        }
        
        
        
        public static Color GetColor(int r, int g, int b, int a = 255)
        {
            return new Color(r / 255f, g / 255f, b / 255f, a / 255f);
        }

        public static Color GetColor(string c)
        {
            Color res = default;

            c = "#" + c;

            ColorUtility.TryParseHtmlString(c, out res);
            
            return res;
        }
        
        
        
        public static T RandomItem<T>(ICollection<T> ic)
        {
            return ic.ElementAt(Random.Range(0, ic.Count));
        }

        public static ICollection<T> CollectionsRandomItem<T>(ICollection<ICollection<T>> icc)
        {
            return icc.ElementAt(Random.Range(0, icc.Count));
        }
        
        public static void Shuffle<T>(List<T> poker)
        {
            for (var i = poker.Count - 1; i >= 0; i--)
            {
                var randomIndex = Random.Range(0, i + 1);
                var temp = poker[randomIndex];
                poker[randomIndex] = poker[i];
                poker[i] = temp;
            }
        }
        
        public static bool CanBirthPrecision1000(float birthProbability)
        {
            var random = Random.Range(1, 1001);
            var birthValue = (int)(birthProbability * 1000);
            return random <= birthValue;
        }

        public static float GetRandomPlusAndMinus(float val)
        {
            return Random.Range(-val, val);
        }
        
        
        
        public static T GetField<T>(object ins, string name)
        {
            var temp = ins.GetType().GetField(name).GetValue(ins);

            return (T)temp;
        }
        
        
        
        public static string DollarFormat(double num, bool isIgnorePoint = true)
        {
            var str = string.Format("{0:N}", num);
            if (isIgnorePoint)
                return str.Replace(".00", "");
            return str;
        }

        public static int GetPureNumber(string str)
        {
            var newStr = Regex.Replace(str, "[^0-9]*", "");
            if (newStr == "") return 0;
            return int.Parse(newStr);
        }

        public static string StrRepeat(string demo, int repeatCount)
        {
            StringBuilder sb = new StringBuilder();
            int step = 0;
            while (step < repeatCount)
            {
                sb.Append(demo);
                step += 1;
            }

            return sb.ToString();
        }

        public static string GetRatio(float val, string format = "f1")
        {
            var tempVal = val;
            tempVal *= 100;
            return tempVal.ToString(format) + "%";
        }
        
        
        
        public static T GetEnumByInt<T>(int val) where T : Enum
        {
            return (T)Enum.Parse(typeof(T), val.ToString());
        }

        public static List<T> GetEnums<T>() where T : Enum
        {
            return Enum.GetValues(typeof(T)).Cast<T>().ToList();
        }
    }
}