from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Count, Q
from django.http.response import HttpResponseBadRequest
from django.urls import reverse_lazy
from django.views.generic import FormView
from profiles.forms import BulkVisibilityForm, UserProfileForm
from scrobbles.constants import Visibility
from scrobbles.models import Scrobble
from tasks.todoist import generate_todoist_oauth_url


class ProfileFormView(LoginRequiredMixin, FormView):
    form_class = UserProfileForm
    template_name = "profiles/settings_form.html"
    success_url = reverse_lazy("profiles:profile_settings")

    def get_form_kwargs(self):
        """Passes the request object to the form class.
        This is necessary to only display members that belong to a given user"""

        kwargs = super(ProfileFormView, self).get_form_kwargs()
        kwargs["request"] = self.request

        return kwargs

    def form_valid(self, form):
        form.save()
        return super(ProfileFormView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["user_id"] = self.request.user.id
        context["profile"] = self.request.user.profile
        context["todoist_oauth_url"] = generate_todoist_oauth_url(self.request.user.id)
        return context


class BulkVisibilityView(LoginRequiredMixin, FormView):
    template_name = "profiles/visibility_settings.html"
    form_class = BulkVisibilityForm
    success_url = reverse_lazy("profiles:bulk_visibility")

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs["profile"] = self.request.user.profile
        return kwargs

    def form_valid(self, form):
        request = self.request
        profile = request.user.profile

        bulk_action = form.cleaned_data.get("bulk_action")
        if bulk_action:
            qs = Scrobble.objects.filter(
                user=request.user,
            ).exclude(visibility=Visibility.SHARED)
            total = qs.count()
            qs.update(visibility=bulk_action)
            messages.success(
                request,
                f"Updated {total} scrobble(s) to {bulk_action}.",
            )

        profile.media_type_visibility = form.cleaned_data["media_type_visibility"]
        profile.save(update_fields=["media_type_visibility"])
        messages.success(request, "Per-media-type visibility overrides saved.")
        return super().form_valid(form)

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        profile = self.request.user.profile
        qs = Scrobble.objects.filter(user=self.request.user)
        ctx["scrobble_count"] = qs.count()
        ctx["visibility_counts"] = qs.values("visibility").annotate(
            count=Count("id")
        )
        ctx["profile"] = profile
        return ctx
