import logging
from celery import shared_task
from django.db import transaction
from django_tenants.utils import schema_context
from integrations.models import RecommerceIntegration
from integrations.recommerce.services import RecommerceService
from products.models import Product
from integrations.recommerce.exceptions import RecommerceError, RecommerceAPIError

logger = logging.getLogger(__name__)

@shared_task(bind=True)
def sync_products_batch_task(self, product_ids, options=None, schema_name=None):
    """
    Celery задача для массовой синхронизации товаров с Recommerce.

    Args:
        product_ids (list): Список ID товаров (PK) для синхронизации
        options (dict): Настройки синхронизации
            - fields (list): Список полей для обновления ['price', 'count', 'content', 'images']
            - create_if_missing (bool): Создавать товар, если он не найден (404)
        schema_name (str): Имя схемы тенанта для выполнения запросов
    """
    if options is None:
        options = {}

    fields = options.get('fields', [])
    create_if_missing = options.get('create_if_missing', False)

    # Используем schema_context для выполнения запросов в правильной tenant схеме
    if schema_name:
        with schema_context(schema_name):
            return _do_sync(product_ids, fields, create_if_missing)
    else:
        return _do_sync(product_ids, fields, create_if_missing)


def _do_sync(product_ids, fields, create_if_missing):
    """
    Внутренняя функция для выполнения синхронизации в контексте схемы.

    Args:
        product_ids (list): Список ID товаров (PK) для синхронизации
        fields (list): Список полей для обновления ['price', 'count', 'content', 'images']
        create_if_missing (bool): Создавать товар, если он не найден (404)
    """
    # 1. Получаем интеграцию
    integration = RecommerceIntegration.objects.filter(is_active=True).first()
    if not integration or not integration.is_configured:
        msg = "Recommerce integration is not active or configured."
        logger.error(msg)
        return {"success": False, "error": msg}
        
    service = RecommerceService(integration)
    
    # 2. Получаем товары
    products = Product.objects.filter(pk__in=product_ids)
    
    results = {
        "total": len(product_ids),
        "success": 0,
        "failed": 0,
        "created": 0,
        "updated": 0,
        "errors": []
    }
    
    logger.info(f"Starting Recommerce sync for {len(product_ids)} products. Fields: {fields}, create_if_missing: {create_if_missing}")
    
    for product in products:
        try:
            # Если fields пустой или содержит 'all' - обновляем всё (передаем None в сервис)
            # Иначе передаем список полей.
            # В сервисе update_product(fields=None) обновляет всё.
            
            # Маппинг опций фронтенда на логику сервиса
            # Фронт: ['price', 'count', 'content', 'images']
            # Сервис: ожидает список полей или None (всё).
            # Если выбраны не все галочки, передаем конкретные поля.
            # Но 'content' и 'images' в сервисе могут не поддерживаться напрямую как ключи, 
            # нужно смотреть реализацию to_api_product.
            # Пока передаем как есть, предполагая, что сервис или маппер разберется, 
            # либо если выбрано "все", передаем None.
            
            # Упрощение: если выбраны все основные группы, считаем это полным обновлением
            is_full_update = False
            if 'content' in fields and 'images' in fields and 'price' in fields and 'count' in fields:
                is_full_update = True
                
            service_fields = None if is_full_update else fields
            
            # Если список полей пуст (ничего не выбрано), но задача запущена - странно, но пропустим
            if not is_full_update and not service_fields:
                logger.warning(f"Product {product.id}: No fields selected for update.")
                continue

            try:
                service.update_product(product, fields=service_fields)
                results["updated"] += 1
                results["success"] += 1
                
            except RecommerceAPIError as e:
                # Если товар не найден (404) и разрешено создание
                if e.status_code == 404 and create_if_missing:
                    logger.info(f"Product {product.sku} not found. Creating...")
                    service.create_product(product)
                    results["created"] += 1
                    results["success"] += 1
                else:
                    raise e
                    
        except Exception as e:
            results["failed"] += 1
            error_msg = f"Product {product.sku} ({product.id}): {str(e)}"
            logger.error(error_msg)
            results["errors"].append(error_msg)
            
    logger.info(f"Recommerce sync completed. Results: {results}")
    return results