"""
Custom exceptions for the web module.

These exceptions are used to provide structured error handling
that can be caught by Flask error handlers and converted to
appropriate JSON responses.
"""

from typing import Any, Optional


class WebAPIException(Exception):
    """Base exception for all web API related errors."""

    def __init__(
        self,
        message: str,
        status_code: int = 500,
        error_code: Optional[str] = None,
        details: Optional[dict[str, Any]] = None,
    ):
        """
        Initialize the web API exception.

        Args:
            message: Human-readable error message
            status_code: HTTP status code for the error
            error_code: Machine-readable error code for API consumers
            details: Additional error details/context
        """
        super().__init__(message)
        self.message = message
        self.status_code = status_code
        self.error_code = error_code or self.__class__.__name__
        self.details = details or {}

    def to_dict(self) -> dict[str, Any]:
        """Convert exception to dictionary for JSON response."""
        result = {
            "status": "error",
            "message": self.message,
            "error_code": self.error_code,
        }
        if self.details:
            result["details"] = self.details  # type: ignore[assignment]
        return result


class AuthenticationRequiredError(WebAPIException):
    """Raised when authentication is required but not available."""

    def __init__(
        self,
        message: str = "Authentication required: Please refresh the page and log in again.",
        username: Optional[str] = None,
    ):
        details = {}
        if username:
            details["username"] = username
        super().__init__(
            message,
            status_code=401,
            error_code="AUTHENTICATION_REQUIRED",
            details=details,
        )
