using System;

namespace BingoBrain.Core
{
    public sealed class DateTimeBoardk : BaseInterfaceManager<DateTimeBoardk>
    {
        public static DateTime StartTimestampDT = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));


        private long HeartBeatInterval = 7;

        private int FixTimeOffset = 0;

        public int ServerRTTOneWayTimeOffset { get; private set; }


        public long ServerTickTimestamp { get; private set; }

        #region CurrTime

        public long GetCurrTimestamp()
        {
            long timestamp = (long)(DateTime.Now - StartTimestampDT).TotalSeconds;
            return timestamp;
        }

        public string GetCurrTimestampInfo()
        {
            long timestamp = (long)(DateTime.Now - StartTimestampDT).TotalSeconds;
            return timestamp.ToString();
        }

        #endregion

        #region ServerCurrTime

        public void SetHeartBeatTime(int heartBeatInterval)
        {
            HeartBeatInterval = heartBeatInterval;
        }

        public long GetHeartBeatTime()
        {
            return HeartBeatInterval;
        }

        public void SetServerCurrTimestamp(long serverCurrTimestamp)
        {
            ServerTickTimestamp = serverCurrTimestamp;
            ServerRTTOneWayTimeOffset = (int)(GetCurrTimestamp() - serverCurrTimestamp);
        }


        public float GetServerTimeOffset()
        {
            return ServerRTTOneWayTimeOffset;
        }


        public long GetServerTickTimestamp()
        {
            return ServerTickTimestamp;
        }


        public DateTime GetServerTickDateTime()
        {
            return GetDateTime(ServerTickTimestamp);
        }


        public long GetServerCurrTimestamp(bool isFix = false)
        {
            var servertimes =  GetCurrTimestamp() - ServerRTTOneWayTimeOffset;
            if(isFix) 
            {
                servertimes += FixTimeOffset;
            }
            return servertimes;
        }

        public void SetTimeOffset(int offset) 
        {
            FixTimeOffset += offset;
        }



        public DateTime GetServerCurrDateTime()
        {
            long timestamp = GetServerCurrTimestamp();
            return GetDateTime(timestamp);
        }

        #endregion

        #region Interval

        public long GetCurrTimeInterval(long timestamp)
        {
            return timestamp - GetCurrTimestamp();
        }

        public long GetServerCurrTimeInterval(long timestamp)
        {
            return timestamp - GetServerCurrTimestamp();
        }


        public int GetInteralDay(ulong time)
        {
            ulong interal = time - (ulong)GetServerCurrTimestamp();
            int day = UnityEngine.Mathf.CeilToInt(interal * 1f / (60 * 60 * 24));
            return day;
        }

        public void GetIntervalHMS(long interval, out int hour, out int minute, out int second)
        {
            second = (int)(interval % 60);
            int tempMinute = (int)(interval / 60);
            hour = tempMinute / 60;
            minute = tempMinute - (hour * 60);
        }

        public void GetIntervalMS(long interval, out int minute, out int second)
        {
            second = (int)(interval % 60);
            minute = (int)(interval / 60);
        }

        public string GetIntervalHMSTextEn(long interval)
        {
            int hour, minute, second;
            GetIntervalHMS(interval, out hour, out minute, out second);
            return string.Format("{0:00}:{1:00}:{2:00}", hour, minute, second);
        }

        public string GetIntervalHMSTextCn(long interval)
        {
            int hour, minute, second;
            GetIntervalHMS(interval, out hour, out minute, out second);
            return string.Format("{0:00}：{1:00}：{2:00}", hour, minute, second);
        }

        public string GetIntervalMSTextEn(long interval)
        {
            int minute, second;
            GetIntervalMS(interval, out minute, out second);
            return string.Format("{0:00}:{1:00}", minute, second);
        }

        public string GetIntervalMSTextCn(long interval)
        {
            int minute, second;
            GetIntervalMS(interval, out minute, out second);
            return string.Format("{0:00}：{1:00}", minute, second);
        }

        public string GetIntervalDateSimpleString(long interval)
        {
            DateTime dateTime = GetDateTime(interval);
            return DateTimeToSimpleString(dateTime);
        }

        #endregion

        #region DateTime

        public DateTime GetCurrDateTime()
        {
            return DateTime.Now;
        }

        public double GetTimestamp(DateTime date)
        {
            return (date - StartTimestampDT).TotalSeconds;
        }

        public DateTime GetDateTime(long timestamp)
        {
            DateTime dt = StartTimestampDT.AddSeconds(timestamp);
            return dt;
        }

        public int GetCurrTimeZone()
        {
            return int.Parse(GetCurrDateTime().ToString("%z"));
        }

        public int GetNowYear()
        {
            DateTime time = GetCurrDateTime();
            return time.Year;
        }

        public int GetNowMonth()
        {
            DateTime time = GetCurrDateTime();
            return time.Month;
        }

        public int GetNowDay()
        {
            DateTime time = GetCurrDateTime();
            return time.Day;
        }

        public int GetNowHour()
        {
            DateTime time = GetCurrDateTime();
            return time.Hour;
        }

        public int GetNowMinute()
        {
            DateTime time = GetCurrDateTime();
            return time.Minute;
        }

        public int GetNowSecond()
        {
            DateTime time = GetCurrDateTime();
            return time.Second;
        }

        public int GetNowMillisecond()
        {
            DateTime time = GetCurrDateTime();
            return time.Millisecond;
        }

        #endregion

        #region DateTimeFormat

        public string DateTimeToMMdd(DateTime date)
        {
            return date.ToString("MM/dd");
        }

        public string DateTimeToYYYYMMDD(DateTime time)
        {
            return time.ToString("yyyyMMdd");
        }

        public string DateTimeToSimpleString(DateTime time)
        {
            return time.ToString("yyyy/MM/dd");
        }

        public string DateTimeToString(DateTime time)
        {
            return time.ToString("yyyy/MM/dd HH:mm:ss");
        }

        public string DateTimeToDetailString(DateTime time)
        {
            return time.ToString("yyyy/MM/dd HH:mm:ss:ffff dddd");
        }

        public DateTime GetDateTimeBy_yyyyMMddStr(string str)
        {
            return new DateTime(GetYearByDateStr(str), GetMonthByDateStr(str), GetDayByDateStr(str));
        }

        public string TimestampToString(long endTimestamp)
        {
            return DateTimeToString(GetDateTime(endTimestamp));
        }

        #endregion

        #region Conversion

        public float Millisecond2Second(uint millisecond)
        {
            if (millisecond == 0)
            {
                return 0f;
            }

            return millisecond / 1000f;
        }

        public double GetTimestampInMilliSecond(DateTime date)
        {
            return GetTimestamp(date) * 1000;
        }

        public string GetMSMTimeUID()
        {
            int minute = GetNowMinute();
            int second = GetNowSecond();
            int millisecond = GetNowMillisecond();
            return string.Concat(minute, second, millisecond);
        }

        #endregion

        #region Calculate

        public int GetMonthDuration(string oldDate, string newDate)
        {
            int year = GetYearByDateStr(newDate) - GetYearByDateStr(oldDate);
            int month = GetMonthByDateStr(newDate) - GetMonthByDateStr(oldDate);
            return year * 12 + month;
        }

        public int GetMonthDuration(DateTime oldDate, DateTime newDate)
        {
            int year = newDate.Year - oldDate.Year;
            int month = newDate.Month - oldDate.Month;
            return year * 12 + month;
        }


        public int GetDayByDateStr(string dateStr)
        {
            int date = int.Parse(dateStr.Substring(6, 2));
            return date;
        }


        public int GetMonthByDateStr(string dateStr)
        {
            int date = int.Parse(dateStr.Substring(4, 2));
            return date;
        }


        public int GetYearByDateStr(string dateStr)
        {
            int date = int.Parse(dateStr.Substring(0, 4));
            return date;
        }


        public DateTime FirstDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day);
        }


        public DateTime LastDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
        }
        public long GetCurrTimesTampByMillisecond()
        {
            long time = (long)(DateTime.Now - StartTimestampDT).TotalMilliseconds;
            return time;
        }
        public string DateTimeToFFFString(DateTime time)
        {
            return time.ToString("HH:mm:ss ff");
        }
        public long GetServerCurrTimestampByMillisecond()
        {
            return GetCurrTimesTampByMillisecond() - ServerRTTOneWayTimeOffset * 1000;
        }
        #endregion
    }
}