
from django import forms
from django.forms.models import inlineformset_factory
from django.core.exceptions import ValidationError
from decimal import Decimal
from .models import MovimientoPerdidaProceso, OrdenCompra, ItemOrdenCompra, DevolucionCompra, DevolucionMuestraComercial, DevolucionProduccion, MovimientoDevolucionVenta, AjusteInventarioFisico, MuestraComercial, RecepcionProduccion, MovimientoVenta
from fabricacion.models import MaquinaReferencia
class OrdenCompraForm(forms.ModelForm):
    class Meta:
        model = OrdenCompra
        fields = [
            'proveedor',
            'fecha_requerida',
            'forma_pago',
            'estado',
            'observaciones',
        ]
        widgets = {
            'proveedor': forms.Select(attrs={'class': 'form-control'}),
            'fecha_requerida': forms.DateInput(
                attrs={'type': 'date', 'class': 'form-control'}
            ),
            'forma_pago': forms.Select(attrs={'class': 'form-control'}),
            'estado': forms.Select(attrs={'class': 'form-control'}),
            'observaciones': forms.Textarea(
                attrs={'class': 'form-control', 'rows': 3}
            ),
        }


# Formset para usar en el admin (permite eliminar ítems)
ItemOrdenCompraFormSet = inlineformset_factory(
    parent_model=OrdenCompra,
    model=ItemOrdenCompra,
    fields=[
        'referencia',
        'cantidad',
        'precio_unitario',
        'empaque',
        'proveedor_referencia',
        'lead_time',
        'certificado',
    ],
    extra=1,
    can_delete=True,
    widgets={
        'referencia': forms.Select(attrs={'class': 'form-control'}),
        'cantidad': forms.NumberInput(
            attrs={'class': 'form-control', 'step': '0.0001'}
        ),
        'precio_unitario': forms.NumberInput(
            attrs={'class': 'form-control', 'step': '0.0001'}
        ),
        'empaque': forms.Select(attrs={'class': 'form-control'}),
        'proveedor_referencia': forms.Select(attrs={'class': 'form-control'}),
        'lead_time': forms.NumberInput(attrs={'class': 'form-control'}),
        'certificado': forms.CheckboxInput(
            attrs={'class': 'form-check-input'}
        ),
    }
)


# Formset para la vista manual (no permite eliminar ítems aquí)
ItemOrdenCompraManualFormSet = inlineformset_factory(
    parent_model=OrdenCompra,
    model=ItemOrdenCompra,
    fields=[
        'referencia',
        'cantidad',
        'precio_unitario',
        'empaque',
        'proveedor_referencia',
        'lead_time',
        'certificado',
    ],
    extra=1,
    can_delete=False,
    widgets={
        'referencia': forms.Select(attrs={'class': 'form-control'}),
        'cantidad': forms.NumberInput(
            attrs={'class': 'form-control', 'step': '0.0001'}
        ),
        'precio_unitario': forms.NumberInput(
            attrs={'class': 'form-control', 'step': '0.0001'}
        ),
        'empaque': forms.Select(attrs={'class': 'form-control'}),
        'proveedor_referencia': forms.Select(attrs={'class': 'form-control'}),
        'lead_time': forms.NumberInput(attrs={'class': 'form-control'}),
        'certificado': forms.CheckboxInput(
            attrs={'class': 'form-check-input'}
        ),
    }
)
class AjusteInventarioFisicoForm(forms.ModelForm):
    class Meta:
        model = AjusteInventarioFisico
        fields = '__all__'

class MuestraComercialForm(forms.ModelForm):
    # Campos de sólo lectura
    stock_antes = forms.CharField(
        label="stock_antes",
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
        })
    )
    stock_despues = forms.CharField(
        label="stock_despues",
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
        })
    )
    costo_unitario = forms.CharField(
        label="costo_unitario",
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
        })
    )
    valor_total_salida = forms.CharField(
        label="valor_total_salida",
        required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
        })
    )

    class Meta:
        model = MuestraComercial
        fields = [
            'referencia',
            'fecha',
            'cantidad_entregada',
            'observaciones',
            'entregado_por',
        ]
        widgets = {
            'referencia': forms.Select(attrs={'class': 'form-control'}),
            'fecha':       forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'cantidad_entregada': forms.NumberInput(attrs={
                'class':'form-control', 'step':'0.0001'
            }),
            'observaciones': forms.Textarea(attrs={
                'class':'form-control', 'rows':2
            }),
            'entregado_por': forms.Select(attrs={'class':'form-control'}),
        }

class RecepcionProduccionForm(forms.ModelForm):
    class Meta:
        model = RecepcionProduccion
        fields = [
            'referencia',
            'planta',
            'maquina',
            'fecha',
            'cantidad_antes',
            'cantidad_producida',
            'cantidad_despues',
            'costo_unitario_produccion',
            'nuevo_costo_ponderado',
            'valor_total',
        ]
        widgets = {
            'referencia': forms.Select(attrs={'class': 'form-control'}),
            'planta': forms.Select(attrs={'class': 'form-control'}),
            'maquina': forms.Select(attrs={'class': 'form-control'}),
            'fecha': forms.DateInput(attrs={'type': 'date','class':'form-control'}),
            'cantidad_antes': forms.NumberInput(attrs={
                'class':'form-control','step':'0.0001','readonly':'readonly'
            }),
            'cantidad_producida': forms.NumberInput(attrs={
                'class':'form-control','step':'0.0001'
            }),
            # Para mostrar coma decimal pero luego lo parseamos manualmente
            'cantidad_despues': forms.TextInput(attrs={
                'class':'form-control','readonly':'readonly'
            }),
            'costo_unitario_produccion': forms.NumberInput(attrs={
                'class':'form-control','step':'0.0001'
            }),
            'nuevo_costo_ponderado': forms.TextInput(attrs={
                'class':'form-control','readonly':'readonly'
            }),
            'valor_total': forms.TextInput(attrs={
                'class':'form-control','readonly':'readonly'
            }),
        }

    def clean_cantidad_producida(self):
        # tu validación de mínimo por máquina…
        cantidad = self.cleaned_data.get('cantidad_producida')
        maquina = self.cleaned_data.get('maquina')
        referencia = self.cleaned_data.get('referencia')
        if maquina and referencia and cantidad is not None:
            try:
                mr = MaquinaReferencia.objects.get(
                    maquina=maquina, referencia=referencia
                )
            except MaquinaReferencia.DoesNotExist:
                raise ValidationError("Máquina no produce esta referencia.")
            if cantidad < mr.minimo_unidades:
                raise ValidationError(
                    f"Mínimo de {mr.minimo_unidades} unidades."
                )
        return cantidad

    def _parse_decimal(self, field_name):
        """Helper para extraer, normalizar coma->punto y convertir a Decimal."""
        raw = self.data.get(field_name, '')
        raw = raw.replace(',', '.')
        try:
            return Decimal(raw)
        except Exception:
            raise ValidationError(f"Formato inválido en {field_name}")

    def clean_valor_total(self):
        val = self._parse_decimal('valor_total')
        print("🐞 clean_valor_total:", val)
        return val

    def clean_nuevo_costo_ponderado(self):
        val = self._parse_decimal('nuevo_costo_ponderado')
        print("🐞 clean_nuevo_costo_ponderado:", val)
        return val

class MovimientoVentaForm(forms.ModelForm):
    class Meta:
        model = MovimientoVenta
        fields = [
            'referencia',
            'cantidad',
            'precio_unitario_venta',
            'fecha',
            'creado_por',
        ]
        widgets = {
            'referencia':           forms.Select(attrs={'class':'form-control'}),
            'cantidad':             forms.NumberInput(attrs={'class':'form-control','step':'0.0001','min':'0.0001'}),
            'precio_unitario_venta':forms.NumberInput(attrs={'class':'form-control','step':'0.01','min':'0'}),
            'fecha':                forms.DateInput(attrs={'type':'date','class':'form-control'}),
            'creado_por':           forms.Select(attrs={'class':'form-control'}),
        }

    def clean_cantidad(self):
        qty = self.cleaned_data['cantidad']
        if qty <= 0:
            raise forms.ValidationError("La cantidad debe ser mayor que cero.")
        return qty

# 1) DevolucionCompraForm
# -------------------------------------------------------------------
class DevolucionCompraForm(forms.ModelForm):
    cantidad_antes = forms.DecimalField(
        label="Cantidad antes", required=False,
        max_digits=12, decimal_places=4,
        widget=forms.NumberInput({
            'class': 'form-control',
            'step': '0.0001',
            'readonly': 'readonly',
        })
    )
    cantidad_despues = forms.DecimalField(
        label="Cantidad después", required=False,
        max_digits=12, decimal_places=4,
        widget=forms.NumberInput({
            'class': 'form-control',
            'step': '0.0001',
            'readonly': 'readonly',
        })
    )
    nuevo_precio_ponderado = forms.DecimalField(
        label="Nuevo precio ponderado", required=False,
        max_digits=12, decimal_places=4,
        widget=forms.NumberInput({
            'class': 'form-control',
            'step': '0.0001',
            'readonly': 'readonly',
        })
    )
    valor_total = forms.DecimalField(
        label="Valor total", required=False,
        max_digits=14, decimal_places=2,
        widget=forms.NumberInput({
            'class': 'form-control',
            'step': '0.01',
            'readonly': 'readonly',
        })
    )

    class Meta:
        model = DevolucionCompra
        fields = [
            'item',
            'referencia',
            'fecha',
            'cantidad_antes',
            'cantidad_devuelta',
            'cantidad_despues',
            'precio_unitario_devuelto',
            'nuevo_precio_ponderado',
            'valor_total',
        ]
        widgets = {
            'item': forms.Select(attrs={'class': 'form-control'}),
            'referencia': forms.Select(attrs={'class': 'form-control'}),
            'fecha': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'cantidad_devuelta': forms.NumberInput(attrs={
                'class': 'form-control', 'step': '0.0001'
            }),
            'precio_unitario_devuelto': forms.NumberInput(attrs={
                'class': 'form-control', 'step': '0.0001'
            }),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance and self.instance.pk:
            self.fields['cantidad_antes'].initial = self.instance.cantidad_antes
            self.fields['cantidad_despues'].initial = self.instance.cantidad_despues
            self.fields['nuevo_precio_ponderado'].initial = self.instance.nuevo_precio_ponderado
            self.fields['valor_total'].initial = self.instance.valor_total

    def clean_cantidad_devuelta(self):
        dv = self.cleaned_data.get('cantidad_devuelta')
        if dv is not None and dv <= 0:
            raise ValidationError("La cantidad devuelta debe ser mayor que cero.")
        return dv


#
# 2) DevolucionMuestraComercialForm
# -------------------------------------------------------------------
class DevolucionMuestraComercialForm(forms.ModelForm):
    stock_antes = forms.CharField(
        label="Stock antes", required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
            'id': 'id_stock_antes',
        })
    )
    stock_despues = forms.CharField(
        label="Stock después", required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
            'id': 'id_stock_despues',
        })
    )
    costo_unitario = forms.CharField(
        label="Costo unitario", required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
            'id': 'id_costo_unitario',
        })
    )
    valor_total_salida = forms.CharField(
        label="Valor total salida", required=False,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'readonly': 'readonly',
            'id': 'id_valor_total_salida',
        })
    )

    class Meta:
        model = DevolucionMuestraComercial
        fields = [
            'muestra',
            'referencia',
            'cantidad',
            'fecha',
            'usuario',
            'comentario',
        ]
        widgets = {
            'muestra': forms.Select(attrs={'class': 'form-control', 'id': 'id_muestra'}),
            'referencia': forms.Select(attrs={'class': 'form-control', 'id': 'id_referencia'}),
            'cantidad': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.0001', 'id': 'id_cantidad'}),
            'fecha': forms.DateInput(attrs={'type': 'date', 'class': 'form-control', 'id': 'id_fecha'}),
            'usuario': forms.Select(attrs={'class': 'form-control', 'id': 'id_usuario'}),
            'comentario': forms.Textarea(attrs={'class': 'form-control', 'rows': 2, 'id': 'id_comentario'}),
        }

    def clean_cantidad(self):
        c = self.cleaned_data.get('cantidad')
        if c is not None and c <= 0:
            raise ValidationError("La cantidad debe ser mayor que cero.")
        return c


#
# 3) DevolucionProduccionForm
# -------------------------------------------------------------------
class DevolucionProduccionForm(forms.ModelForm):
    stock_antes = forms.CharField(
        label="Stock antes", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'})
    )
    stock_despues = forms.CharField(
        label="Stock después", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'})
    )
    precio_costo_antes = forms.CharField(
        label="Precio costo antes", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'})
    )
    nuevo_precio_costo = forms.CharField(
        label="Nuevo precio costo", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'})
    )
    valor_inventario = forms.CharField(
        label="Valor inventario", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'})
    )

    class Meta:
        model = DevolucionProduccion
        fields = [
            'recepcion',
            'referencia',
            'cantidad_devuelta',
            'costo_unitario',
            'fecha',
            'observaciones',
        ]
        widgets = {
            'recepcion': forms.Select(attrs={'class': 'form-control'}),
            'referencia': forms.Select(attrs={'class': 'form-control'}),
            'cantidad_devuelta': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.0001'}),
            'costo_unitario': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.0001'}),
            'fecha': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
            'observaciones': forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self.instance and self.instance.pk:
            self.fields['stock_antes'].initial = self.instance.stock_antes
            self.fields['stock_despues'].initial = self.instance.stock_despues
            self.fields['precio_costo_antes'].initial = self.instance.precio_costo_antes
            self.fields['nuevo_precio_costo'].initial = self.instance.nuevo_precio_costo
            self.fields['valor_inventario'].initial = self.instance.valor_inventario

    def clean_cantidad_devuelta(self):
        dv = self.cleaned_data.get('cantidad_devuelta')
        if dv is not None and dv <= 0:
            raise ValidationError("La cantidad devuelta debe ser mayor que cero.")
        return dv

    def _parse_decimal(self, fn):
        raw = self.data.get(fn, '').replace(',', '.')
        try:
            return Decimal(raw)
        except:
            raise ValidationError(f"Formato inválido en {fn}")

    def clean_valor_inventario(self):
        return self._parse_decimal('valor_inventario')

    def clean_nuevo_precio_costo(self):
        return self._parse_decimal('nuevo_precio_costo')


#
# 4) MovimientoDevolucionVentaForm
# -------------------------------------------------------------------
class MovimientoDevolucionVentaForm(forms.ModelForm):
    stock_antes = forms.CharField(
        label="Stock antes", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control','readonly': 'readonly'})
    )
    stock_despues = forms.CharField(
        label="Stock después", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control','readonly': 'readonly'})
    )
    precio_venta_pond = forms.CharField(
        label="Precio venta ponderado", required=False,
        widget=forms.TextInput(attrs={'class': 'form-control','readonly': 'readonly'})
    )

    class Meta:
        model = MovimientoDevolucionVenta
        fields = [
            'venta',
            'referencia',
            'cantidad',
            'precio_venta_unitario',
            'fecha',
            'observaciones',
        ]
        widgets = {
            'venta': forms.Select(attrs={'class': 'form-control'}),
            'referencia': forms.Select(attrs={'class': 'form-control'}),
            'cantidad': forms.NumberInput(attrs={'class': 'form-control','step': '0.0001'}),
            'precio_venta_unitario': forms.NumberInput(attrs={'class': 'form-control','step': '0.01'}),
            'fecha': forms.DateInput(attrs={'type': 'date','class': 'form-control'}),
            'observaciones': forms.Textarea(attrs={'class': 'form-control','rows': 2}),
        }

    def clean_cantidad(self):
        q = self.cleaned_data.get('cantidad')
        if q is not None and q <= 0:
            raise ValidationError("La cantidad debe ser mayor que cero.")
        return q
class PerdidaProcesoForm(forms.ModelForm):
    class Meta:
        model = MovimientoPerdidaProceso
        fields = ['referencia', 'cantidad', 'motivo', 'observaciones']
        widgets = {
            'referencia': forms.Select(attrs={'id': 'id_referencia'}),
        }