"""This module contains the apiv2 related views for the ``media`` app"""

from django.shortcuts import get_object_or_404
from django.utils.functional import cached_property

from rest_framework import filters, viewsets

from mtp.apps.api.permissions import IsAuthenticated

from ..models import (
    Note,
    Presentation,
    Video,
)

from .serializers import (
    NoteSerializer,
    PresentationSerializer,
    VideoSerializer,
)


class PresentationViewSet(viewsets.ReadOnlyModelViewSet):
    """ViewSet for the ``Presentation`` model"""

    permission_classes = [IsAuthenticated]
    serializer_class = PresentationSerializer
    queryset = Presentation.objects.non_deleted()


class VideoViewSet(viewsets.ReadOnlyModelViewSet):
    """ViewSet for the ``Video`` model"""

    permission_classes = [IsAuthenticated]
    serializer_class = VideoSerializer
    queryset = Video.objects.non_deleted()


class BaseNoteViewSet(viewsets.ModelViewSet):
    """Base ViewSet for the ``Note`` model"""

    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = (
        'training_session',
    )
    permission_classes = [IsAuthenticated]
    serializer_class = NoteSerializer

    def get_queryset(self):
        """Filter the notes the user can see

        Returns
        -------
        NoteQuerySet

        """

        return Note.objects.filter(user=self.request.user)


class FreeNoteViewSet(BaseNoteViewSet):
    """ViewSet for the ``Note``model  not linked to a ``Presentation``"""

    def get_queryset(self):
        """Exclude the notes linked to a ``Presentation``

        Returns
        -------
        NoteQuerySet

        """

        return super().get_queryset().without_presentation()


class PresentationNoteViewSet(BaseNoteViewSet):
    """ViewSet for the ``Note``model linked to given ``Presentation``"""

    @cached_property
    def presentation(self):
        """Get the presentation from the url parameter

        Returns
        -------
        presentation: Presentation

        Raises
        ------
        Http404
            If the presentation cannot be found

        """

        return get_object_or_404(
            Presentation.objects.non_deleted(),
            id=self.kwargs['presentation_uuid']
        )

    def get_queryset(self):
        """Exclude the notes linked to a ``Presentation``

        Returns
        -------
        NoteQuerySet

        """

        return super().get_queryset().for_presentation(self.presentation)
