from django import forms
from django.forms import inlineformset_factory
from .models import Brand, ProductCategory, ProductSize, Supplier, Product, Purchase, PurchaseItem


class BrandForm(forms.ModelForm):
    class Meta:
        model = Brand
        fields = ["name", "is_active"]
        widgets = {
            "name": forms.TextInput(attrs={"class": "form-control", "placeholder": "Brand name"}),
            "is_active": forms.CheckboxInput(attrs={"class": "form-check-input"}),
        }


class ProductCategoryForm(forms.ModelForm):
    class Meta:
        model = ProductCategory
        fields = ["name", "is_active"]
        widgets = {
            "name": forms.TextInput(attrs={"class": "form-control", "placeholder": "Category name"}),
            "is_active": forms.CheckboxInput(attrs={"class": "form-check-input"}),
        }


class ProductSizeForm(forms.ModelForm):
    class Meta:
        model = ProductSize
        fields = ["name"]
        widgets = {
            "name": forms.TextInput(attrs={"class": "form-control", "placeholder": "e.g. 1kg, 500ml, XL"}),
        }


class SupplierForm(forms.ModelForm):
    class Meta:
        model = Supplier
        fields = ["name", "phone", "email", "address", "is_active"]
        widgets = {
            "name": forms.TextInput(attrs={"class": "form-control"}),
            "phone": forms.TextInput(attrs={"class": "form-control"}),
            "email": forms.EmailInput(attrs={"class": "form-control"}),
            "address": forms.Textarea(attrs={"class": "form-control", "rows": 2}),
            "is_active": forms.CheckboxInput(attrs={"class": "form-check-input"}),
        }


class ProductForm(forms.ModelForm):
    """Product catalogue entry.

    Products are company-wide; stock is held per branch. ``stock_qty`` is the
    opening stock (create) or the stock of one branch (update) - it is NOT a
    model field, the view writes it through ``inventory.stock``.
    """
    stock_qty = forms.IntegerField(
        label="Opening Stock", min_value=0, initial=0,
        widget=forms.NumberInput(attrs={"class": "form-control", "step": "1", "min": "0", "inputmode": "numeric", "pattern": "[0-9]*"}),
    )
    # Stock quantities are whole units only.
    min_stock_alert = forms.IntegerField(
        min_value=0,
        widget=forms.NumberInput(attrs={"class": "form-control", "step": "1", "min": "0", "inputmode": "numeric", "pattern": "[0-9]*"}),
    )

    class Meta:
        model = Product
        fields = ["brand", "category", "size", "name", "sku", "buy_price", "sell_price",
                  "min_stock_alert", "is_active"]
        widgets = {
            "brand": forms.Select(attrs={"class": "form-control"}),
            "category": forms.Select(attrs={"class": "form-control"}),
            "size": forms.Select(attrs={"class": "form-control"}),
            "name": forms.TextInput(attrs={"class": "form-control"}),
            "sku": forms.TextInput(attrs={"class": "form-control"}),
            "buy_price": forms.NumberInput(attrs={"class": "form-control", "step": "0.01", "min": "0"}),
            "sell_price": forms.NumberInput(attrs={"class": "form-control", "step": "0.01", "min": "0"}),
            "is_active": forms.CheckboxInput(attrs={"class": "form-check-input"}),
        }

    def __init__(self, *args, company=None, branches=None, stock_branch=None, stock_initial=None, **kwargs):
        """
        branches      - active branches of the company (create mode shows a picker when > 1)
        stock_branch  - update mode: the branch whose stock this form edits (None = cannot edit)
        stock_initial - update mode: that branch's current quantity
        """
        super().__init__(*args, **kwargs)
        creating = self.instance.pk is None
        if company is not None:
            self.fields["brand"].queryset = Brand.objects.filter(company=company, is_active=True)
            self.fields["category"].queryset = ProductCategory.objects.filter(company=company, is_active=True)
            self.fields["size"].queryset = ProductSize.objects.filter(company=company)

        if creating:
            if branches and len(branches) > 1:
                self.fields["opening_branch"] = forms.ChoiceField(
                    label="Opening stock branch",
                    choices=[(str(b.pk), b.name) for b in branches],
                    initial=str((stock_branch or branches[0]).pk),
                    widget=forms.Select(attrs={"class": "form-control"}),
                )
        else:
            if stock_branch is not None:
                self.fields["stock_qty"].label = f"Stock in {stock_branch.name}"
                self.fields["stock_qty"].initial = int(stock_initial or 0)
                self.initial["stock_qty"] = int(stock_initial or 0)
            else:
                del self.fields["stock_qty"]


class PurchaseForm(forms.ModelForm):
    def __init__(self, *args, company=None, **kwargs):
        super().__init__(*args, **kwargs)
        if company is not None:
            self.fields["supplier"].queryset = Supplier.objects.filter(
                company=company, is_active=True
            )

    class Meta:
        model = Purchase
        fields = ["supplier", "invoice_number", "date", "discount", "notes"]
        widgets = {
            "supplier": forms.Select(attrs={"class": "form-control"}),
            "invoice_number": forms.TextInput(attrs={"class": "form-control", "readonly": True}),
            "date": forms.DateInput(attrs={"class": "form-control", "type": "date"}),
            "discount": forms.NumberInput(attrs={"class": "form-control", "step": "0.01", "value": "0"}),
            "notes": forms.Textarea(attrs={"class": "form-control", "rows": 2}),
        }


class PurchaseItemForm(forms.ModelForm):
    # Purchase quantities are whole units only.
    quantity = forms.IntegerField(
        min_value=1,
        widget=forms.NumberInput(attrs={"class": "form-control", "step": "1", "min": "1", "inputmode": "numeric", "pattern": "[0-9]*"})
    )

    class Meta:
        model = PurchaseItem
        fields = ["product", "quantity", "buy_price"]
        widgets = {
            "product": forms.Select(attrs={"class": "form-control"}),
            "buy_price": forms.NumberInput(attrs={"class": "form-control", "step": "0.01", "min": "0"}),
        }


PurchaseItemFormSet = inlineformset_factory(
    Purchase, PurchaseItem, form=PurchaseItemForm, extra=2, can_delete=True
)
