using System;
using System.Linq;

namespace Fort23.Core
{
    public static class TimeHelper
    {
        public static readonly long epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;

        public static DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));

        public const long OneDay = 86400000;
        public const long Hour = 3600000;
        public const long Minute = 60000;
        private static long _clientFrame;

        public static long clientFrame
        {
            set => _clientFrame = value;
        }

        /// <summary>
        /// 用于唯一Id生成，不重复
        /// </summary>
        /// <returns></returns>
        public static long ClientNowMicroseconds()
        {
            return DateTime.UtcNow.Ticks - epoch;
        }


        /// <summary>
        /// 客户端非暂停状态经历的帧数对应的毫秒
        /// </summary>
        /// <returns></returns>
        public static long ClientFrame()
        {
            return _clientFrame;
        }

        /// <summary>
        /// 客户端时间(毫秒)
        /// </summary>
        /// <returns></returns>
        public static long ClientNow()
        {
            return (DateTime.UtcNow.Ticks - epoch) / 10000;
        }

        /// <summary>
        /// 客户端时间(秒)
        /// </summary>
        /// <returns></returns>
        public static long ClientNowSeconds()
        {
            return ClientNow() / 1000;
        }

        public static DateTime DateTimeNow()
        {
            return DateTime.Now;
        }

        /// <summary>
        /// 服务器时间(毫秒)
        /// </summary>
        /// <returns></returns>
        public static long ServerNow()
        {
            return ClientNow();
        }

        /// <summary>
        /// 服务器时间(秒)
        /// </summary>
        /// <returns></returns>
        public static long ServerNowSeconds()
        {
            return ClientNowSeconds();
        }

        /// <summary>
        /// 时间戳转字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToHour(this int value)
        {
            int fen = value / 60;
            int hour = fen / 60;
            return (hour + 1) + "";
        }

        /// <summary>
        /// 客户端时间（年月日）
        /// </summary>
        /// <param name="timeStamp">当前时间</param>
        /// <returns></returns>
        public static int ClientNowInt(long timeStamp)
        {
            TimeSpan toNow = new TimeSpan(timeStamp * 10000);
            DateTime dateTime = dtStart.Add(toNow);
            int year = dateTime.Year;
            int month = dateTime.Month;
            int day = dateTime.Day;
            int date;
            string smouth = "";
            if (month >= 10)
            {
                smouth = month.ToString();
            }
            else
            {
                smouth = $"0{month}";
            }

            string sday = "";
            if (day >= 10)
            {
                sday = day.ToString();
            }
            else
            {
                sday = $"0{day}";
            }

            if (int.TryParse($"{year}{smouth}{sday}", out date))
            {
                return date;
            }

            return 20201010;
        }


        /// <summary>
        /// 客户端时间（月日时分秒）
        /// </summary>
        /// <param name="timeStamp">当前时间(毫秒)</param>
        /// <returns></returns>
        public static string ToString1(long timeStamp)
        {
            TimeSpan toNow = new TimeSpan(timeStamp * 10000);
            DateTime dateTime = dtStart.Add(toNow);
            string month = String.Empty;
            string day = String.Empty;
            string hour = String.Empty;
            string minute = String.Empty;
            string second = String.Empty;
            if (dateTime.Month >= 10)
            {
                month = dateTime.Month.ToString();
            }
            else
            {
                month = $"0{dateTime.Month}";
            }

            if (dateTime.Day >= 10)
            {
                day = dateTime.Day.ToString();
            }
            else
            {
                day = $"0{dateTime.Day}";
            }
            
            if (dateTime.Hour >= 10)
            {
                hour = dateTime.Hour.ToString();
            }
            else
            {
                hour = $"0{dateTime.Hour}";
            }
            if (dateTime.Minute >= 10)
            {
                minute = dateTime.Minute.ToString();
            }
            else
            {
                minute = $"0{dateTime.Minute}";
            }
            if (dateTime.Second >= 10)
            {
                second = dateTime.Second.ToString();
            }
            else
            {
                second = $"0{dateTime.Second}";
            }

            string result = $"{month}月{day}日{hour}：{minute}：{second}";

            return result;
        }

        /// <summary>
        /// 判断法定工作日和节假日
        /// </summary>
        /// <param name="dt">时间</param>
        /// <returns>0上班，1不需要上班的周末（也包括节假日），2法定节假日</returns>
        public static int IsHolidayOrWeekend(DateTime dt)
        {
            //特殊的周末（周末却上班）
            string[] specalWeek2022 = { };
            string[] specalWeek2023 = { "0128", "0129", "0214", "0429", "0430", "0625", "1007", "1008" };

            //法定假日
            string[] holiday2022 = { "1231" };
            string[] holiday2023 =
            {
                "0101", "0102", "0121", "0122", "0123", "0124", "0125", "0126", "0127", "0405", "0501", "0502", "0503", "0504", "0505", "0622", "0623",
                "0929", "1002", "1003", "1004", "1005", "1006"
            };

            bool isHoildayOrWeek = false;
            //取年
            string weekYear = dt.Year.ToString();
            //取月日
            string[] weekDate = { dt.ToString("MMdd") };
            //判断周末和周五
            if ((int)dt.DayOfWeek == 0 || (int)dt.DayOfWeek == 6 || (int)dt.DayOfWeek == 5)
            {
                //周末是否需要上班
                switch (weekYear)
                {
                    case "2022":
                        isHoildayOrWeek = specalWeek2022.Intersect(weekDate).Count() == 0;
                        break;
                    case "2023":
                        isHoildayOrWeek = specalWeek2023.Intersect(weekDate).Count() == 0;
                        break;
                }
            }

            if (isHoildayOrWeek)
            {
                return 1;
            }

            //判断法定节假日
            switch (weekYear)
            {
                case "2022":
                    isHoildayOrWeek = holiday2022.Intersect(weekDate).Count() > 0;
                    break;
                case "2023":
                    isHoildayOrWeek = holiday2023.Intersect(weekDate).Count() > 0;
                    break;
            }

            if (isHoildayOrWeek)
            {
                return 2;
            }

            return 0;
        }
    }
}