from django import forms
from django.db import models

from oscar.apps.basket import forms as oscar
from oscar.core.loading import get_class, get_model

Product = get_model("catalogue", "Product")
AddToBasketFormMixin = get_class("basket.mixins", "AddToBasketFormMixin")
DataPriceMixin = get_class("basket.mixins", "DataPriceMixin")


def basket_product_quantity(basket, product):
    amount = (
        basket.all_lines()
        .filter(product=product)
        .aggregate(models.Sum("quantity"))["quantity__sum"]
    )
    return amount if amount is not None else 0


def minimum_product_quantity(product, basket=None):
    min_quantity = product.min_quantity

    if basket is None:
        return min_quantity

    basket_quantity = basket_product_quantity(basket, product)
    if basket_quantity < min_quantity:
        return min_quantity - basket_quantity
    else:
        return 1


class BasketLineForm(oscar.BasketLineForm):
    def __init__(self, strategy, *args, **kwargs):
        super(BasketLineForm, self).__init__(strategy, *args, **kwargs)
        min_product_quantity = minimum_product_quantity(self.instance.product)
        self.fields["quantity"].widget.attrs.update({"pattern": "\\d*"})
        if min_product_quantity > 1:
            self.fields["quantity"].widget.attrs.update({"min": min_product_quantity})


class AddToBasketForm(DataPriceMixin, AddToBasketFormMixin, oscar.AddToBasketForm):
    def __init__(self, basket, product, *args, **kwargs):
        super(AddToBasketForm, self).__init__(basket, product, *args, **kwargs)
        if "quantity" in self.fields:
            initial_quantity = minimum_product_quantity(
                self.parent_product, self.basket
            )
            self.fields["quantity"].initial = initial_quantity
            self.fields["quantity"].widget.attrs.update(
                {"min": initial_quantity, "pattern": "\\d*"}
            )


class SimpleAddToBasketForm(AddToBasketForm):
    def __init__(self, basket, product, *args, **kwargs):
        super(SimpleAddToBasketForm, self).__init__(basket, product, *args, **kwargs)
        if "quantity" in self.fields:
            initial_quantity = self.fields["quantity"].initial
            if initial_quantity == 1:
                self.fields["quantity"].widget = forms.HiddenInput()
