"""
Tests for Document Category API Endpoints.

TDD tests for category filtering and management in document endpoints.
"""

import pytest
from datetime import datetime
from unittest.mock import MagicMock, patch
from uuid import UUID, uuid4

from fastapi import FastAPI
from fastapi.testclient import TestClient


# Test constants
TEST_DOC_UUID = "550e8400-e29b-41d4-a716-446655440000"
TEST_TOKEN = "test-admin-token-12345"


class TestGetCategoriesEndpoint:
    """Tests for GET /admin/documents/categories endpoint."""

    def test_categories_endpoint_returns_list(self):
        """Test categories endpoint returns list of available categories."""
        from backend.web.schemas.admin import DocumentCategoriesResponse

        # Test schema exists and works
        response = DocumentCategoriesResponse(
            categories=["invoice", "letter", "receipt"],
            total=3,
        )
        assert response.categories == ["invoice", "letter", "receipt"]
        assert response.total == 3

    def test_categories_response_schema(self):
        """Test DocumentCategoriesResponse schema structure."""
        from backend.web.schemas.admin import DocumentCategoriesResponse

        assert "categories" in DocumentCategoriesResponse.model_fields
        assert "total" in DocumentCategoriesResponse.model_fields


class TestDocumentListFilterByCategory:
    """Tests for filtering documents by category."""

    @pytest.fixture
    def mock_document_repo(self):
        """Create mock DocumentRepository."""
        repo = MagicMock()
        repo.is_valid.return_value = True

        # Mock documents with different categories
        invoice_doc = MagicMock()
        invoice_doc.document_id = uuid4()
        invoice_doc.category = "invoice"
        invoice_doc.filename = "invoice1.pdf"

        letter_doc = MagicMock()
        letter_doc.document_id = uuid4()
        letter_doc.category = "letter"
        letter_doc.filename = "letter1.pdf"

        repo.get_paginated.return_value = ([invoice_doc], 1)
        repo.get_categories.return_value = ["invoice", "letter", "receipt"]
        return repo

    def test_list_documents_accepts_category_filter(self, mock_document_repo):
        """Test list documents endpoint accepts category query parameter."""
        # The endpoint should accept ?category=invoice parameter
        # This test verifies the schema/query parameter exists
        from backend.web.schemas.admin import DocumentListResponse

        # Schema should work with category filter applied
        assert DocumentListResponse is not None

    def test_get_document_categories_from_repo(self, mock_document_repo):
        """Test fetching unique categories from repository."""
        categories = mock_document_repo.get_categories()
        assert "invoice" in categories
        assert "letter" in categories
        assert len(categories) == 3


class TestDocumentUploadWithCategory:
    """Tests for uploading documents with category."""

    def test_upload_request_accepts_category(self):
        """Test upload request can include category field."""
        # When uploading via form data, category should be accepted
        # This is typically a form field, not a schema
        pass

    def test_upload_response_includes_category(self):
        """Test upload response includes the category that was set."""
        from backend.web.schemas.admin import DocumentUploadResponse

        response = DocumentUploadResponse(
            document_id=TEST_DOC_UUID,
            filename="test.pdf",
            file_size=1024,
            page_count=1,
            status="pending",
            category="letter",  # Custom category
            message="Upload successful",
        )
        assert response.category == "letter"

    def test_upload_defaults_to_invoice_category(self):
        """Test upload defaults to 'invoice' if no category specified."""
        from backend.web.schemas.admin import DocumentUploadResponse

        response = DocumentUploadResponse(
            document_id=TEST_DOC_UUID,
            filename="test.pdf",
            file_size=1024,
            page_count=1,
            status="pending",
            message="Upload successful",
            # No category specified - should default to "invoice"
        )
        assert response.category == "invoice"


class TestDocumentRepositoryCategoryMethods:
    """Tests for DocumentRepository category-related methods."""

    def test_get_categories_method_exists(self):
        """Test DocumentRepository has get_categories method."""
        from backend.data.repositories import DocumentRepository

        repo = DocumentRepository()
        assert hasattr(repo, "get_categories")

    def test_get_paginated_accepts_category_filter(self):
        """Test get_paginated method accepts category parameter."""
        from backend.data.repositories import DocumentRepository
        import inspect

        repo = DocumentRepository()
        # Check the method exists and accepts category parameter
        method = getattr(repo, "get_paginated", None)
        assert callable(method)

        # Check category is in the method signature
        sig = inspect.signature(method)
        assert "category" in sig.parameters


class TestUpdateDocumentCategory:
    """Tests for updating document category."""

    def test_update_category_method_exists(self):
        """Test DocumentRepository has method to update document category."""
        from backend.data.repositories import DocumentRepository

        repo = DocumentRepository()
        assert hasattr(repo, "update_category")

    def test_update_request_schema(self):
        """Test DocumentUpdateRequest can update category."""
        from backend.web.schemas.admin import DocumentUpdateRequest

        request = DocumentUpdateRequest(category="receipt")
        assert request.category == "receipt"
