"""Error classification and user-facing error messages for agent failures."""

import anthropic
import httpx
import pydantic_ai.exceptions

ERROR_MESSAGES: dict[str, dict[str, str]] = {
    "rate_limit": {
        "nl": "We zijn momenteel erg druk. Probeer het over een moment opnieuw.",
        "en": "We're experiencing high demand. Please try again in a moment.",
    },
    "context_overflow": {
        "nl": "Dit gesprek is te lang geworden. Start alstublieft een nieuw gesprek.",
        "en": "This conversation is getting long. Please start a new one.",
    },
    "tool_failure": {
        "nl": "Er ging iets mis bij het verwerken. Kunt u het opnieuw proberen?",
        "en": "I had trouble processing that. Could you try again?",
    },
    "service_unavailable": {
        "nl": "Sommige services zijn tijdelijk niet beschikbaar. Probeer het zo opnieuw.",
        "en": "Some services are temporarily unavailable. Please try again shortly.",
    },
    "unknown": {
        "nl": "Er is iets misgegaan. Probeer het opnieuw.",
        "en": "Something went wrong. Please try again.",
    },
}


def classify_error(exc: Exception) -> str:
    """Map an exception to a stable error code for structured error reporting."""
    if isinstance(exc, anthropic.RateLimitError):
        return "rate_limit"
    if isinstance(exc, anthropic.BadRequestError):
        msg = str(exc).lower()
        if "context" in msg or "token" in msg:
            return "context_overflow"
        return "unknown"
    if isinstance(exc, (httpx.ConnectError, httpx.TimeoutException)):
        return "service_unavailable"
    if isinstance(exc, pydantic_ai.exceptions.UsageLimitExceeded):
        return "context_overflow"
    if isinstance(exc, pydantic_ai.exceptions.UnexpectedModelBehavior):
        return "tool_failure"
    return "unknown"


def get_error_message(code: str, language: str) -> str:
    """Return a user-facing message for the given error code and language.

    Falls back to ``"nl"`` for unknown languages and ``"unknown"`` for unknown codes.
    """
    messages = ERROR_MESSAGES.get(code, ERROR_MESSAGES["unknown"])
    return messages.get(language, messages["nl"])


TOOL_MESSAGES: dict[str, dict[str, str]] = {
    "invalid_date_time": {
        "nl": "Ongeldige datum of tijd. Gebruik formaat YYYY-MM-DD voor datum en HH:MM voor tijd.",
        "en": "Invalid date or time. Use format YYYY-MM-DD for date and HH:MM for time.",
    },
    "party_too_large": {
        "nl": "Het aantal gasten is te groot. Maximaal {max} personen.",
        "en": "Party size is too large. Maximum {max} guests.",
    },
    "reservation_not_found": {
        "nl": "Reservering niet gevonden.",
        "en": "Reservation not found.",
    },
    "reservation_cancelled": {
        "nl": "Deze reservering is al geannuleerd en kan niet meer worden gewijzigd.",
        "en": "This reservation has been cancelled and cannot be modified.",
    },
    "slot_unavailable": {
        "nl": "Het gevraagde tijdslot is niet beschikbaar.",
        "en": "The requested time slot is not available.",
    },
    "too_soon": {
        "nl": "De reservering moet minstens {hours} uur van tevoren worden gemaakt.",
        "en": "The reservation must be made at least {hours} hours in advance.",
    },
    "too_far_in_advance": {
        "nl": "De reservering kan maximaal {days} dagen van tevoren worden gemaakt.",
        "en": "Reservations can be made at most {days} days in advance.",
    },
}


def get_tool_message(code: str, language: str, **kwargs) -> str:
    """Return a user-facing tool message for the given code and language."""
    messages = TOOL_MESSAGES.get(code)
    if messages is None:
        messages = ERROR_MESSAGES["unknown"]

    message = messages.get(language, messages["nl"])
    return message.format(**kwargs)
