# -*- coding: utf-8 -*-
from celery import shared_task
from django.utils import timezone
from django.db.models import Q
import logging
from django_tenants.utils import get_tenant_model, schema_context

logger = logging.getLogger(__name__)


@shared_task
def cleanup_expired_cart_locks():
    """
    Периодическая задача для очистки истекших блокировок корзины.
    Освобождает витринные комплекты, которые были добавлены в корзину,
    но блокировка истекла (timeout 30 минут).

    Запускается каждые 5 минут (настроить в celery beat schedule).
    Проходит по всем тенантам.

    Returns:
        dict: Статистика очистки {
            'released_count': int,  # Общее количество освобожденных блокировок
            'details': list         # Детали по каждому тенанту
        }
    """
    Tenant = get_tenant_model()
    overall_stats = {
        'released_count': 0,
        'details': []
    }
    
    # Проходим по всем тенантам (кроме public)
    # Public схема не содержит бизнес-данных (корзины, резервы)
    tenants = Tenant.objects.exclude(schema_name='public')
    
    for tenant in tenants:
        try:
            with schema_context(tenant.schema_name):
                from inventory.models import Reservation
                
                # Находим все резервы с истекшей блокировкой
                expired_locks = Reservation.objects.filter(
                    Q(cart_lock_expires_at__lte=timezone.now()) &
                    Q(cart_lock_expires_at__isnull=False) &
                    Q(status='reserved')
                ).select_related('product_kit', 'locked_by_user')

                count = expired_locks.count()
                
                if count > 0:
                    affected_kits = list(
                        expired_locks.values_list('product_kit_id', flat=True).distinct()
                    )
                    
                    logger.info(
                        f"[{tenant.schema_name}] Очистка истекших блокировок: {count} резервов"
                    )

                    # Очищаем блокировки
                    expired_locks.update(
                        cart_lock_expires_at=None,
                        locked_by_user=None,
                        cart_session_id=None
                    )
                    
                    overall_stats['released_count'] += count
                    overall_stats['details'].append({
                        'tenant': tenant.schema_name,
                        'released': count,
                        'kits': affected_kits
                    })

        except Exception as e:
            # Логируем ошибку, но не прерываем обработку других тенантов
            logger.error(f"[{tenant.schema_name}] Ошибка при очистке блокировок: {e}", exc_info=True)
            overall_stats['details'].append({
                'tenant': tenant.schema_name,
                'error': str(e)
            })

    if overall_stats['released_count'] > 0:
        logger.info(f"Общая очистка блокировок завершена: {overall_stats}")

    return overall_stats
