"""Утилиты для работы с SQLAlchemy моделями"""

from datetime import date, datetime
from typing import Any, Optional, TypeVar, Type, cast

T = TypeVar('T')

def safe_get_column_value(obj: Any, column_name: str, default_value: Optional[T] = None) -> Optional[T]:
    """
    Безопасное получение значения колонки из SQLAlchemy модели.
    
    Args:
        obj: Объект SQLAlchemy модели
        column_name: Имя колонки
        default_value: Значение по умолчанию, если колонка отсутствует или значение None
    
    Returns:
        Значение колонки или значение по умолчанию
    """
    if not hasattr(obj, column_name):
        return default_value
    
    value = getattr(obj, column_name)
    if value is None:
        return default_value
    
    # Если значение - дата, преобразуем его в Python date
    if hasattr(value, 'isoformat'):  # Дата или дата-время
        return cast(T, value)
    
    # Для других типов просто возвращаем значение
    return cast(T, value)

def safe_int(value: Any, default: int = 0) -> int:
    """Безопасно преобразует значение в целое число"""
    if value is None:
        return default
    
    try:
        return int(value)
    except (ValueError, TypeError):
        return default

def safe_str(value: Any, default: str = "") -> str:
    """Безопасно преобразует значение в строку"""
    if value is None:
        return default
    
    try:
        return str(value)
    except (ValueError, TypeError):
        return default

def safe_bool(value: Any, default: bool = False) -> bool:
    """Безопасно преобразует значение в булево значение"""
    if value is None:
        return default
    
    if isinstance(value, bool):
        return value
    
    try:
        return bool(value)
    except (ValueError, TypeError):
        return default

def safe_date(value: Any, default: Optional[date] = None) -> date:
    """Безопасно преобразует значение в дату"""
    if default is None:
        default = date.today()
        
    if value is None:
        return default
    
    if isinstance(value, date) and not isinstance(value, datetime):
        return value
    
    if isinstance(value, datetime):
        return value.date()
    
    try:
        return date.fromisoformat(str(value))
    except (ValueError, TypeError):
        return default

def safe_datetime(value: Any, default: Optional[datetime] = None) -> datetime:
    """Безопасно преобразует значение в дату-время"""
    if default is None:
        default = datetime.now()
        
    if value is None:
        return default
    
    if isinstance(value, datetime):
        return value
    
    if isinstance(value, date):
        return datetime.combine(value, datetime.min.time())
    
    try:
        return datetime.fromisoformat(str(value))
    except (ValueError, TypeError):
        return default