"""
辅助函数
"""
from datetime import datetime, timedelta
from typing import Optional, Any
import json


def format_datetime(dt: Optional[datetime]) -> Optional[str]:
    """格式化日期时间"""
    if not dt:
        return None
    return dt.isoformat()


def parse_datetime(dt_str: str) -> Optional[datetime]:
    """解析日期时间字符串"""
    if not dt_str:
        return None
    try:
        return datetime.fromisoformat(dt_str)
    except:
        return None


def format_duration(seconds: int) -> str:
    """格式化时长"""
    if seconds < 60:
        return f"{seconds}s"
    elif seconds < 3600:
        return f"{seconds // 60}m"
    elif seconds < 86400:
        return f"{seconds // 3600}h"
    else:
        return f"{seconds // 86400}d"


def truncate_string(s: str, max_length: int = 100, suffix: str = "...") -> str:
    """截断字符串"""
    if len(s) <= max_length:
        return s
    return s[:max_length - len(suffix)] + suffix


def safe_json_loads(data: str, default: Any = None) -> Any:
    """安全的 JSON 解析"""
    try:
        return json.loads(data)
    except:
        return default


def safe_json_dumps(data: Any, default: str = "{}") -> str:
    """安全的 JSON 序列化"""
    try:
        return json.dumps(data, ensure_ascii=False)
    except:
        return default


def generate_session_title() -> str:
    """生成默认会话标题"""
    return f"Session {datetime.utcnow().strftime('%Y-%m-%d %H:%M')}"


def calculate_timeout(start_time: datetime, timeout_seconds: int) -> bool:
    """检查是否超时"""
    if not start_time:
        return True
    
    elapsed = (datetime.utcnow() - start_time).total_seconds()
    return elapsed > timeout_seconds


def merge_dicts(base: dict, override: dict) -> dict:
    """合并字典"""
    result = base.copy()
    result.update(override)
    return result


def filter_none_values(data: dict) -> dict:
    """过滤字典中的 None 值"""
    return {k: v for k, v in data.items() if v is not None}


class PaginationHelper:
    """分页辅助类"""
    
    @staticmethod
    def paginate(query, page: int = 1, per_page: int = 20):
        """分页查询"""
        if page < 1:
            page = 1
        if per_page < 1:
            per_page = 20
        if per_page > 100:
            per_page = 100
        
        total = query.count()
        items = query.offset((page - 1) * per_page).limit(per_page).all()
        
        pages = (total + per_page - 1) // per_page
        
        return {
            'items': items,
            'total': total,
            'page': page,
            'per_page': per_page,
            'pages': pages,
            'has_next': page < pages,
            'has_prev': page > 1,
        }
