from django.db import models
from io import BytesIO
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

# Справочник товаров
class Product(models.Model):
    name = models.CharField(max_length=255, verbose_name="Наименование товара")
    manufacturer_name = models.CharField(max_length=255, verbose_name="Производитель")
    manufacturer_country = models.CharField(max_length=255, verbose_name="Страна производителя")
    manufacturer_code = models.CharField(max_length=50, verbose_name="Код производителя", blank=True, null=True)
    dimensions = models.CharField(max_length=255, verbose_name="Размеры", blank=True, null=True)
    unit_of_measure = models.CharField(max_length=50, verbose_name="Единица измерения")
    shelf_life_days = models.IntegerField(verbose_name="Срок годности (дни)")
    barcode = models.CharField(max_length=50, unique=True, verbose_name="Штрихкод")

    def __str__(self):
        return self.name


# Типы цен (например, регулярная, скидочная, акционная)
class PriceType(models.Model):
    name = models.CharField(max_length=50, verbose_name="Тип цены", choices=[
        ('regular', 'Регулярная'),
        ('discount', 'Скидочная'),
        ('promotional', 'Акционная'),
    ])

    def __str__(self):
        return self.name


# Прайс-листы (со всеми ценами)
class PriceList(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
    price_type = models.ForeignKey(PriceType, on_delete=models.CASCADE, verbose_name="Тип цены")
    entry_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Входная цена")
    final_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Итоговая цена")
    date_effective = models.DateField(verbose_name="Дата вступления в силу")
    constraint_percent_limit = models.DecimalField(max_digits=5, decimal_places=2, default=1000, verbose_name="Лимит на наценку (%)")
    constraint_price_change = models.DecimalField(max_digits=5, decimal_places=2, default=90, verbose_name="Лимит на изменение цены (%)")

    def save(self, *args, **kwargs):
        if self.pk:
            old_price = PriceList.objects.get(pk=self.pk).final_price
            price_change_percent = abs((self.final_price - old_price) / old_price) * 100
            if price_change_percent > self.constraint_price_change:
                raise ValueError(f"Цена не может измениться более чем на {self.constraint_price_change}%")
        
        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.product.name} - {self.price_type.name} - {self.final_price} руб."


# Скидки и акции (могут применяться к товарам)
class Discount(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
    discount_percentage = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Процент скидки")
    start_date = models.DateField(verbose_name="Дата начала")
    end_date = models.DateField(verbose_name="Дата окончания")
    description = models.TextField(verbose_name="Описание акции", blank=True, null=True)

    def __str__(self):
        return f"Скидка {self.discount_percentage}% на {self.product.name} с {self.start_date} по {self.end_date}"


# История изменений цен
class PriceChangeHistory(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
    old_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Старая цена")
    new_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Новая цена")
    change_date = models.DateTimeField(auto_now_add=True, verbose_name="Дата изменения цены")
    reason = models.TextField(verbose_name="Причина изменения цены", blank=True, null=True)

    def __str__(self):
        return f"{self.product.name} - изменение цены с {self.old_price} на {self.new_price} - {self.change_date}"


# Пример использования ценников для печати
class PriceTag(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="Товар")
    price_list = models.ForeignKey(PriceList, on_delete=models.CASCADE, verbose_name="Прайс-лист")
    tag_image = models.ImageField(upload_to='price_tags/', verbose_name="Изображение ценника", blank=True, null=True)
    price_effective_date = models.DateField(verbose_name="Дата вступления в силу ценника")
    
    def generate_pdf(self):
        """Генерация ценника в формате PDF."""
        buffer = BytesIO()
        c = canvas.Canvas(buffer, pagesize=letter)
        c.drawString(100, 750, f"Продукт: {self.product.name}")
        c.drawString(100, 730, f"Тип цены: {self.price_list.price_type.name}")
        c.drawString(100, 710, f"Входная цена: {self.price_list.entry_price} руб.")
        c.drawString(100, 690, f"Итоговая цена: {self.price_list.final_price} руб.")
        c.showPage()
        c.save()
        buffer.seek(0)
        return buffer

    def __str__(self):
        return f"Ценник для {self.product.name} - {self.price_effective_date}"


# Связь с историей акций
class DiscountHistory(models.Model):
    discount = models.ForeignKey(Discount, on_delete=models.CASCADE, verbose_name="Акция/Скидка")
    old_discount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Старая скидка")
    new_discount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Новая скидка")
    change_date = models.DateTimeField(auto_now_add=True, verbose_name="Дата изменения скидки")
    reason = models.TextField(verbose_name="Причина изменения скидки", blank=True, null=True)

    def __str__(self):
        return f"Изменение скидки с {self.old_discount}% на {self.new_discount}% для {self.discount.product.name}"


# Пример применения скидки к прайс-листу
class PriceListWithDiscount(models.Model):
    price_list = models.ForeignKey(PriceList, on_delete=models.CASCADE, verbose_name="Прайс-лист")
    discount = models.ForeignKey(Discount, on_delete=models.CASCADE, verbose_name="Скидка")
    final_price_after_discount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Итоговая цена после скидки")

    def save(self, *args, **kwargs):
        # Расчёт итоговой цены с учётом скидки
        self.final_price_after_discount = self.price_list.final_price - (self.price_list.final_price * self.discount.discount_percentage / 100)
        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.price_list.product.name} - {self.final_price_after_discount} руб. (с учетом скидки)"
