"""Tibber API response handler"""

import logging
from http import HTTPStatus
from typing import Any

from aiohttp import ClientResponse

from .const import (
    API_ERR_CODE_UNAUTH,
    API_ERR_CODE_UNKNOWN,
    HTTP_CODES_FATAL,
    HTTP_CODES_RETRIABLE,
)
from .exceptions import (
    FatalHttpExceptionError,
    InvalidLoginError,
    NotForDemoUserError,
    RetryableHttpExceptionError,
)

_LOGGER = logging.getLogger(__name__)


def extract_error_details(errors: list[Any], default_message: str) -> tuple[str, str]:
    """Tries to extract the error message and code from the provided 'errors' dictionary"""
    if not errors:
        return API_ERR_CODE_UNKNOWN, default_message
    return errors[0].get("extensions").get("code"), errors[0].get("message")


async def extract_response_data(response: ClientResponse) -> dict[Any, Any]:
    """Extracts the response as JSON or throws a HttpException"""
    _LOGGER.debug("Response status: %s", response.status)

    if response.content_type != "application/json":
        raise RetryableHttpExceptionError(
            response.status,
            f"Unexpected content type: {response.content_type}",
            API_ERR_CODE_UNKNOWN,
        )

    result: dict[str, Any] = await response.json()

    if response.status == HTTPStatus.OK:
        errors: list[dict[str, Any]] = result.get("errors", [])
        if not errors:
            return result

        error_code, error_message = extract_error_details(errors, str(response.content))

        if error_code == "UNAUTHENTICATED":
            raise InvalidLoginError(response.status, error_message, error_code)

        if (error_code == "INTERNAL_SERVER_ERROR") & ("demo user" in error_message):
            raise NotForDemoUserError(response.status, error_message, error_code)

        raise RetryableHttpExceptionError(response.status, message=error_message, extension_code=error_code)

    if response.status in HTTP_CODES_RETRIABLE:
        error_code, error_message = extract_error_details(result.get("errors", []), str(response.content))

        raise RetryableHttpExceptionError(response.status, message=error_message, extension_code=error_code)

    if response.status in HTTP_CODES_FATAL:
        error_code, error_message = extract_error_details(result.get("errors", []), "request failed")
        if error_code == API_ERR_CODE_UNAUTH:
            raise InvalidLoginError(response.status, error_message, error_code)

        raise FatalHttpExceptionError(response.status, error_message, error_code)

    error_code, error_message = extract_error_details(result.get("errors", []), "N/A")
    # if reached here the HTTP response code is not currently handled
    _LOGGER.error("Unexpected HTTP status: %s", response.status)
    raise FatalHttpExceptionError(response.status, f"Unhandled error: {error_message}", error_code)
