using System;
using MrWu;
using MrWu.Debug;

namespace Server.Core
{
    //UTC 时间 也就是 格林威治时间 比北京时间慢8小时
    public class TimeInfo : SingleInstance<TimeInfo>
    {
        private int timeZone;

        public int TimeZone
        {
            get
            {
                return this.timeZone;
            }
            set
            {
                this.timeZone = value;
                
            }
        }

        private DateTime dt1970;
        private DateTime dt;
        
        // ping消息会设置该值，原子操作
        public long ServerMinusClientTime { private get; set; }

        public long FrameTime { get; private set; }

        /// <summary>
        /// 下一天的时间值
        /// </summary>
        private long NextDayFrameTime;

        public event Action DayChange; 
        
        public TimeInfo()
        {
            this.dt1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            this.dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            this.FrameTime = this.ClientNow();
            NextDayFrameTime = (DateTime.Now.Date.AddDays(1).AddHours(-8).Ticks - this.dt1970.Ticks) / 10000;
            Debug.Info($"下一天的时间：{NextDayFrameTime} {FrameTime} {DateTime.Now} {DateTime.UtcNow}");
        }

        public void Update()
        {
            // if (IsDisposed())
            // {
            //     return;
            // }
            // 赋值long型是原子操作，线程安全
            this.FrameTime = this.ClientNow();

            if (this.FrameTime > NextDayFrameTime)
            {
                NextDayFrameTime = (DateTime.Now.Date.AddDays(1).AddHours(-8).Ticks - this.dt1970.Ticks) / 10000;
                Debug.Info($"下一天的时间：{NextDayFrameTime}");
                DayChange?.Invoke();
            }
        }

        /// <summary> 
        /// 根据时间戳获取时间 
        /// </summary>  
        public DateTime ToDateTime(long timeStamp)
        {
            return dt.AddTicks(timeStamp * 10000);
        }
        
        // 线程安全
        public long ClientNow()
        {
            return (DateTime.UtcNow.Ticks - this.dt1970.Ticks) / 10000;
        }

        /// <summary>
        /// 当天零点的时间
        /// </summary>
        /// <returns></returns>
        public long NowDayTime()
        {
            return (DateTime.UtcNow.Date.Ticks - this.dt1970.Ticks) / 10000;
        }

        public long ServerNow()
        {
            return ClientNow() + this.ServerMinusClientTime;
        }
        
        public long ClientFrameTime()
        {
            return this.FrameTime;
        }
        
        public long ServerFrameTime()
        {
            return this.FrameTime + this.ServerMinusClientTime;
        }
        
        /// <summary>
        /// UTC时间转换
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public long Transition(DateTime d)
        {
            return (d.Ticks - dt.Ticks) / 10000;
        }

        /// <summary>
        /// 本地时间转换
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public long TransitionLocationDateTime(DateTime dateTime)
        {
            return Transition(dateTime.AddHours(-8));
        }
    }
}