"""
时间工具模块
统一处理系统时间，使用北京时间 (UTC+8)
"""

from datetime import datetime, timezone, timedelta
from flask import current_app

# 北京时间时区
BEIJING_TIMEZONE = timezone(timedelta(hours=8))

class TimeUtils:
    """时间处理工具类"""
    
    @staticmethod
    def get_beijing_timezone():
        """获取北京时区对象"""
        return BEIJING_TIMEZONE
    
    @staticmethod
    def now():
        """获取当前北京时间"""
        return datetime.now(BEIJING_TIMEZONE)
    
    @staticmethod
    def utcnow():
        """
        获取当前UTC时间
        兼容原有代码，但建议使用 now() 方法
        """
        return datetime.utcnow()
    
    @staticmethod
    def beijing_now():
        """获取当前北京时间（明确命名）"""
        return datetime.now(BEIJING_TIMEZONE)
    
    @staticmethod
    def utc_to_beijing(utc_dt):
        """
        将UTC时间转换为北京时间
        
        Args:
            utc_dt: UTC时间的datetime对象
            
        Returns:
            北京时间的datetime对象
        """
        if utc_dt is None:
            return None
            
        # 如果没有时区信息，假设为UTC
        if utc_dt.tzinfo is None:
            utc_dt = utc_dt.replace(tzinfo=timezone.utc)
        
        # 转换为北京时间
        return utc_dt.astimezone(BEIJING_TIMEZONE)
    
    @staticmethod
    def beijing_to_utc(beijing_dt):
        """
        将北京时间转换为UTC时间
        
        Args:
            beijing_dt: 北京时间的datetime对象
            
        Returns:
            UTC时间的datetime对象
        """
        if beijing_dt is None:
            return None
            
        # 如果没有时区信息，假设为北京时间
        if beijing_dt.tzinfo is None:
            beijing_dt = beijing_dt.replace(tzinfo=BEIJING_TIMEZONE)
        
        # 转换为UTC时间
        return beijing_dt.astimezone(timezone.utc)
    
    @staticmethod
    def format_datetime(dt, format_str='%Y-%m-%d %H:%M:%S'):
        """
        格式化日期时间
        
        Args:
            dt: datetime对象
            format_str: 格式字符串
            
        Returns:
            格式化后的时间字符串
        """
        if dt is None:
            return '未知时间'
        
        # 如果是UTC时间，转换为北京时间
        if dt.tzinfo is None or dt.tzinfo == timezone.utc:
            dt = TimeUtils.utc_to_beijing(dt)
        
        return dt.strftime(format_str)
    
    @staticmethod
    def format_relative_time(dt):
        """
        格式化相对时间（如：2小时前、3天前）
        
        Args:
            dt: datetime对象
            
        Returns:
            相对时间字符串
        """
        if dt is None:
            return '未知时间'
        
        # 确保都是北京时间
        now = TimeUtils.now()
        if dt.tzinfo is None:
            dt = TimeUtils.utc_to_beijing(dt)
        
        diff = now - dt
        
        if diff.days > 0:
            if diff.days == 1:
                return '1天前'
            elif diff.days < 7:
                return f'{diff.days}天前'
            elif diff.days < 30:
                weeks = diff.days // 7
                return f'{weeks}周前'
            elif diff.days < 365:
                months = diff.days // 30
                return f'{months}个月前'
            else:
                years = diff.days // 365
                return f'{years}年前'
        else:
            seconds = diff.seconds
            if seconds < 60:
                return '刚刚'
            elif seconds < 3600:
                minutes = seconds // 60
                return f'{minutes}分钟前'
            else:
                hours = seconds // 3600
                return f'{hours}小时前'
    
    @staticmethod
    def parse_datetime(date_string, format_str='%Y-%m-%d %H:%M:%S'):
        """
        解析日期时间字符串
        
        Args:
            date_string: 日期时间字符串
            format_str: 格式字符串
            
        Returns:
            datetime对象（北京时间）
        """
        try:
            dt = datetime.strptime(date_string, format_str)
            # 设置为北京时区
            return dt.replace(tzinfo=BEIJING_TIMEZONE)
        except (ValueError, TypeError):
            return None
    
    @staticmethod
    def get_start_of_day(dt=None):
        """
        获取某天的开始时间（00:00:00）
        
        Args:
            dt: 指定日期，如果为None则使用当前日期
            
        Returns:
            当天开始时间的datetime对象
        """
        if dt is None:
            dt = TimeUtils.now()
        elif dt.tzinfo is None:
            dt = TimeUtils.utc_to_beijing(dt)
        
        return dt.replace(hour=0, minute=0, second=0, microsecond=0)
    
    @staticmethod
    def get_end_of_day(dt=None):
        """
        获取某天的结束时间（23:59:59）
        
        Args:
            dt: 指定日期，如果为None则使用当前日期
            
        Returns:
            当天结束时间的datetime对象
        """
        if dt is None:
            dt = TimeUtils.now()
        elif dt.tzinfo is None:
            dt = TimeUtils.utc_to_beijing(dt)
        
        return dt.replace(hour=23, minute=59, second=59, microsecond=999999)
    
    @staticmethod
    def add_days(dt, days):
        """
        在指定日期基础上增加天数
        
        Args:
            dt: 基础日期
            days: 要增加的天数
            
        Returns:
            新的datetime对象
        """
        if dt is None:
            dt = TimeUtils.now()
        elif dt.tzinfo is None:
            dt = TimeUtils.utc_to_beijing(dt)
        
        return dt + timedelta(days=days)
    
    @staticmethod
    def add_hours(dt, hours):
        """
        在指定日期基础上增加小时数
        
        Args:
            dt: 基础日期
            hours: 要增加的小时数
            
        Returns:
            新的datetime对象
        """
        if dt is None:
            dt = TimeUtils.now()
        elif dt.tzinfo is None:
            dt = TimeUtils.utc_to_beijing(dt)
        
        return dt + timedelta(hours=hours)


# 提供快捷函数，方便直接使用
def now():
    """获取当前北京时间"""
    return TimeUtils.now()

def format_datetime(dt, format_str='%Y-%m-%d %H:%M:%S'):
    """格式化日期时间"""
    return TimeUtils.format_datetime(dt, format_str)

def format_relative_time(dt):
    """格式化相对时间"""
    return TimeUtils.format_relative_time(dt)

def utc_to_beijing(utc_dt):
    """UTC时间转北京时间"""
    return TimeUtils.utc_to_beijing(utc_dt) 