from pydantic import BaseModel

from app.utils.api_response_mixin import ApiResponseMixin
from app.utils.helpers import get_logger
from typing import Optional, Dict, Any

class BaseController(ApiResponseMixin):
    """
    Base controller class that provides PHP trait-like functionality.
    All controllers can inherit from this to get direct access to response methods.
    """

    def __init__(self):
        self.logger = get_logger(self.__class__.__name__.lower())

    def validate_required_params(self, params: Dict[str, Any], required_fields: list) -> Optional[tuple]:
        """
        Validate required parameters and return error response if validation fails.

        Args:
            params: Dictionary of parameters to validate
            required_fields: List of required field names

        Returns:
            Error response tuple if validation fails, None if validation passes
        """
        if isinstance(params, BaseModel):
            params = params.model_dump()

        missing_fields = []
        for field in required_fields:
            if field not in params or params[field] is None or params[field] == '':
                missing_fields.append(field)

        if missing_fields:
            return self.bad_request({
                "message": "Missing required parameters",
                "missing_fields": missing_fields,
                "provided_params": list(params.keys())
            })

        return None

    def validate_integer_param(self, value: str, param_name: str) -> Optional[tuple]:
        """
        Validate integer parameter and return error response if invalid.

        Args:
            value: String value to validate
            param_name: Name of the parameter for error messaging

        Returns:
            Error response tuple if validation fails, None if validation passes
        """
        try:
            int(value)
            return None
        except (ValueError, TypeError):
            return self.bad_request({
                "message": f"Invalid {param_name} format. Must be an integer.",
                "provided_value": value,
                "param_name": param_name
            })

    def handle_database_error(self, error: Exception, operation: str) -> tuple:
        """
        Handle database errors consistently across controllers.

        Args:
            error: The exception that occurred
            operation: Description of the operation that failed

        Returns:
            Appropriate error response tuple
        """
        self.logger.error(f"Database error in {operation}: {str(error)}", exc_info=True)

        return self.server_error({
            "error": type(error).__name__,
            "message": f"Database operation failed: {operation}"
        })

    def log_and_return_success(self, data: Any, message: str, key: Optional[str] = None) -> tuple:
        """
        Log success message and return formatted response.

        Args:
            data: Response data
            message: Log message
            key: Optional response key

        Returns:
            Success response tuple
        """
        self.logger.info(message)
        return self.ok(data, key=key)
