using System;

namespace Siger.Middlelayer.Common.Helpers
{
    public class UnixTimeHelper
    {
        public const string DateTimeFormat = "yyyy-MM-dd HH:mm:ss";

        public const string DateFormat = "yyyy-MM-dd";

        public const string MinSecondFormat = "HH:mm";

        public const string MouthFirstDayFormat = "yyyy-MM-01";

        public const string DateTimeFormatYmd = "yyyyMMdd";

        public const string TimeFormat = "HH:mm:ss";
        public const string DateTimeFormatYYmmdd = "yyMMdd";

        /// <summary>
        /// unix time to date-->yyyyMMdd
        /// </summary>
        /// <param name="unixTime">suah as unixtime</param>
        /// <returns>yyyyMMdd</returns>
        public static string ConvertIntYmd(int unixTime)
        {
            if (unixTime == 0)
            {
                return string.Empty;
            }
            var dateTime = ConvertStringDateTime(unixTime.ToString());

            return dateTime.ToString(DateTimeFormatYmd);
        }

        /// <summary>
        /// unix time to date-->HH:mm
        /// </summary>
        /// <param name="unixTime">suah as unixtime</param>
        /// <returns>HH:ss</returns>
        public static string ConvertIntHm(int unixTime)
        {
            if (unixTime == 0)
            {
                return string.Empty;
            }
            var dateTime = ConvertStringDateTime(unixTime.ToString());

            return dateTime.ToString(MinSecondFormat);
        }

        /// <summary>
        /// 将string类型转换为DateTime类型
        /// </summary>
        /// <param name="unixTime"></param>
        /// <returns></returns>
        public static DateTime ConvertStringDateTime(string unixTime)
        {
            var dtStart = new DateTime(1970, 1, 1);
            try
            {
                var dt = TimeZone.CurrentTimeZone.ToLocalTime(dtStart);
                return dt.Add(new TimeSpan(long.Parse(unixTime + "0000000")));
            }
            catch (Exception)
            {
                return dtStart;
            }
        }

        /// <summary>
        /// unix time -- int
        /// </summary>
        /// <param name="unixTime">suah as unixtime</param>
        /// <returns>yyyy-MM-dd HH:mm:ss</returns>
        public static string ConvertIntDateTime(int unixTime)
        {
            if (unixTime == 0)
            {
                return string.Empty;
            }
            var dateTime = ConvertStringDateTime(unixTime.ToString());

            return dateTime.ToString(DateTimeFormat);
        }
        /// <summary>
        ///int 类型转换成时分秒
        /// </summary>
        /// <param name="unixTime"></param>
        /// <returns></returns>
        public static string ConvertIntTime(int unixTime)
        {
            if (unixTime == 0)
            {
                return string.Empty;
            }
            var dateTime = ConvertStringDateTime(unixTime.ToString());

            return dateTime.ToString(TimeFormat);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="unixTime">unixTime</param>
        /// <returns>yyyyMMddHHmmssfff</returns>
        public static string ConvertIntDateTimeToStr(int unixTime)
        {
            if (unixTime == 0)
            {
                return string.Empty;
            }
            var dateTime = ConvertStringDateTime(unixTime.ToString());

            return dateTime.ToString("yyyyMMddHHmmssfff");
        }

        /// <summary>
        /// unix time -- int
        /// </summary>
        /// <param name="unixTime">int time</param>
        /// <returns>yyyy-MM-dd</returns>
        public static string ConvertIntDate(int unixTime)
        {
            if (unixTime == 0)
            {
                return string.Empty;
            }
            var dateTime = ConvertStringDateTime(unixTime.ToString());

            return dateTime.ToString(DateFormat);
        }
        
        /// <summary>
        /// 将DateTime类型转换为long类型
        /// </summary>
        /// <param name="dt">DateTime</param>
        /// <returns>UnixTime --long</returns>
        public static long ConvertDataTimeLong(DateTime dt)
        {
            try
            {
                var dtStart = new DateTime(1970, 1, 1);
                var dtTime = TimeZone.CurrentTimeZone.ToLocalTime(dtStart);
                var toNow = dt.Subtract(dtTime);
                var timeStamp = toNow.Ticks;
                return long.Parse(timeStamp.ToString().Substring(0, timeStamp.ToString().Length - 7));
            }
            catch (Exception)
            {
                return 0;
            }
        }
        public static long ConvertDataTimeLongMilliSecond(DateTime dt)
        {
            try
            {
                var dtStart = new DateTime(1970, 1, 1);
                var dtTime = TimeZone.CurrentTimeZone.ToLocalTime(dtStart);
                var toNow = dt.Subtract(dtTime);
                var timeStamp = toNow.Ticks;
                return long.Parse(timeStamp.ToString().Substring(0, timeStamp.ToString().Length - 4));
            }
            catch (Exception)
            {
                return 0;
            }
        }
        /// <summary>
        /// 将unixTime类型转换为long类型
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        public static long ConvertDataTimeLong(string datetime)
        {
            try
            {
                if (!DateTime.TryParse(datetime, out var dt))
                {
                    return 0;
                }
                var dtStart = new DateTime(1970, 1, 1);
                var dtTime = TimeZone.CurrentTimeZone.ToLocalTime(dtStart);
                var toNow = dt.Subtract(dtTime);
                var timeStamp = toNow.Ticks;
                return long.Parse(timeStamp.ToString().Substring(0, timeStamp.ToString().Length - 7));
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// get current unix string time
        /// </summary>
        /// <returns>"154121211"</returns>
        public static string GetCurrentTime()
        {
            var dateTime = ConvertDataTimeLong(DateTime.Now);

            return dateTime.ToString();
        }

        /// <summary>
        /// get current unix int time
        /// </summary>
        /// <returns></returns>
        public static int GetNow()
        {
            var dateTime = ConvertDataTimeLong(DateTime.Now);

            return int.Parse(dateTime.ToString());
        }

        public static int GetTodayUnix()
        {
            var dateTime = ConvertDataTimeLong(DateTime.Parse(DateTime.Now.ToShortDateString()));

            return int.Parse(dateTime.ToString());
        }

        public static int GetMouthUnix()
        {
            var dateTime = ConvertDataTimeLong(DateTime.Parse(DateTime.Now.ToString(MouthFirstDayFormat)));

            return int.Parse(dateTime.ToString());
        }

        /// <summary>
        /// get int unix time by date
        /// </summary>
        /// <param name="date">yyyy-MM-dd HH:mm:ss</param>
        /// <returns>unixtime</returns>
        public static int GetUnixByShortDate(string date)
        {
            if (string.IsNullOrEmpty(date))
            {
                return GetNow();
            }
            bool success = DateTime.TryParse(date, out DateTime value);
            if (success)
            {
                return (int) ConvertDataTimeLong(value);
            }

            return GetNow();
        }

        /// <summary>
        /// get string time by unix time
        /// </summary>
        /// <param name="unixTime">such as 28800</param>
        /// <returns>mm:ss</returns>
        public static string GetTimeByUnix(int unixTime)
        {
            try
            {
                var time = Convert.ToDouble(unixTime);
                if (time > 86400)
                {
                    time = time % 86400;
                }

                var hour = Math.Floor(time / 3600);
                var min = Math.Floor((time % 3600) / 60);

                return hour.ToString().PadLeft(2, '0') + ":" +
                       min.ToString().PadLeft(2, '0');
            }
            catch
            {
                return "00:00";
            }
        }

        /// <summary>
        /// get unixtime by time 
        /// </summary>
        /// <param name="time">such as 08:00</param>
        /// <returns>such as 28800</returns>
        public static int GetUnixTime(string time)
        {
            if (string.IsNullOrEmpty(time))
            {
                return 0;
            }

            var times = time.Split(':');
            if (times.Length != 2)
            {
                return 0;
            }
            try
            {
                return int.Parse(times[0]) * 3600 + int.Parse(times[1]) * 60;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// get unixtime by time 
        /// </summary>
        /// <param name="time">such as 08:01:02</param>
        /// <returns>such as 28800</returns>
        public static int GetUnixAllTime(string time)
        {
            if (string.IsNullOrEmpty(time))
            {
                return 0;
            }

            var times = time.Split(':');
            if (times.Length != 3)
            {
                return 0;
            }
            try
            {
                return int.Parse(times[0]) * 3600 + int.Parse(times[1]) * 60 + int.Parse(times[2]);
            }
            catch
            {
                return 0;
            }
        }

        public static string GetDateTime(string date)
        {
            if (string.IsNullOrEmpty(date))
            {
                return string.Empty;
            }

            var result = DateTime.TryParse(date, out var dateTime);
            if (result)
            {
                return dateTime.ToString(DateFormat);
            }

            return string.Empty;
        }

        public static string GetTimeBySecond(int totalSecond)
        {
            var timeStr = "";
            if (totalSecond == 0)
            {
                timeStr = "0";
            }

            var day = totalSecond / 86400;
            if (day > 0)
            {
                timeStr += day + "天";
            }

            var hour = (totalSecond % 86400) / 3600;
            if (hour > 0)
            {
                timeStr += hour + "小时";
            }

            var min = (((totalSecond % 86400) % 3600) / 60);
            if (min > 0)
            {
                timeStr += min + "分钟";
            }

            var sec = ((totalSecond % 86400) % 3600) % 60;
            if (sec > 0)
            {
                timeStr += sec + "秒";
            }

            return timeStr;
        }

        /// <summary>
        /// get unixtime by time 
        /// </summary>
        /// <param name="time">such as 08:01:02</param>
        /// <returns>such as 28800</returns>
        public static int GetUnixTimeByTime(string time)
        {
            if (string.IsNullOrEmpty(time))
            {
                return 0;
            }

            var times = time.Split(':');
            if (times.Length != 3)
            {
                return 0;
            }
            try
            {
                return int.Parse(times[0]) * 3600 + int.Parse(times[1]) * 60 + int.Parse(times[2]);
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// get int unix time by date
        /// </summary>
        /// <param name="date">such as 2018-9-1 08:00:00</param>
        /// <param name="defaultValue"></param>
        /// <returns>unixtime</returns>
        public static int GetUnixByDate(string date, int defaultValue = 0)
        {
            if (string.IsNullOrEmpty(date))
            {
                return defaultValue;
            }
            bool success = DateTime.TryParse(date, out DateTime value);
            if (success)
            {
                return (int)ConvertDataTimeLong(value);
            }

            return defaultValue;
        }
    }
}
