"""
Модуль с миксином для операций записи в Bitrix24 API.

Содержит методы для создания, обновления и удаления данных в API Bitrix24.
"""

from typing import Any, ClassVar

from fast_bitrix24 import Bitrix

from app.domain.entities.base_entity import BitrixEntity
from app.infrastructure.bitrix.mixins.error_handling import (
    BitrixErrorHandlingMixin,
)
from app.infrastructure.logging.logger import logger


class BitrixWriteMixin[T: BitrixEntity](BitrixErrorHandlingMixin):
    """
    Миксин для операций записи данных в Bitrix24 API.

    Предоставляет методы для создания, обновления и удаления сущностей.
    """

    _bitrix_create_method: ClassVar[str]
    _bitrix_update_method: ClassVar[str]
    _bitrix_delete_method: ClassVar[str]
    _entity_factory: type[T]

    _id_param_name: ClassVar[str] = "ID"
    _fields_param_name: ClassVar[str] = "fields"

    def __init__(self, bitrix: Bitrix):
        """
        Инициализация миксина.

        :param bitrix: Клиент для работы с API Bitrix24
        """
        self.bitrix = bitrix

    async def create(self, entity: T) -> int | None:
        """
        Создание новой сущности.

        :param entity: Объект сущности для создания
        :return: ID созданной сущности или None в случае ошибки
        """
        error_message = (
            f"Ошибка при создании сущности "
            f"{self._format_entity_name(self._entity_factory)}"
        )

        try:
            fields = entity.to_bitrix()

            response = await self._safe_call(
                self.bitrix.call,
                error_message,
                None,
                self._bitrix_create_method,
                {self._fields_param_name: fields},
            )

            if not response or "result" not in response:
                logger.warning(f"{error_message}: получен некорректный ответ")
                return None

            result = response.get("result")
            if not result:
                logger.error(
                    f"{error_message}: отсутствует идентификатор в ответе",
                )
                return None

            try:
                return int(result)
            except (ValueError, TypeError):
                logger.error(
                    f"Не удалось преобразовать ID={result} к целому числу "
                    f"при создании сущности "
                    f"{self._format_entity_name(self._entity_factory)}",
                )
                return None
        except Exception as e:
            logger.error(f"{error_message}: {e}")
            return None

    async def update(self, entity_id: int, entity: T) -> bool:
        """
        Обновление существующей сущности.

        :param entity_id: Идентификатор сущности
        :param entity: Объект сущности с обновленными данными
        :return: True, если обновление успешно, иначе False
        """
        error_message = (
            f"Ошибка при обновлении сущности "
            f"{self._format_entity_name(self._entity_factory)} с ID={entity_id}"
        )

        try:
            fields = entity.to_bitrix()

            response = await self._safe_call(
                self.bitrix.call,
                error_message,
                None,
                self._bitrix_update_method,
                {
                    self._id_param_name: entity_id,
                    self._fields_param_name: fields,
                },
            )

            if not response or "result" not in response:
                logger.warning(f"{error_message}: получен некорректный ответ")
                return False

            return bool(response.get("result"))
        except Exception as e:
            logger.error(f"{error_message}: {e}")
            return False

    async def update_fields(
        self,
        entity_id: int,
        fields: dict[str, Any],
    ) -> bool:
        """
        Обновление выбранных полей существующей сущности.

        :param entity_id: Идентификатор сущности
        :param fields: Словарь с полями для обновления
        :return: True, если обновление успешно, иначе False
        """
        error_message = (
            f"Ошибка при обновлении полей сущности "
            f"{self._format_entity_name(self._entity_factory)} с ID={entity_id}"
        )

        try:
            response = await self._safe_call(
                self.bitrix.call,
                error_message,
                None,
                self._bitrix_update_method,
                {
                    self._id_param_name: entity_id,
                    self._fields_param_name: fields,
                },
            )

            if not response or "result" not in response:
                logger.warning(f"{error_message}: получен некорректный ответ")
                return False

            return bool(response.get("result"))
        except Exception as e:
            logger.error(f"{error_message}: {e}")
            return False

    async def delete(self, entity_id: int) -> bool:
        """
        Удаление сущности.

        :param entity_id: Идентификатор сущности
        :return: True, если удаление успешно, иначе False
        """
        error_message = (
            f"Ошибка при удалении сущности "
            f"{self._format_entity_name(self._entity_factory)} с ID={entity_id}"
        )

        try:
            response = await self._safe_call(
                self.bitrix.call,
                error_message,
                None,
                self._bitrix_delete_method,
                {self._id_param_name: entity_id},
            )

            if not response or "result" not in response:
                logger.warning(f"{error_message}: получен некорректный ответ")
                return False

            return bool(response.get("result"))
        except Exception as e:
            logger.error(f"{error_message}: {e}")
            return False
