using JiShe.CollectBus.Common.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JiShe.CollectBus.Common.Helpers
{
    /// <summary>
    /// 时间戳帮助类
    /// </summary>
    public static class TimestampHelper
    {
        private static readonly long UnixEpochTicks = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).Ticks;

        /// <summary>
        /// 获取当前 DateTimeOffset 距离 Unix 纪元（1970-01-01）的微秒数
        /// </summary>
        public static long ToUnixTimeMicroseconds(this DateTimeOffset dateTimeOffset)
        {
            // Ticks 单位是 100 纳秒，转换为微秒需除以 10
            long elapsedTicks = dateTimeOffset.Ticks - UnixEpochTicks;
            return elapsedTicks / 10; // 1 微秒 = 1000 纳秒 = 10 Ticks
        }

        /// <summary>
        /// 获取当前 DateTimeOffset 距离 Unix 纪元（1970-01-01）的纳秒数
        /// </summary>
        public static long ToUnixTimeNanoseconds(this DateTimeOffset dateTimeOffset)
        {
            long nanoseconds = (dateTimeOffset.Ticks - UnixEpochTicks) * 100;
            return nanoseconds;
        }

        /// <summary>
        /// 将 long 类型时间戳转换为 DateTime（UTC）
        /// </summary>
        /// <param name="timestamp">时间戳数值</param>
        /// <param name="unit">时间戳单位</param>
        public static DateTime ConvertToDateTime(long timestamp, TimestampUnit unit = TimestampUnit.Milliseconds)
        {
            long ticks = unit switch
            {
                TimestampUnit.Seconds => checked(timestamp * TimeSpan.TicksPerSecond),
                TimestampUnit.Milliseconds => checked(timestamp * TimeSpan.TicksPerMillisecond),
                TimestampUnit.Microseconds => checked(timestamp * 10), // 1微秒 = 10 Ticks（100纳秒）
                TimestampUnit.Nanoseconds => checked(timestamp / 100),// 1 Tick = 100纳秒
                _ => throw new ArgumentException("无效的时间单位", nameof(unit))
            };

            try
            {
                DateTime result = new DateTime(UnixEpochTicks + ticks, DateTimeKind.Utc);
                // 校验结果是否在 DateTime 合法范围内（0001-01-01 至 9999-12-31）
                if (result < DateTime.MinValue || result > DateTime.MaxValue)
                {
                    throw new ArgumentOutOfRangeException(nameof(timestamp), "时间戳超出 DateTime 范围");
                }
                return result;
            }
            catch (ArgumentOutOfRangeException ex)
            {
                throw new ArgumentOutOfRangeException("时间戳无效", ex);
            }
        }
    }
}
