"""
File Service — API Tests.

تست‌های REST API سرویس فایل.
"""
import uuid

import pytest
from rest_framework import status

from apps.services.file_service.models import (
    FileReference,
    FileStatus,
    StoredFile,
)


# ══════════════════════════════════════════════════════════════
# StoredFile API
# ══════════════════════════════════════════════════════════════

@pytest.mark.django_db
class TestStoredFileAPI:
    """Tests for stored file endpoints (read-only)."""

    def test_list_stored_files_unauthenticated(self, api_client):
        """Unauthenticated users get 401."""
        response = api_client.get(
            '/api/v1/files/stored-files/', HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_list_stored_files(self, authenticated_client, stored_file):
        """Authenticated user can list stored files."""
        response = authenticated_client.get(
            '/api/v1/files/stored-files/', HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_200_OK

    def test_retrieve_stored_file(self, authenticated_client, stored_file):
        """Get detail of a stored file."""
        response = authenticated_client.get(
            f'/api/v1/files/stored-files/{stored_file.id}/',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_200_OK

    def test_signed_url(self, authenticated_client, stored_file):
        """Generate a signed URL for download."""
        response = authenticated_client.post(
            f'/api/v1/files/stored-files/{stored_file.id}/signed_url/',
            data={'expires_in': 3600},
            format='json',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_200_OK
        data = response.data.get('data', response.data)
        assert 'url' in data
        assert 'expires_in' in data

    def test_soft_delete_file(self, authenticated_client, stored_file):
        """Soft-delete a stored file."""
        response = authenticated_client.post(
            f'/api/v1/files/stored-files/{stored_file.id}/soft-delete/',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_200_OK
        stored_file.refresh_from_db()
        assert stored_file.status == FileStatus.DELETED


# ══════════════════════════════════════════════════════════════
# FileReference API
# ══════════════════════════════════════════════════════════════

@pytest.mark.django_db
class TestFileReferenceAPI:
    """Tests for file reference endpoints (read-only)."""

    def test_list_references(self, authenticated_client, file_reference):
        """List active file references."""
        response = authenticated_client.get(
            '/api/v1/files/references/', HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_200_OK

    def test_retrieve_reference(self, authenticated_client, file_reference):
        """Get detail of a file reference."""
        response = authenticated_client.get(
            f'/api/v1/files/references/{file_reference.id}/',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_200_OK


# ══════════════════════════════════════════════════════════════
# Upload API
# ══════════════════════════════════════════════════════════════

@pytest.mark.django_db
class TestFileUploadAPI:
    """Tests for file upload endpoint."""

    def test_upload_unauthenticated(self, api_client, sample_file):
        """Unauthenticated users cannot upload."""
        response = api_client.post(
            '/api/v1/files/upload/',
            data={'file': sample_file},
            format='multipart',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_upload_file(self, authenticated_client, sample_file):
        """Upload a valid file."""
        response = authenticated_client.post(
            '/api/v1/files/upload/',
            data={'file': sample_file},
            format='multipart',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_201_CREATED
        data = response.data.get('data', response.data)
        assert data['original_name'] == 'test-file.txt'

    def test_upload_file_with_context(self, authenticated_client, sample_file):
        """Upload with context info."""
        response = authenticated_client.post(
            '/api/v1/files/upload/',
            data={
                'file': sample_file,
                'context': 'chat',
                'context_id': str(uuid.uuid4()),
            },
            format='multipart',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_201_CREATED

    def test_upload_no_file_fails(self, authenticated_client):
        """Upload without file raises validation error."""
        response = authenticated_client.post(
            '/api/v1/files/upload/',
            data={},
            format='multipart',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_400_BAD_REQUEST


# ══════════════════════════════════════════════════════════════
# Download API
# ══════════════════════════════════════════════════════════════

@pytest.mark.django_db
class TestFileDownloadAPI:
    """Tests for file download endpoint (signed URL)."""

    def test_download_invalid_signature(self, api_client, stored_file):
        """Invalid signature returns 403."""
        response = api_client.get(
            f'/api/v1/files/{stored_file.id}/download/',
            {'ts': '9999999999', 'sig': 'invalid'},
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_403_FORBIDDEN

    def test_download_missing_params(self, api_client, stored_file):
        """Missing signature params returns 403."""
        response = api_client.get(
            f'/api/v1/files/{stored_file.id}/download/',
            HTTP_HOST='localhost',
        )
        assert response.status_code == status.HTTP_403_FORBIDDEN
