from django_filters import rest_framework as drf_filters
from rest_framework import status, viewsets, parsers, permissions
from rest_framework.decorators import action
from rest_framework.response import Response

from filer.models.imagemodels import Image

from . import models, forms, filters, serializers
from .views import BaseAPIView

__all__ = (
    "ImageViewSet",
    "SoundViewSet",
    "TrackROViewSet",
    "UserSettingsViewSet",
)


class ImageViewSet(viewsets.ModelViewSet):
    parsers = (parsers.MultiPartParser,)
    permissions = (permissions.IsAuthenticatedOrReadOnly,)
    serializer_class = serializers.admin.ImageSerializer
    queryset = Image.objects.all().order_by("-uploaded_at")
    filter_backends = (drf_filters.DjangoFilterBackend,)
    filterset_class = filters.ImageFilterSet

    def create(self, request, **kwargs):
        # FIXME: to be replaced by regular DRF
        form = forms.ImageForm(request.POST, request.FILES)
        if form.is_valid():
            file = form.cleaned_data["file"]
            Image.objects.create(original_filename=file.name, file=file)
            return Response({"status": "ok"})
        return Response({"status": "error", "errors": form.errors})


class SoundViewSet(BaseAPIView, viewsets.ModelViewSet):
    parsers = (parsers.MultiPartParser,)
    permissions = (permissions.IsAuthenticatedOrReadOnly,)
    serializer_class = serializers.SoundSerializer
    queryset = models.Sound.objects.order_by("-pk")
    filter_backends = (drf_filters.DjangoFilterBackend,)
    filterset_class = filters.SoundFilterSet

    def perform_create(self, serializer):
        obj = serializer.save()
        # FIXME: hack to avoid "TYPE_REMOVED" status
        # -> file is saved to fs after object is saved to db
        obj.save()

    def get_queryset(self):
        query = super().get_queryset()
        if not self.request.user.is_authenticated:
            return query.available()
        return query


class TrackROViewSet(viewsets.ReadOnlyModelViewSet):
    """Track viewset used for auto completion."""

    serializer_class = serializers.admin.TrackSerializer
    permission_classes = (permissions.IsAuthenticated,)
    filter_backends = (drf_filters.DjangoFilterBackend,)
    filterset_class = filters.TrackFilterSet
    queryset = models.Track.objects.all()

    @action(name="autocomplete", detail=False)
    def autocomplete(self, request):
        field = request.GET.get("field", None)
        if field:
            queryset = self.filter_queryset(self.get_queryset())
            values = queryset.values_list(field, flat=True).distinct()
            return Response(values[:10])
        return self.list(request)


# --- admin
class UserSettingsViewSet(viewsets.ViewSet):
    """User's settings specific to aircox.

    Allow only to create and edit user's own settings.
    """

    serializer_class = serializers.admin.UserSettingsSerializer
    permission_classes = (permissions.IsAuthenticated,)

    def get_serializer(self, instance=None, **kwargs):
        return self.serializer_class(instance=instance, context={"user": self.request.user}, **kwargs)

    @action(detail=False, methods=["GET"])
    def retrieve(self, request):
        user = self.request.user
        settings = getattr(user, "aircox_settings", None)
        data = settings and self.get_serializer(settings) or None
        return Response(data)

    @action(detail=False, methods=["POST", "PUT"])
    def update(self, request):
        user = self.request.user
        settings = getattr(user, "aircox_settings", None)
        data = dict(request.data)
        data["user_id"] = self.request.user
        serializer = self.get_serializer(instance=settings, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"status": "ok"})
        else:
            return Response(
                {"errors": serializer.errors},
                status=status.HTTP_400_BAD_REQUEST,
            )
