using System;
using NBC;
using UnityEngine;

namespace NBF
{
    public class GameTimer
    {
        static GameTimer()
        {
            SetServerTime(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
        }

        // 游戏纪元开始时间（Unix 时间戳，毫秒）
        private const long GameEpoch = 1672531200000; // 2023-01-01 00:00:00 UTC

        // 时间加速比例 (1现实秒 = 15游戏秒)
        private const int TimeAcceleration = 200;

        //一天, 一小时, 一分钟固定时长(毫秒)
        public const long DAY_MILLS = 86400000;
        public const long HOUR_MILLS = 3600000;
        public const long MINUTE_MILLS = 60000;
        public const long SECOND_MILLS = 1000;

        private static long _serverTime;

        /// <summary>
        /// 更新服务器时间时的unity运行时间
        /// </summary>
        private static float _serverTimeLocalTime;

        /// <summary>
        /// 当前服务器时间（ms）
        /// </summary>
        public static long serverTime
        {
            get
            {
                var offsetLocalTime = (long)((Time.realtimeSinceStartup - _serverTimeLocalTime) * 1000);
                return _serverTime + offsetLocalTime;
            }
        }

        /// <summary>
        /// 当前游戏时间
        /// </summary>
        public static long gameTime => RealToGameTimestamp(serverTime);

        public static string gameTimeString
        {
            get
            {
                var realTime = DateTimeOffset.FromUnixTimeMilliseconds(gameTime);
                return $"{realTime.Hour:D2}:{realTime.Minute:D2}";
            }
        }

        public static DateTime ServerDateTime => ConvertUtcToDateTime(serverTime);


        public static void SetServerTime(long time)
        {
            Log.Info($"设置服务器时间={time}");
            _serverTime = time;
            _serverTimeLocalTime = Time.realtimeSinceStartup;
        }

        /// <summary>
        /// 获取本地时区
        /// </summary>
        /// <returns></returns>
        public static int GetLocalTimeZoneOffset()
        {
            TimeZoneInfo localTimeZone = TimeZoneInfo.Local;
            int offset = (int)localTimeZone.BaseUtcOffset.TotalHours;

            return offset;
        }


        /// <summary>
        /// 现实时间戳转游戏时间戳
        /// </summary>
        /// <param name="realTimestamp">现实时间戳(毫秒)</param>
        /// <returns>游戏时间戳(毫秒)</returns>
        public static long RealToGameTimestamp(long realTimestamp)
        {
            long realElapsed = realTimestamp - GameEpoch;
            long gameElapsed = realElapsed * TimeAcceleration;
            return GameEpoch + gameElapsed;
        }

        /// <summary>
        /// 游戏时间戳转现实时间戳
        /// </summary>
        /// <param name="gameTimestamp">游戏时间戳(毫秒)</param>
        /// <returns>现实时间戳(毫秒)</returns>
        public static long GameToRealTimestamp(long gameTimestamp)
        {
            long gameElapsed = gameTimestamp - GameEpoch;
            long realElapsed = gameElapsed / TimeAcceleration;
            return GameEpoch + realElapsed;
        }

        /// <summary>
        /// 13位时间戳转化为时间
        /// </summary>
        /// <param name="utcTime">时间戳</param>
        /// <returns></returns>
        public static DateTime ConvertUtcToDateTime(long utcTime)
        {
            var startTime = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Utc);
            var cTime = startTime.AddTicks(utcTime * 10000);
            return cTime;
        }


        /// <summary>
        /// 时间转化为10位时间戳
        /// </summary>
        /// <param name="time">获取的时间</param>
        /// <returns></returns>
        public static long ConvertDateTimeToUtc_10(DateTime time)
        {
            TimeSpan timeSpan = time.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(timeSpan.TotalSeconds);
        }

        /// <summary>
        /// 转为毫秒时间戳 13位
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static long ConvertDateTimeToUtc(DateTime time)
        {
            TimeSpan timeSpan = time - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(timeSpan.TotalMilliseconds);
        }

        /// <summary>
        /// 将一个秒数转换成"00:00:00"格式
        /// </summary>
        /// <param name="second"></param>
        /// <returns></returns>
        public static string GetTimeStringHMD(long second)
        {
            int h = Mathf.FloorToInt(second / 3600f);
            int m = Mathf.FloorToInt(second / 60f - h * 60f);
            int s = Mathf.FloorToInt(second - m * 60f - h * 3600f);
            // 直接返回格式化好的小时、分钟、秒
            return string.Format("{0:D2}:{1:D2}:{2:D2}", h, m, s);
        }

        /// <summary>
        /// 将一个秒数转换成"00:00"格式
        /// </summary>
        /// <param name="second"></param>
        /// <returns></returns>
        public static string GetTimeStringMD(int second)
        {
            if (second <= 0)
            {
                return "00:00";
            }

            float m = Mathf.FloorToInt(second / 60f);
            float s = Mathf.FloorToInt(second % 60);

            // 使用ZString进行高效的字符串拼接
            return string.Format("{0:D2}:{1:D2}", (int)m, (int)s);
        }


        /// <summary>
        /// 获取游戏时间在当天的进度（0到1之间的值）
        /// 0表示当天0点，1表示当天24点
        /// </summary>
        public static float GetGameDayProgress()
        {
            // 获取当天的总毫秒数
            double totalMillisecondsInDay = 24 * 60 * 60 * 1000; // 86400000ms

            // 计算当天已过去的毫秒数
            double elapsedMilliseconds = ConvertUtcToDateTime(gameTime).TimeOfDay.TotalMilliseconds;

            // 计算进度（0-1）
            return (float)(elapsedMilliseconds / totalMillisecondsInDay);
            // return 0.2f;
        }
    }
}