from typing import Optional
from sqlalchemy.orm import Session
from fastapi import HTTPException
import logging

logger = logging.getLogger(__name__)

class BaseService:
    """Base service class that provides common functionality for all services"""
    
    def __init__(self, db: Session):
        self.db = db
    
    def handle_db_error(self, error: Exception, operation: str) -> None:
        """
        Handle database errors in a consistent way
        
        Args:
            error: The exception that was raised
            operation: Description of the operation that failed
        """
        logger.error(f"Database error during {operation}: {str(error)}")
        raise HTTPException(status_code=500, detail=f"Database error occurred during {operation}")
    
    def get_by_field(self, model_class: any, field: str, value: str) -> Optional[any]:
        """
        Generic method to get an entity by a field
        """
        try:
            return self.db.query(model_class).filter(getattr(model_class, field) == value).first()
        except Exception as e:
            self.handle_db_error(e, f"getting {model_class.__name__} by {field}")

    def get_by_id(self, model_class: any, id: int) -> Optional[any]:
        """
        Generic method to get an entity by ID
        
        Args:
            model_class: The SQLAlchemy model class
            id: The ID to look up
            
        Returns:
            The found entity or None
        """
        try:
            return self.get_by_field(model_class, "id", id)
        except Exception as e:
            self.handle_db_error(e, f"getting {model_class.__name__} by ID")

    def create(self, model_class: any, data: dict) -> any:
        """
        Generic method to create an entity
        
        Args:
            model_class: The SQLAlchemy model class
            data: Dict containing the entity data
            
        Returns:
            The created entity
        """
        try:
            entity = model_class(**data)
            self.db.add(entity)
            self.db.commit()
            self.db.refresh(entity)
            return entity
        except Exception as e:
            self.db.rollback()
            self.handle_db_error(e, f"creating {model_class.__name__}")
