"""
File Service — API Views.
"""
import logging

from django.http import FileResponse, Http404
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import FileReference, StoredFile
from .serializers import (
    FileReferenceSerializer,
    FileUploadSerializer,
    SignedURLSerializer,
    StoredFileDetailSerializer,
    StoredFileListSerializer,
)
from .services import FileStorageService

logger = logging.getLogger('apps')
file_service = FileStorageService()


class StoredFileViewSet(viewsets.ReadOnlyModelViewSet):
    """فایل‌های ذخیره‌شده — فقط خواندنی (آپلود از endpoint جدا)."""
    permission_classes = [IsAuthenticated]
    filterset_fields = ['status', 'mime_type', 'extension']
    search_fields = ['original_name']
    ordering_fields = ['created_at', 'size', 'original_name']
    ordering = ['-created_at']

    def get_queryset(self):
        return StoredFile.objects.filter(
            tenant=self.request.user.tenant,
        ).select_related('uploaded_by')

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return StoredFileDetailSerializer
        return StoredFileListSerializer

    @action(detail=True, methods=['post'])
    def signed_url(self, request, pk=None):
        """تولید URL امن موقت برای دانلود."""
        stored_file = self.get_object()
        expires_in = int(request.data.get('expires_in', 3600))
        url = file_service.generate_signed_url(stored_file, expires_in)
        return Response({
            'data': {'url': url, 'expires_in': expires_in}
        })

    @action(detail=True, methods=['post'], url_path='soft-delete')
    def soft_delete(self, request, pk=None):
        """حذف نرم فایل."""
        stored_file = self.get_object()
        file_service.soft_delete(stored_file)
        return Response({'data': {'message': 'فایل حذف شد.'}})


class FileReferenceViewSet(viewsets.ReadOnlyModelViewSet):
    """ارجاع‌های فایل — فقط خواندنی."""
    permission_classes = [IsAuthenticated]
    serializer_class = FileReferenceSerializer
    filterset_fields = ['context', 'context_id', 'is_active']
    ordering = ['-created_at']

    def get_queryset(self):
        return FileReference.objects.filter(
            tenant=self.request.user.tenant,
            is_active=True,
        ).select_related('stored_file')


class FileUploadView(APIView):
    """آپلود فایل جدید."""
    permission_classes = [IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser]

    def post(self, request):
        serializer = FileUploadSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        file_obj = serializer.validated_data['file']
        context = serializer.validated_data.get('context', '')
        context_id = serializer.validated_data.get('context_id')

        # بررسی محدودیت حجم (50MB)
        max_size = 50 * 1024 * 1024
        if file_obj.size > max_size:
            return Response(
                {'error': {'code': 'file_too_large', 'message': 'حداکثر حجم فایل ۵۰ مگابایت است.'}},
                status=status.HTTP_400_BAD_REQUEST,
            )

        stored_file = file_service.upload(
            tenant=request.user.tenant,
            user=request.user,
            file_obj=file_obj,
            context=context,
            context_id=context_id,
        )

        return Response(
            {'data': StoredFileDetailSerializer(stored_file).data},
            status=status.HTTP_201_CREATED,
        )


class FileDownloadView(APIView):
    """دانلود فایل با signed URL."""
    permission_classes = []  # اعتبارسنجی از طریق signature

    def get(self, request, file_id):
        ts = request.query_params.get('ts', '')
        sig = request.query_params.get('sig', '')

        if not file_service.verify_signed_url(file_id, ts, sig):
            return Response(
                {'error': {'code': 'invalid_signature', 'message': 'لینک نامعتبر یا منقضی شده.'}},
                status=status.HTTP_403_FORBIDDEN,
            )

        try:
            stored_file = StoredFile.objects.get(pk=file_id)
        except StoredFile.DoesNotExist:
            raise Http404

        file_path = file_service.get_download_path(stored_file)
        if not file_path or not file_path.exists():
            raise Http404

        response = FileResponse(
            open(file_path, 'rb'),
            content_type=stored_file.mime_type or 'application/octet-stream',
        )
        response['Content-Disposition'] = f'attachment; filename="{stored_file.original_name}"'
        return response
