from django import forms
from .models import (
    Customer,
    Invoice,
    InvoiceItem,
    InvoicePayment,
    Sale,
    SaleItem,
    SalesReturn,
    SalesReturnItem,
)
from inventory.models import Product
from finance.models import Account


class SaleForm(forms.ModelForm):
    class Meta:
        model = Sale
        fields = [
            'customer', 'customer_name', 'date', 'payment_method',
            'account', 'discount', 'note'
        ]
        widgets = {
            'date': forms.DateInput(attrs={'type': 'date'}),
            'note': forms.Textarea(attrs={'rows': 2}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['account'].queryset = Account.objects.filter(is_active=True)
        self.fields['account'].required = False
        self.fields['customer'].queryset = Customer.objects.filter(is_active=True)
        self.fields['customer'].required = False


class SaleItemForm(forms.ModelForm):
    class Meta:
        model = SaleItem
        fields = ['product', 'quantity', 'unit_price']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['product'].queryset = Product.objects.filter(
            is_active=True, stock_quantity__gt=0
        )

    def clean(self):
        cleaned_data = super().clean()
        product = cleaned_data.get('product')
        quantity = cleaned_data.get('quantity')
        if product and quantity:
            if quantity > product.stock_quantity:
                raise forms.ValidationError(
                    f'Only {product.stock_quantity} {product.unit}(s) available for {product.name}.'
                )
        return cleaned_data


# Inline formset — multiple items in one sale
SaleItemFormSet = forms.inlineformset_factory(
    Sale, SaleItem,
    form=SaleItemForm,
    extra=3,
    min_num=1,
    validate_min=True,
    can_delete=True,
)

from .models import Invoice, InvoiceItem, InvoicePayment


class InvoiceForm(forms.ModelForm):
    class Meta:
        model = Invoice
        fields = [
            'customer', 'customer_name', 'customer_phone', 'customer_email',
            'customer_address', 'issue_date', 'due_date',
            'discount', 'note'
        ]
        widgets = {
            'issue_date': forms.DateInput(attrs={'type': 'date'}),
            'due_date': forms.DateInput(attrs={'type': 'date'}),
            'customer_address': forms.Textarea(attrs={'rows': 2}),
            'note': forms.Textarea(attrs={'rows': 2}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['customer'].queryset = Customer.objects.filter(is_active=True)
        self.fields['customer'].required = False


class InvoiceItemForm(forms.ModelForm):
    class Meta:
        model = InvoiceItem
        fields = ['product', 'description', 'quantity', 'unit_price']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['product'].required = False
        self.fields['product'].queryset = Product.objects.filter(is_active=True)

    def clean(self):
        cleaned_data = super().clean()
        product = cleaned_data.get('product')
        description = cleaned_data.get('description')
        if not product and not description:
            raise forms.ValidationError('Provide a product or description.')
        # Auto fill description from product
        if product and not description:
            cleaned_data['description'] = product.name
        return cleaned_data


InvoiceItemFormSet = forms.inlineformset_factory(
    Invoice, InvoiceItem,
    form=InvoiceItemForm,
    extra=3,
    min_num=1,
    validate_min=True,
    can_delete=True,
)


class InvoicePaymentForm(forms.ModelForm):
    class Meta:
        model = InvoicePayment
        fields = ['account', 'amount', 'payment_method', 'date', 'note']
        widgets = {
            'date': forms.DateInput(attrs={'type': 'date'}),
        }

    def __init__(self, *args, invoice=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.invoice = invoice
        self.fields['account'].queryset = Account.objects.filter(is_active=True)

    def clean_amount(self):
        amount = self.cleaned_data.get('amount')
        if self.invoice and amount > self.invoice.balance_due:
            raise forms.ValidationError(
                f'Amount exceeds balance due of {self.invoice.balance_due}.'
            )
        if amount <= 0:
            raise forms.ValidationError('Amount must be greater than zero.')
        return amount


class CustomerForm(forms.ModelForm):
    class Meta:
        model = Customer
        fields = ['name', 'phone', 'email', 'address', 'is_active']
        widgets = {
            'address': forms.Textarea(attrs={'rows': 2}),
        }


class SalesReturnForm(forms.ModelForm):
    class Meta:
        model = SalesReturn
        fields = ['sale', 'date', 'reason']
        widgets = {
            'date': forms.DateInput(attrs={'type': 'date'}),
            'reason': forms.Textarea(attrs={'rows': 2}),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['sale'].queryset = Sale.objects.filter(status=Sale.Status.COMPLETED)


class SalesReturnItemForm(forms.ModelForm):
    class Meta:
        model = SalesReturnItem
        fields = ['product', 'quantity', 'unit_price']


SalesReturnItemFormSet = forms.inlineformset_factory(
    SalesReturn,
    SalesReturnItem,
    form=SalesReturnItemForm,
    extra=2,
    min_num=1,
    validate_min=True,
    can_delete=True,
)
