from django import forms

from saleboxdjango.lib.shipping_options import SaleboxShippingOptions
from saleboxdjango.views.checkout.base import SaleboxCheckoutBaseView


class SaleboxCheckoutShippingMethodForm(forms.Form):
    shipping_method = forms.IntegerField()


class SaleboxCheckoutShippingMethodView(SaleboxCheckoutBaseView):
    shipping_options_class = SaleboxShippingOptions
    checkout_step = "shipping_method"
    form_class = SaleboxCheckoutShippingMethodForm
    template_name = "salebox/checkout/shipping_method.html"

    def get_additional_context_data(self, context):
        context = self._get_shipping_options(context)

        # print(context['shipping_options'])

        combined_price = None

        # use selected option if exists
        if self.sc.get_raw_data()["shipping_method"]["id"] is not None:
            for o in context["shipping_options"]:
                if o["id"] == self.sc.get_raw_data()["shipping_method"]["id"]:
                    combined_price = o["combined_price"]
                    break

        # no option selected, choice the default
        if combined_price is None:
            for o in context["shipping_options"]:
                if o["available"] and o["selected"]:
                    combined_price = o["combined_price"]
                    break

        # no option selected, no default, fallback to first available
        if combined_price is None:
            for o in context["shipping_options"]:
                if o["available"]:
                    combined_price = o["combined_price"]
                    break

        context["combined_shipping_price"] = combined_price
        return context

    def form_valid_pre_redirect(self, form):
        # retrieve selected option
        id = form.cleaned_data["shipping_method"]
        options = self._get_shipping_options()["shipping_options"]
        selected = next(o for o in options if o["id"] == id)

        # store in checkout
        self.sc.set_shipping_method(
            selected["id"],
            selected["code"],
            selected["label"],
            selected["price"],
            selected["meta"],
            self.request,
        )

        return True

    def _get_shipping_options(self, context={}):
        smc = self.shipping_options_class()
        return smc.go(self.request, self.sc.get_raw_data(), context)
