"""
Модели для работы с группами вариантов товаров.
Позволяет группировать взаимозаменяемые товары (например, розы разной длины).
"""
from django.db import models


class ProductVariantGroup(models.Model):
    """
    Группа вариантов товара (взаимозаменяемые товары).
    Например: "Роза красная Freedom" включает розы 50см, 60см, 70см.
    """
    name = models.CharField(max_length=200, verbose_name="Название")
    description = models.TextField(blank=True, verbose_name="Описание")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="Дата обновления")

    class Meta:
        verbose_name = "Группа вариантов"
        verbose_name_plural = "Группы вариантов"
        ordering = ['name']

    def __str__(self):
        return self.name

    def get_products_count(self):
        """Возвращает количество товаров в группе"""
        return self.items.count()

    @property
    def in_stock(self):
        """
        Вариант в наличии, если хотя бы один из его товаров в наличии.
        Товар в наличии, если Product.in_stock = True.

        Оптимизирован для использования с prefetch_related('items__product').
        Вычисляет результат в памяти без доп. запроса БД.
        """
        for item in self.items.all():
            if item.product.in_stock:
                return True
        return False

    @property
    def price(self):
        """
        Цена варианта определяется по приоритету товаров:
        1. Берётся финальная цена товара с приоритетом 1, если он в наличии
        2. Если нет - финальная цена товара с приоритетом 2
        3. И так далее по приоритетам
        4. Если ни один товар не в наличии - берётся максимальная цена из группы

        Финальная цена = sale_price (скидка) если задана, иначе price (основная цена).
        Оптимизирован для использования с prefetch_related('items__product').
        Вычисляет результат в памяти без доп. запроса БД.

        Возвращает Decimal (цену) или None если группа пуста.
        """
        items = self.items.all().order_by('priority', 'id')

        if not items.exists():
            return None

        # Ищем первый товар в наличии
        for item in items:
            if item.product.in_stock:
                return item.product.actual_price

        # Если ни один товар не в наличии - берем максимальную цену
        max_price = None
        for item in items:
            item_price = item.product.actual_price
            if max_price is None or item_price > max_price:
                max_price = item_price

        return max_price


class ProductVariantGroupItem(models.Model):
    """
    Товар в группе вариантов с приоритетом для этой конкретной группы.
    Приоритет определяет порядок выбора товара при использовании группы в комплектах.
    Например: в группе "Роза красная Freedom" - роза 50см имеет приоритет 1, 60см = 2, 70см = 3.
    """
    variant_group = models.ForeignKey(
        ProductVariantGroup,
        on_delete=models.CASCADE,
        related_name='items',
        verbose_name="Группа вариантов"
    )
    product = models.ForeignKey(
        'Product',
        on_delete=models.CASCADE,
        related_name='variant_group_items',
        verbose_name="Товар"
    )
    priority = models.PositiveIntegerField(
        default=0,
        help_text="Меньше = выше приоритет (1 - наивысший приоритет в этой группе)"
    )

    class Meta:
        verbose_name = "Товар в группе вариантов"
        verbose_name_plural = "Товары в группах вариантов"
        ordering = ['priority', 'id']
        unique_together = [['variant_group', 'product']]
        indexes = [
            models.Index(fields=['variant_group', 'priority']),
            models.Index(fields=['product']),
        ]

    def __str__(self):
        return f"{self.variant_group.name} - {self.product.name} (приоритет {self.priority})"
