import random

from django.contrib.auth.mixins import PermissionRequiredMixin, UserPassesTestMixin
from django.urls import reverse

from aircox import models, forms, permissions
from . import page
from .mixins import VueFormDataMixin


__all__ = (
    "ProgramDetailView",
    "ProgramDetailView",
    "ProgramCreateView",
    "ProgramUpdateView",
)


class ProgramDetailView(page.PageDetailView):
    model = models.Program

    def can_edit(self, obj):
        return permissions.program.can(self.request.user, "update", obj)

    def get_related_queryset(self):
        queryset = (
            self.get_queryset()
            .filter(category_id=self.object.category_id)
            .exclude(pk=self.object.pk)
            .published()
            .order_by("-pub_date")[:50]
        )
        return random.sample(list(queryset), min(len(queryset), self.related_count))

    def get_related_url(self):
        return reverse("program-list") + f"?category__id={self.object.category_id}"

    def get_context_data(self, **kwargs):
        episodes = models.Episode.objects.program(self.object).published().order_by("-pub_date")
        podcasts = episodes.with_podcasts()
        articles = models.Article.objects.parent(self.object).published().order_by("-pub_date")
        return super().get_context_data(
            articles=articles[: self.related_count],
            episodes=episodes[: self.related_count],
            podcasts=podcasts[: self.related_count],
            **kwargs,
        )

    def get_template_names(self):
        return super().get_template_names() + ["aircox/program_detail.html"]


@page.attach
class ProgramListView(page.PageListView):
    model = models.Program
    attach_to_value = models.StaticPage.Target.PROGRAMS

    def get_queryset(self):
        return super().get_queryset().order_by("title")


class ProgramEditMixin(VueFormDataMixin):
    model = models.Program
    form_class = forms.ProgramForm
    queryset = models.Program.objects.select_related("editors_group")


# FIXME: not used as long there is no complete administration mgt (schedule, etc.)
class ProgramCreateView(PermissionRequiredMixin, ProgramEditMixin, page.PageCreateView):
    permission_required = "aircox.add_program"


class ProgramUpdateView(UserPassesTestMixin, ProgramEditMixin, page.PageUpdateView):
    def can_edit(self, obj):
        return self.test_func()

    def test_func(self):
        obj = self.get_object()
        return permissions.program.can(self.request.user, "update", obj)
