import logging
import typing as t

from dependency_injector.wiring import Provide, inject
from django.http import HttpRequest, HttpResponse
from django.views.generic import FormView, TemplateView

from ..containers import Container
from .forms import SubscriptionForm

if t.TYPE_CHECKING:
    from .repository import CivicrmRepositoryProtocol  # pragma: no cover

logger = logging.getLogger(__package__)


class SubscribedView(TemplateView):
    template_name = "subscribed.html.jinja"


class UnsubscriptionView(TemplateView):
    template_name = "unsubscribe.html.jinja"


class ResubscriptionView(TemplateView):
    template_name = "resubscribe.html.jinja"


class OptoutView(TemplateView):
    template_name = "optout.html.jinja"


class SubscriptionRequestedView(TemplateView):
    template_name = "subscription_requested.html.jinja"


class SubscriptionView(FormView):
    form_class = SubscriptionForm
    template_name = "subscribe.html.jinja"
    success_url = "/subscription-requested/"

    def get_context_data(self, **kwargs: t.Any) -> t.Dict[str, t.Any]:
        context = super().get_context_data(**kwargs)
        context.update({})
        return context  # type: ignore[no-any-return]

    @inject
    def form_valid(  # type: ignore
        self,
        form: SubscriptionForm,
        civi=Provide[Container.civi]
    ) -> t.Dict[str, t.Any]:
        civi.newsletter_signup_sync({
            "email_address": form.cleaned_data["email_address"],
        })
        return super().form_valid(form)  # type: ignore[no-any-return]


@inject
async def confirm_subscription(
    request: HttpRequest,
    civi: "CivicrmRepositoryProtocol" = Provide[Container.civi],
) -> HttpResponse:
    return await civi.confirm_subscription(request)


@inject
async def mailing_action(
    request: HttpRequest,
    civi: "CivicrmRepositoryProtocol" = Provide[Container.civi],
    action: str = ""
) -> HttpResponse:
    try:
        return await civi.mailing_action(request, action)
    except Exception as e:
        return HttpResponse({"error", str(e)}, status=400)
