from django.db import models
from .base import BaseDiscount


class Discount(BaseDiscount):
    """
    Основная модель скидки.
    Наследует все поля из BaseDiscount и добавляет специфические параметры.
    """

    # Для scope='order' - минимальная сумма заказа
    min_order_amount = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        null=True,
        blank=True,
        verbose_name="Мин. сумма заказа",
        help_text="Скидка применяется только если сумма заказа >= этого значения"
    )

    # Для scope='product' и scope='category' - товары и категории
    products = models.ManyToManyField(
        'products.Product',
        blank=True,
        related_name='discounts',
        verbose_name="Товары"
    )

    categories = models.ManyToManyField(
        'products.ProductCategory',
        blank=True,
        related_name='discounts',
        verbose_name="Категории"
    )

    # Исключения (товары, к которым скидка НЕ применяется)
    excluded_products = models.ManyToManyField(
        'products.Product',
        blank=True,
        related_name='excluded_from_discounts',
        verbose_name="Исключенные товары"
    )

    # Автоматическая скидка (не требует промокода)
    is_auto = models.BooleanField(
        default=False,
        verbose_name="Автоматическая",
        help_text="Применяется автоматически при выполнении условий"
    )

    # Режим объединения с другими скидками
    combine_mode = models.CharField(
        max_length=20,
        choices=BaseDiscount.COMBINE_MODE_CHOICES,
        default='max_only',
        verbose_name="Режим объединения",
        help_text="stack = суммировать с другими, max_only = применить максимальную, exclusive = отменить остальные"
    )

    class Meta:
        verbose_name = "Скидка"
        verbose_name_plural = "Скидки"
        indexes = [
            models.Index(fields=['is_active']),
            models.Index(fields=['scope']),
            models.Index(fields=['discount_type']),
            models.Index(fields=['is_auto']),
        ]

    def applies_to_product(self, product):
        """
        Проверить, применяется ли скидка к товару.

        Args:
            product: Объект Product

        Returns:
            bool: True если скидка применяется к товару
        """
        # Проверяем исключения
        if self.excluded_products.filter(id=product.id).exists():
            return False

        # Если scope='product', проверяем прямое соответствие
        if self.scope == 'product':
            return self.products.filter(id=product.id).exists()

        # Если scope='category', проверяем категории товара
        if self.scope == 'category':
            if not self.categories.exists():
                return False
            product_categories = product.categories.all()
            return self.categories.filter(id__in=product_categories).exists()

        return False

    def get_applicable_products(self):
        """
        Получить queryset товаров, к которым применяется эта скидка.

        Returns:
            QuerySet: Товары, к которым применяется скидка
        """
        from products.models import Product

        if self.scope == 'product':
            qs = self.products.all()
            # Исключаем исключенные товары
            if self.excluded_products.exists():
                qs = qs.exclude(id__in=self.excluded_products.values_list('id', flat=True))
            return qs

        if self.scope == 'category':
            # Товары из указанных категорий
            product_ids = Product.objects.filter(
                categories__in=self.categories.all()
            ).values_list('id', flat=True).distinct()
            # Исключаем исключенные товары
            if self.excluded_products.exists():
                excluded_ids = self.excluded_products.values_list('id', flat=True)
                product_ids = set(product_ids) - set(excluded_ids)
            return Product.objects.filter(id__in=product_ids)

        return Product.objects.none()
