from fastapi.testclient import TestClient
from unittest.mock import patch, MagicMock
from app.main import app
from app.services.set_label_service import SetLabelService
from sqlalchemy.orm import Session
from app.db.database import get_db
import asyncio

client = TestClient(app)

def test_generate_set_labels_success():
    # Mock the SetLabelService
    with patch('app.routes.set_label_routes.set_label_service') as mock_service:
        # Setup mock
        mock_service.generate_labels.return_value = asyncio.Future()
        mock_service.generate_labels.return_value.set_result([
            "app/data/cache/set_labels/MH1.pdf",
            "app/data/cache/set_labels/NEO.pdf"
        ])
        
        # Make request
        response = client.post("/api/set-labels/generate", json={"sets": ["MH1", "NEO"]})
        
        # Assert response
        assert response.status_code == 200
        assert response.json() == {
            "message": "Labels generated successfully",
            "files": [
                "app/data/cache/set_labels/MH1.pdf",
                "app/data/cache/set_labels/NEO.pdf"
            ]
        }
        
        # Verify service was called correctly
        mock_service.generate_labels.assert_called_once_with(["MH1", "NEO"])

def test_generate_set_labels_error():
    # Mock the SetLabelService to raise an exception
    with patch('app.routes.set_label_routes.set_label_service') as mock_service:
        mock_service.generate_labels.side_effect = Exception("Test error")
        
        # Make request
        response = client.post("/api/set-labels/generate", json={"sets": ["MH1", "NEO"]})
        
        # Assert response
        assert response.status_code == 500
        assert response.json() == {"detail": "Test error"}

def test_get_available_sets_success():
    # Mock the database session and SetLabelService
    with patch('app.routes.set_label_routes.set_label_service') as mock_service, \
         patch('app.db.database.get_db') as mock_get_db:
        # Setup mock database session
        mock_db = MagicMock(spec=Session)
        mock_get_db.return_value = mock_db
        
        # Setup mock service
        mock_sets = [
            {"code": "MH1", "name": "Modern Horizons"},
            {"code": "NEO", "name": "Kamigawa: Neon Dynasty"}
        ]
        mock_service.get_available_sets.return_value = asyncio.Future()
        mock_service.get_available_sets.return_value.set_result(mock_sets)
        
        # Override the dependency injection
        app.dependency_overrides[get_db] = lambda: mock_db
        
        try:
            # Make request
            response = client.get("/api/set-labels/available-sets")
            
            # Assert response
            assert response.status_code == 200
            assert response.json() == {
                "message": "Available sets retrieved successfully",
                "sets": mock_sets
            }
            
            # Verify service was called correctly
            mock_service.get_available_sets.assert_called_once_with(mock_db)
        finally:
            # Clean up dependency override
            app.dependency_overrides.clear()

def test_get_available_sets_error():
    # Mock the SetLabelService to raise an exception
    with patch('app.routes.set_label_routes.set_label_service') as mock_service:
        mock_service.get_available_sets.side_effect = Exception("Test error")
        
        # Make request
        response = client.get("/api/set-labels/available-sets")
        
        # Assert response
        assert response.status_code == 500
        assert response.json() == {"detail": "Test error"} 