from django.db import models
from django.core.exceptions import ValidationError
from django.utils import timezone


class PromoCode(models.Model):
    """
    Промокод для активации скидки.
    Связывает код с одной скидкой.
    """

    code = models.CharField(
        max_length=50,
        unique=True,
        verbose_name="Код промокода",
        help_text="Уникальный код (например: SALE2025, WINTER10)"
    )

    discount = models.ForeignKey(
        'Discount',
        on_delete=models.CASCADE,
        related_name='promo_codes',
        verbose_name="Скидка"
    )

    # Ограничения использования
    max_uses_per_user = models.PositiveIntegerField(
        null=True,
        blank=True,
        verbose_name="Макс. использований на клиента",
        help_text="Оставьте пустым для безлимитного использования"
    )

    max_total_uses = models.PositiveIntegerField(
        null=True,
        blank=True,
        verbose_name="Макс. общее количество использований"
    )

    current_uses = models.PositiveIntegerField(
        default=0,
        verbose_name="Текущее количество использований"
    )

    is_active = models.BooleanField(
        default=True,
        verbose_name="Активен"
    )

    start_date = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name="Дата начала действия"
    )

    end_date = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name="Дата окончания действия"
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Дата создания"
    )

    created_by = models.ForeignKey(
        'accounts.CustomUser',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='created_promo_codes',
        verbose_name="Создал"
    )

    class Meta:
        verbose_name = "Промокод"
        verbose_name_plural = "Промокоды"
        indexes = [
            models.Index(fields=['code']),
            models.Index(fields=['is_active']),
        ]

    def __str__(self):
        return f"{self.code} -> {self.discount.name}"

    def clean(self):
        """Валидация промокода"""
        super().clean()
        if self.code:
            self.code = self.code.strip().upper()

    def save(self, *args, **kwargs):
        """Приводим код к верхнему регистру при сохранении"""
        if self.code:
            self.code = self.code.strip().upper()
        super().save(*args, **kwargs)

    def is_valid(self, customer=None):
        """
        Проверить валидность промокода.

        Args:
            customer: Customer для проверки использований на пользователя

        Returns:
            tuple: (is_valid, error_message)
        """
        now = timezone.now()

        if not self.is_active:
            return False, "Промокод неактивен"

        if self.start_date and now < self.start_date:
            return False, "Промокод еще не начал действовать"

        if self.end_date and now > self.end_date:
            return False, "Промокод истек"

        if self.max_total_uses and self.current_uses >= self.max_total_uses:
            return False, "Промокод полностью использован"

        if customer and self.max_uses_per_user:
            # Проверяем использования этим клиентом
            uses = DiscountApplication.objects.filter(
                promo_code=self,
                customer=customer
            ).count()

            if uses >= self.max_uses_per_user:
                return False, f"Вы уже использовали этот промокод максимальное количество раз ({self.max_uses_per_user})"

        return True, None

    def record_usage(self, customer=None):
        """
        Зарегистрировать использование промокода.

        Args:
            customer: Customer (опционально)
        """
        self.current_uses += 1
        self.save(update_fields=['current_uses'])


# Импортируем здесь, чтобы избежать циклического импорта
from .application import DiscountApplication
