"""Error handling utilities."""

import json
from json import JSONDecodeError
from typing import Any

from slices_clientlib_core.base.exceptions import (
    ApiException,
    BadRequestException,
    NotFoundException,
    ServiceException,
    UnauthorizedException,
    ValidationError,
)


def get_error_detail(error_body: Any | None):
    """Get detail from error response."""
    if not isinstance(error_body, str):
        return None
    try:
        error_body_contents = json.loads(error_body)
    except JSONDecodeError:
        return error_body

    error_details = []

    if "detail" in error_body_contents:
        if isinstance(error_body_contents["detail"], list):
            for detail in error_body_contents["detail"]:
                if "msg" in detail:
                    error_details.append(detail["msg"])
                else:
                    error_details.append(str(detail))
        else:
            error_details.append(error_body_contents["detail"])

    if error_details:
        res = []
        for detail in error_details:
            if isinstance(detail, str):
                res.append(detail)
            elif isinstance(detail, dict | list):
                res.append(json.dumps(detail, indent=4))
            else:
                res.append(str(detail))
        return "\n".join(res)

    return "No details available"


def get_api_error_detail(err: ApiException):
    """Show error details for API exceptions."""

    if isinstance(err, ValidationError):
        return "\n".join([f"{error_detail.loc}: {error_detail.msg}" for error_detail in err.details])

    if isinstance(err, BadRequestException):
        return f"Bad Request: {err.detail}"

    if isinstance(err, ServiceException):
        message = "The server encountered an internal error"
        if err._httpx_error:
            message += (
                f" while processing {err._httpx_error.request.method} request "
                f"on {err._httpx_error.request.url}: {err._httpx_status_error.response.text}"
            )
        else:
            message += "."
        message += "\n\nPlease report this issue to support if the issue persists."

        return message

    if isinstance(err, UnauthorizedException):
        return f"Unauthorized: {err._httpx_error}"

    if isinstance(err, NotFoundException):
        assert err._httpx_error
        return f"Resource not found: {err._httpx_error.request.url}"

    return f"TODO: Implement get_api_error_detail for other error types {err} {err!r}"
