from typing import List, Dict, Any, Optional
from django.conf import settings
from .client import RecommerceClient
from .mappers import to_api_product, from_api_order, RECOMMERCE_INFINITY_COUNT
from .exceptions import RecommerceError
# Imports for typing only to avoid circular dependency issues at module level if possible
# but for simplicity in this structure we'll import inside methods if needed or use 'Any'


class RecommerceService:
    """
    Высокоуровневый сервис для интеграции с Recommerce.
    Предоставляет методы для синхронизации товаров и заказов.
    """

    def __init__(self, integration_instance):
        """
        Args:
            integration_instance: Экземпляр модели RecommerceIntegration
        """
        self.integration = integration_instance
        self.client = RecommerceClient(
            store_url=integration_instance.store_url,
            api_token=integration_instance.api_token
        )

    def update_product(self, product: Any, fields: Optional[List[str]] = None) -> bool:
        """
        Обновить товар в Recommerce.
        
        Args:
            product: Экземпляр Product
            fields: Список полей для обновления (например ['price', 'count']).
                    Если None - обновляются все поля.
        
        Returns:
            bool: Успех операции
        """
        # Получаем остаток, если нужно
        stock_count = None
        if fields is None or 'count' in fields:
            # Используем in_stock для определения наличия в формате Recommerce:
            # - in_stock=False → count=0 (нет в наличии)
            # - in_stock=True → count=999999 (есть в наличии, "бесконечность")
            stock_count = RECOMMERCE_INFINITY_COUNT if product.in_stock else 0

        data = to_api_product(product, stock_count=stock_count, fields=fields)
        
        try:
            # Сначала пробуем обновить
            # SKU берем из data или продукта
            sku = data.get('sku', getattr(product, 'sku', str(product.id)))
            
            # Recommerce API: POST /catalog/products/{sku} для обновления
            self.client.update_product(sku, data)
            return True
            
        except RecommerceError as e:
            # Если 404 - товар не найден, можно попробовать создать?
            # В рамках "простой" интеграции - пока просто логируем или рейзим
            # Если нужно автоматическое создание:
            # if isinstance(e, RecommerceAPIError) and e.status_code == 404:
            #     return self.create_product(product)
            raise e

    def create_product(self, product: Any) -> bool:
        """
        Создать товар в Recommerce.

        Raises:
            RecommerceError: Если отсутствует обязательное поле parent_category_sku
        """
        # Для создания нужны все поля
        # Используем in_stock для определения наличия в формате Recommerce
        stock_count = RECOMMERCE_INFINITY_COUNT if product.in_stock else 0

        data = to_api_product(product, stock_count=stock_count, fields=None, for_create=True)

        # Проверяем обязательное поле для создания
        if 'parent_category_sku' not in data:
            raise RecommerceError(
                f"Невозможно создать товар '{product.sku}' в Recommerce: "
                f"не указана категория (parent_category_sku). "
                f"Добавьте поле recommerce_category_sku к товару или категории."
            )

        self.client.create_product(data)
        return True

    def get_new_orders(self, updated_after: str) -> List[Dict[str, Any]]:
        """
        Получить список новых заказов из Recommerce.
        
        Args:
            updated_after: Дата в формате 'Y-m-d-H-i-s'
            
        Returns:
            List[Dict]: Список DTO заказов (готовых для сохранения)
        """
        raw_orders = self.client.get_orders(updated_after=updated_after)
        
        orders_dto = []
        for raw_order in raw_orders:
            dto = from_api_order(raw_order)
            orders_dto.append(dto)
            
        return orders_dto

    def check_connection(self) -> bool:
        """Проверить соединение"""
        try:
            # Пробуем получить список заказов (легкий запрос)
            self.client.get_orders()
            return True
        except RecommerceError:
            return False