from django.shortcuts import get_object_or_404
from django.http import FileResponse, Http404
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.settings import api_settings
from .models import Paper, PaperAbstract
from .serializers import PaperListSerializer
from .filters import PaperFilterSet
from apps.utils.viewsets import CustomGenericViewSet, CustomListModelMixin
from apps.utils.mixins import CustomRetrieveModelMixin
from apps.utils.apikey_auth import ApiKeyAuthentication, HasApiKey
import os


@api_view(['GET'])
@authentication_classes([ApiKeyAuthentication] + api_settings.DEFAULT_AUTHENTICATION_CLASSES)
@permission_classes([HasApiKey | IsAuthenticated])
def paper_pdf_view(request, pk):
    paper = get_object_or_404(Paper, pk=pk)
    if not paper.has_fulltext_pdf:
        raise Http404("PDF not available")
    pdf_path = paper.init_paper_path("pdf")
    if not os.path.isfile(pdf_path):
        raise Http404("PDF file not found on disk")
    safe_doi = paper.doi.replace("/", "_")
    response = FileResponse(
        open(pdf_path, 'rb'),
        content_type='application/pdf',
    )
    response['Content-Disposition'] = f'inline; filename="{safe_doi}.pdf"'
    return response


paper_pdf_view.cls.swagger_schema = None


# Create your views here.
class PaperViewSet(CustomGenericViewSet, CustomListModelMixin, CustomRetrieveModelMixin):
    queryset = Paper.objects.select_related("abstract").all()
    serializer_class = PaperListSerializer
    filterset_class = PaperFilterSet
    search_fields = ['title', 'first_author', 'first_author_institution']
    ordering = ["-publication_date", "-create_time"]

    def get_authenticators(self):
        authenticators = super().get_authenticators()
        if self.request.method == 'GET':
            return [ApiKeyAuthentication()] + authenticators
        return authenticators

    def get_permissions(self):
        if self.request.method == 'GET':
            return [(HasApiKey | IsAuthenticated)()]
        return super().get_permissions()
