from argparse import Namespace

from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import UserPassesTestMixin
from django.contrib.sites.shortcuts import get_current_site
from django.views.generic import DetailView

from oscar.core.loading import get_model

from ocyan.plugin.oscar.info import OSCAR_NEEDS_OXYAN

from ocyan.plugin.oscar_communications.order_extension.context import (
    EmailContext,
    OrderContext,
    ShippingContext,
)

if OSCAR_NEEDS_OXYAN:
    CommunicationEventType = get_model("communication", "CommunicationEventType")
else:
    CommunicationEventType = get_model("customer", "CommunicationEventType")

Product = get_model("catalogue", "Product")
Order = get_model("order", "Order")
User = get_user_model()


class PreView(UserPassesTestMixin, DetailView):
    template_name = "communications/email-preview.html"

    def test_func(self):
        return self.request.user.is_superuser

    def get_template_names(self):
        return [
            "communications/email-preview.%(extension)s" % self.kwargs,
            self.template_name,
        ]

    def get_ctx(self):
        return EmailContext(**self.request.GET.dict())

    def get_context_data(self, **kwargs):
        event_type = self.kwargs["event_type"]
        messages = CommunicationEventType(code=event_type).get_messages(self.get_ctx())
        kwargs.update(messages)
        return super().get_context_data(**kwargs)


class OrderEmailPreview(PreView):
    model = Order
    template_name = "communications/email-preview.html"
    slug_field = "number"

    def get_ctx(self):
        order = self.get_object()

        extra_context = self.request.GET.dict()

        if order.shipping_events.exists():
            ctx = ShippingContext(order.shipping_events.first(), **extra_context)
        else:
            ctx = OrderContext(order, **extra_context)

        return ctx


class UserEmailPreview(PreView):
    model = User
    slug_field = "username"

    def get_ctx(self):
        user = self.get_object()
        alert = Namespace(product=Product.objects.first(), user=user)
        extra_context = self.request.GET.dict()

        context = {
            "new_email": user.email,
            "email": user.email,
            "static_base_url": getattr(settings, "OSCAR_STATIC_BASE_URL", None),
        }

        context.update(extra_context)

        return EmailContext(
            user=user, alert=alert, site=get_current_site(self.request), **context
        )
