"""Shared utilities for handling Pydantic validation errors."""

import json
from pydantic import ValidationError
from pydantic_core import ErrorDetails
from ninja.errors import HttpError


def format_validation_error(error: ErrorDetails) -> str:
    """Format a Pydantic validation error into a user-friendly message.

    Args:
        error: A Pydantic error details dictionary containing 'msg', 'type', 'ctx', etc.

    Returns:
        A user-friendly error message string.
    """
    msg = error.get("msg") or "Invalid value"
    error_type = error.get("type") or ""

    # Handle common validation types with friendly messages
    if error_type == "enum":
        ctx = error.get("ctx", {})
        expected = ctx.get("expected", "") if ctx else ""
        return f"Please select a valid option{': ' + expected if expected else ''}"
    elif error_type == "literal_error":
        # Literal errors (like Literal["active", "inactive"])
        return msg.replace("Input should be ", "Please enter ")
    elif error_type == "missing":
        return "This field is required"
    elif error_type == "string_type":
        return "Please enter a valid string"
    elif error_type == "int_type":
        return "Please enter a valid int"
    elif error_type == "int_parsing":
        return "Please enter a valid int"
    elif error_type == "float_type":
        return "Please enter a valid float"
    elif error_type == "float_parsing":
        return "Please enter a valid float"
    elif error_type == "value_error":
        # Strip "Value error, " prefix from custom validator messages
        return msg.replace("Value error, ", "")
    else:
        # Default: use the message from Pydantic but clean it up
        return msg.replace("Input should be ", "Please enter ").replace("Value error, ", "")


def handle_validation_error(e: ValidationError) -> None:
    """Convert a Pydantic ValidationError into a structured HttpError.

    This function transforms Pydantic validation errors into a JSON structure
    that the frontend expects for displaying field-level errors.

    Args:
        e: The Pydantic ValidationError to handle.

    Raises:
        HttpError: Always raises a 400 error with structured JSON containing
                   type, field_errors, and message fields.
    """
    # Transform Pydantic validation errors into user-friendly format
    field_errors: dict[str, list[str]] = {}
    for error in e.errors():
        # Get the field name from location tuple
        loc = error.get("loc", ())
        field = str(loc[-1]) if loc else "root"

        # Format the error message
        friendly_msg = format_validation_error(error)

        if field not in field_errors:
            field_errors[field] = []
        field_errors[field].append(friendly_msg)

    # Return structured error for frontend parsing
    error_response = {
        "type": "validation_error",
        "field_errors": field_errors,
        "message": "Please correct the errors below",
    }
    raise HttpError(400, json.dumps(error_response))
