# lista_de_materiales/models.py
from django.db import models
from django.core.validators import MinValueValidator
from decimal import Decimal
from referencias.models import Referencia

class ListaMateriales(models.Model):
    """
    Lista de Materiales (BOM) para fabricar un producto
    """
    ESTADOS_BOM = (
        ('D', 'Borrador'),
        ('A', 'Activa'),
        ('H', 'Histórica'),
        ('I', 'Inactiva'),
    )

    referencia = models.ForeignKey(
        Referencia,
        on_delete=models.CASCADE,
        related_name='listas_materiales',
        limit_choices_to={'tipo__in': ['PP', 'PT']},
        verbose_name="Producto final"
    )
    codigo = models.CharField(
        max_length=20,
        unique=True,
        verbose_name="Código BOM"
    )
    version = models.PositiveIntegerField(
        verbose_name="Versión"
    )
    estado = models.CharField(
        max_length=1,
        choices=ESTADOS_BOM,
        default='D',
        verbose_name="Estado"
    )
    fecha_creacion = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Fecha creación"
    )
    fecha_actualizacion = models.DateTimeField(
        auto_now=True,
        verbose_name="Fecha actualización"
    )
    fecha_activacion = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name="Fecha activación"
    )
    descripcion = models.TextField(
        blank=True,
        verbose_name="Descripción"
    )
    notas = models.TextField(
        blank=True,
        verbose_name="Notas técnicas"
    )
    creado_por = models.ForeignKey(
        'auth.User',
        on_delete=models.PROTECT,
        related_name='listas_creadas',
        verbose_name="Creado por"
    )

    class Meta:
        verbose_name = 'Lista de Materiales'
        verbose_name_plural = 'Listas de Materiales'
        unique_together = ('referencia', 'version')
        ordering = ['referencia__sku', '-version']

    def __str__(self):
        return f"BOM-{self.codigo} v{self.version} - {self.referencia.sku}"

    def save(self, *args, **kwargs):
        if not self.codigo:
            self.codigo = f"BOM-{self.referencia.sku}-{self.version}"
        super().save(*args, **kwargs)

class ComponenteListaMateriales(models.Model):
    """
    Componentes que forman parte de una lista de materiales
    """
    lista_materiales = models.ForeignKey(
        ListaMateriales,
        on_delete=models.CASCADE,
        related_name='componentes',
        verbose_name="Lista de Materiales"
    )
    referencia = models.ForeignKey(
        Referencia,
        on_delete=models.PROTECT,
        related_name='componente_en_listas',
        verbose_name="Componente"
    )
    cantidad = models.DecimalField(
        max_digits=12,
        decimal_places=4,
        validators=[MinValueValidator(0.0001)],
        verbose_name="Cantidad requerida"
    )
    desperdicio = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        default=0,
        validators=[MinValueValidator(0)],
        verbose_name="% Desperdicio"
    )
    orden = models.PositiveSmallIntegerField(
        default=0,
        verbose_name="Orden en ensamble"
    )
    obligatorio = models.BooleanField(
        default=True,
        verbose_name="Obligatorio"
    )
    notas = models.CharField(
        max_length=255,
        blank=True,
        verbose_name="Notas del componente"
    )

    class Meta:
        verbose_name = 'Componente de Lista'
        verbose_name_plural = 'Componentes de Lista'
        ordering = ['lista_materiales', 'orden']
        constraints = [
            models.UniqueConstraint(
                fields=['lista_materiales', 'referencia'],
                name='unique_componente_lista'
            )
        ]

    def __str__(self):
        return f"{self.cantidad} x {self.referencia.sku} para {self.lista_materiales}"

    @property
    def cantidad_total(self):
        """Cantidad incluyendo desperdicio"""
        if self.cantidad is None or self.desperdicio is None:
            return Decimal('0.0')
        return self.cantidad * (Decimal('1') + (self.desperdicio / Decimal('100')))