"""Credentials mixin: verify_credentials, determine_instance_type, _set_instance_parameters."""

import json
import logging
from typing import Any

from httpx import HTTPError

from minimal_activitypub import __display_name__
from minimal_activitypub.constants import INSTANCE_TYPE_PLEROMA
from minimal_activitypub.constants import INSTANCE_TYPE_TAKAHE
from minimal_activitypub.constants import MAX_ATTACHMENTS_PLEROMA
from minimal_activitypub.constants import MAX_ATTACHMENTS_TAKAHE
from minimal_activitypub.exceptions import NetworkError
from minimal_activitypub.types import ActivityPubClass
from minimal_activitypub.utils import _check_exception

logger = logging.getLogger(__display_name__)


class _CredentialsMixin:
    """Mixin providing credential verification and instance type detection."""

    async def verify_credentials(self: ActivityPubClass) -> Any:
        """Verify the credentials of the user.

        :returns: The response is a JSON object containing the account's information.

        """
        url = f"{self.instance}/api/v1/accounts/verify_credentials"
        logger.debug("ActivityPub.verify_credentials() - url=%s", url)
        try:
            response = await self.client.get(url=url, headers=self.headers, timeout=self.timeout)
            logger.debug(
                "ActivityPub.verify_credentials - response: \n%s",
                response,
            )
            self._update_ratelimit(response.headers)
            await _check_exception(response=response)
            self._parse_next_prev(links=response.headers.get("Link"))
            json_response = response.json()
        except HTTPError as error:
            raise NetworkError from error

        return json_response

    async def determine_instance_type(self: ActivityPubClass) -> None:
        """Check if the instance is a Pleroma instance or not."""
        instance = self.instance
        if "http" not in self.instance:
            instance = f"https://{self.instance}"

        try:
            response = await self.client.get(url=f"{instance}/api/v1/instance", timeout=self.timeout)
            await _check_exception(response=response)
            response_dict = response.json()
        except HTTPError as error:
            raise NetworkError from error

        logger.debug(
            "ActivityPub.determine_instance_type -> response.dict:\n%s",
            json.dumps(response_dict, indent=4),
        )
        self.instance = instance

        self._set_instance_parameters(response_dict)

        logger.debug(
            "ActivityPub.determine_instance_type() ... instance_type=%s",
            self.instance_type,
        )

    def _set_instance_parameters(self, response_dict: dict[str, Any]) -> None:
        """Set instance parameters from the /api/v1/instance response dict.

        :param response_dict: Dictionary returned by call to .../api/v1/instance
        """
        version = response_dict.get("version", "")
        if INSTANCE_TYPE_TAKAHE in version:
            self.instance_type = INSTANCE_TYPE_TAKAHE
            self.max_attachments = MAX_ATTACHMENTS_TAKAHE
        elif INSTANCE_TYPE_PLEROMA in version:
            self.instance_type = INSTANCE_TYPE_PLEROMA
            self.max_attachments = MAX_ATTACHMENTS_PLEROMA

        instance_config = response_dict.get("configuration", {})

        if (max_status_len := instance_config.get("statuses", {}).get("max_characters")) or (
            max_status_len := response_dict.get("max_characters")
        ):
            self.max_status_len = max_status_len

        if (max_attachments := instance_config.get("statuses", {}).get("max_media_attachments")) or (
            max_attachments := response_dict.get("max_media_attachments")
        ):
            self.max_attachments = max_attachments

        if max_att_size := instance_config.get("media_attachments", {}).get("image_size_limit"):
            self.max_att_size = max_att_size

        if mime_types := instance_config.get("media_attachments", {}).get("supported_mime_types"):
            self.supported_mime_types = mime_types
