using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Edge.Core.UniversalApi
{
    public abstract class ApiDataBase
    {
        /// <summary>
        /// used to match request and response
        /// </summary>
        //public Guid Id { get; set; }
    }

    public class ApiData : ApiDataBase
    {

        //public IEnumerable<string> Ids { get; set; }
        public List<ApiDataParameter> Parameters { get; set; }

        //public int IntValue { get; set; }

        //public InnerApiData InnerData { get; set; }
    }

    public class ApiDataParameter
    {
        public string Name { get; set; }
        public string Value { get; set; }
    }

    public static class ApiDataExtension
    {
        public static string Get(this ApiData self, string name)
        {
            return self.Parameters.FirstOrDefault(i => i.Name.ToLower() == name)?.Value;
        }

        public static TResult Get<TResult>(this ApiData self, string name, TResult defaultValue)
        {
            var value = self.Parameters.FirstOrDefault(i => i.Name.ToLower() == name)?.Value;
            try
            {
                return ParseType(value, defaultValue);
            }
            catch(Exception ex)
            {

            }
            return defaultValue;
        }

        public static bool IsEmpty(this ApiData self)
        {
            return self.Parameters == null || !self.Parameters.Any();
        }

        private static TResult ParseType<TResult>(string value, TResult defaultValue) => defaultValue.GetType().Name switch
        {
            "Boolean" => (TResult)Convert.ChangeType(bool.Parse(value), typeof(TResult)),
            "Byte" => (TResult)Convert.ChangeType(byte.Parse(value), typeof(TResult)),
            "SByte" => (TResult)Convert.ChangeType(sbyte.Parse(value), typeof(TResult)),
            "Decimal" => (TResult)Convert.ChangeType(decimal.Parse(value), typeof(TResult)),
            "Double" => (TResult)Convert.ChangeType(double.Parse(value), typeof(TResult)),
            "Single" => (TResult)Convert.ChangeType(float.Parse(value), typeof(TResult)),
            "Int32" => (TResult)Convert.ChangeType(int.Parse(value), typeof(TResult)),
            "UInt32" => (TResult)Convert.ChangeType(uint.Parse(value), typeof(TResult)),
            "Int64" => (TResult)Convert.ChangeType(long.Parse(value), typeof(TResult)),
            "UInt64" => (TResult)Convert.ChangeType(ulong.Parse(value), typeof(TResult)),
            "Int16" => (TResult)Convert.ChangeType(short.Parse(value), typeof(TResult)),
            "UInt16" => (TResult)Convert.ChangeType(ushort.Parse(value), typeof(TResult)),
            "DateTime" => (TResult)Convert.ChangeType(DateTime.Parse(value), typeof(TResult)),
            _ => defaultValue
        };
    }
}
