using System;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;

namespace BMA.EHR.Recurit.Exam.Service.Extensions
{
    public enum DateTimeFormat
    {
        Dmy,
        Mdy,
        Ymd
    }

    public static partial class StringExtension
    {
        #region " Methods "

        #region " Utilities "

        public static string Format(this string input, int digit)
        {
            var fmt = $"D{digit}";
            return input.ToInteger().ToString(fmt);

        }

        public static string RemoveComma(this string value)
        {
            string ret;
            if (value.Contains(","))
            {
                ret = value.Replace(",", "");
                return ret;
            }
            else
            {
                if (value != "")
                {
                    return value;
                }
                else
                    return "0.00";
            }
        }

        public static string RemoveSpace(this string value)
        {
            string ret;
            if (value.Contains(","))
            {
                ret = value.Replace(" ", "");
                return ret;
            }
            else
            {
                if (value != "")
                {
                    return value;
                }
                else
                    return "";
            }
        }

        public static string Left(this string input, int length)
        {
            if (length > 0 && input.Length >= length)
            {
                return input.Substring(0, length);
            }
            else
            {
                return input;
            }
        }

        public static string Right(this string input, int length)
        {
            if (length > 0 && input.Length >= length)
            {
                return input.Substring(input.Length - length, length);
            }
            else
            {
                return input;
            }
        }

        #endregion

        #region " Validation "

        public static bool IsDateTime(this string input)
        {
            try
            {
                var d = Convert.ToDateTime(input);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public static bool IsUrl(this string input)
        {
            if (input.Trim() != "")
            {
                if ((input.Left(7).ToLower() != "http://") || (input.Left(8).ToLower() != "https://"))
                {
                    input = "http://" + input;
                }
                Regex reg = new Regex("http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&amp;=]*)?");
                return reg.Match(input).Success;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Determines whether this instance is email.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns></returns>
        public static bool IsEmail(this string input)
        {
            if (input.Trim() != "")
            {
                Regex reg = new Regex("\\w+([-+.\']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
                return reg.Match(input).Success;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Determines whether this instance is numeric.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns></returns>
        public static bool IsNumeric(this string input)
        {
            if (input.Length > 0)
            {
                double tempDouble = (double)(NumberStyles.Number);
                return double.TryParse(input, out tempDouble);
            }
            else
            {
                return false;
            }
        }

        public static string IsNull(this string input, string value)
        {
            if (input == null)
                return value;
            else
                return input;
        }

        #endregion

        #region " Conversion "

        public static DateTime ToDateTime(this string input, DateTimeFormat format, string seperator = "/")
        {
            try
            {
                var dd = input.Split(seperator);
                switch (format)
                {
                    case DateTimeFormat.Dmy:
                        return new DateTime(dd[2].ToInteger().ToCeYear(), dd[1].ToInteger(), dd[0].ToInteger());
                    case DateTimeFormat.Mdy:
                        return new DateTime(dd[2].ToInteger().ToCeYear(), dd[0].ToInteger(), dd[1].ToInteger());
                    case DateTimeFormat.Ymd:
                        return new DateTime(dd[0].ToInteger().ToCeYear(), dd[1].ToInteger(), dd[2].ToInteger());
                    default:
                        return DateTime.MinValue;
                }
            }
            catch
            {
                return DateTime.MinValue;
            }

        }

        public static string ValueOrBlank(this string input)
        {
            if (input == null) return "";

            if (input == "0")
                return "";
            else
                return input;
        }

        public static MemoryStream ToMemoryStream(this string base64String)
        {
            if (base64String == null || base64String == String.Empty) return null;

            var bytes = Convert.FromBase64String(base64String);
            var stream = new MemoryStream(bytes);

            return stream;
        }

        public static double ToDouble(this string input)
        {
            if (input == null) return 0.0;

            if (input == "") return 0.0;

            double ret = 0.0;
            input = input.RemoveComma();
            if (input.IsNumeric())
            {
                ret = double.Parse(input);
            }
            return ret;
        }

        public static float ToFloat(this string input)
        {
            if (input == null) return 0F;

            if (input == "") return 0F;

            float ret = 0F;
            input = input.RemoveComma();
            if (input.IsNumeric())
            {
                ret = float.Parse(input);
            }
            return ret;
        }

        public static int ToInteger(this string input)
        {
            if (input == null) return 0;

            if (input == "") return 0;

            int ret = 0;
            input = input.RemoveComma();
            int.TryParse(input, out ret);
            return ret;
        }

        public static string ToBlank(this string value)
        {
            if (value == "0")
                return "";
            else
                return value;
        }

        public static DateTime ToCeDateTime(this string date)
        {
            try
            {
                DateTime dddd;
                if (!DateTime.TryParse(date, out dddd))
                    return DateTime.MinValue;


                if (date == "01/01/0001")
                    return Convert.ToDateTime(date);

                string[] dd = date.Split('/');

                int yy = 0;
                if (dd[2].Length == 2)
                    yy = dd[2].Left(2).ToInteger() + 2500;
                else
                    yy = dd[2].Left(4).ToInteger();
                if (yy >= 2400) yy -= 543;
                DateTime birthdate = new DateTime(yy, dd[1].ToInteger(), dd[0].ToInteger());
                return birthdate;
            }
            catch
            {
                return DateTime.MinValue;
            }

        }

        #endregion

        #endregion
    }

}