from unittest.mock import MagicMock
from datetime import datetime
from app.db import models

def test_add_document_success(client):
    test_client, mock_services = client
    mock_services.document_service.add_document.return_value = 123
    
    # Update the payload to include the default values from the Pydantic model
    doc_payload = {
        "title": "Test Doc", 
        "text": "Content here",
        "source_url": None,  # Add these based on your schema's defaults
        "author": None,
        "user_id": "default_user",
    }

    # The payload sent to the endpoint is just title and text
    request_payload = {"title": "Test Doc", "text": "Content here"}
    
    response = test_client.post("/documents", json=request_payload)
    
    assert response.status_code == 200
    assert response.json()["message"] == "Document 'Test Doc' added successfully with ID 123"
    
    # Assert against the full payload that the router will generate and pass to the service
    mock_services.document_service.add_document.assert_called_once_with(
        db=mock_services.document_service.add_document.call_args.kwargs['db'],
        doc_data=doc_payload
    )

def test_get_documents_success(client):
    test_client, mock_services = client
    
    # Ensure mock attributes are valid types for the schema
    mock_docs = [
        MagicMock(
            spec=models.Document, 
            id=1, 
            title="Doc One", 
            status="ready", 
            created_at=datetime.now(),
            source_url="http://example.com/doc1", # Explicitly set a string value
            text="text one",
            author="author one"
        ),
        MagicMock(
            spec=models.Document, 
            id=2, 
            title="Doc Two", 
            status="processing", 
            created_at=datetime.now(),
            source_url=None, # Or explicitly set to None if that's a valid case
            text="text two",
            author="author two"
        )
    ]
    
    mock_services.document_service.get_all_documents.return_value = mock_docs
    
    response = test_client.get("/documents")
    
    assert response.status_code == 200
    response_data = response.json()
    assert len(response_data["documents"]) == 2
    # You can also add more specific assertions
    assert response_data["documents"][0]["title"] == "Doc One"
    assert response_data["documents"][1]["status"] == "processing"
    
    mock_services.document_service.get_all_documents.assert_called_once()

def test_delete_document_success(client):
    """Tests the DELETE /documents/{document_id} endpoint for successful deletion."""
    test_client, mock_services = client
    mock_services.document_service.delete_document.return_value = 42
    response = test_client.delete("/documents/42")
    assert response.status_code == 200
    assert response.json()["document_id"] == 42
    mock_services.document_service.delete_document.assert_called_once_with(
        db=mock_services.document_service.delete_document.call_args.kwargs['db'],
        document_id=42
    )

def test_delete_document_not_found(client):
    """Tests the DELETE /documents/{document_id} endpoint when the document is not found."""
    test_client, mock_services = client
    mock_services.document_service.delete_document.return_value = None
    response = test_client.delete("/documents/999")
    assert response.status_code == 404
    mock_services.document_service.delete_document.assert_called_once_with(
        db=mock_services.document_service.delete_document.call_args.kwargs['db'],
        document_id=999
    )