"""
Tests for Base CXR Model
"""

import pytest
from unittest.mock import Mock, patch
from kernel_service.base_model import BaseCXRModel
from kernel_service.registry import ModelCapabilities


class ConcreteModel(BaseCXRModel):
    """Concrete implementation for testing"""
    
    def __init__(self):
        super().__init__(
            model_id="test-model",
            fusion_planes=7,
            use_monte_carlo=False,
            use_all_contexts=True,
        )
    
    def _analyze_claim(self, claim, tenant_id):
        """Test implementation"""
        return self._format_result(
            verdict="approved",
            explanation={"summary": "Test"},
            financial_impact={"projectedRecovery": 0.0, "currency": "USD"},
        )


class TestBaseCXRModel:
    """Test base model functionality"""

    def test_base_model_initialization(self):
        """Test base model initializes with correct parameters"""
        model = ConcreteModel()
        assert model.model_id == "test-model"
        assert model.fusion_planes == 7
        assert model.use_monte_carlo is False
        assert model.use_all_contexts is True

    def test_analyze_interface(self):
        """Test analyze() method exists and accepts claim/tenant_id"""
        model = ConcreteModel()
        claim = {"claimId": "TEST-001"}
        result = model.analyze(claim, tenant_id="tenant-123")
        
        assert isinstance(result, dict)
        assert "verdict" in result
        assert "explanation" in result
        assert "financialImpact" in result

    def test_analyze_calls_internal(self):
        """Test analyze() calls _analyze_claim() internally"""
        model = ConcreteModel()
        claim = {"claimId": "TEST-001"}
        
        with patch.object(model, '_analyze_claim') as mock_analyze:
            mock_analyze.return_value = {
                "verdict": "approved",
                "explanation": {},
                "financialImpact": {},
            }
            model.analyze(claim, tenant_id="tenant-123")
            mock_analyze.assert_called_once_with(claim, "tenant-123")

    def test_analyze_logging(self, capsys):
        """Test analyze() logs start and completion"""
        model = ConcreteModel()
        claim = {"claimId": "TEST-001"}
        model.analyze(claim, tenant_id="tenant-123")
        
        # structlog outputs to stdout, check captured output
        captured = capsys.readouterr()
        assert "model.analysis_start" in captured.out
        assert "model.analysis_complete" in captured.out

    def test_analyze_error_handling(self):
        """Test analyze() handles exceptions gracefully"""
        class FailingModel(BaseCXRModel):
            def __init__(self):
                super().__init__("fail", 3, False, False)
            
            def _analyze_claim(self, claim, tenant_id):
                raise ValueError("Test error")
        
        model = FailingModel()
        claim = {"claimId": "TEST-001"}
        
        with pytest.raises(ValueError, match="Test error"):
            model.analyze(claim, tenant_id="tenant-123")

    def test_format_result(self):
        """Test format_result() formats correctly"""
        model = ConcreteModel()
        result = model._format_result(
            verdict="denied",
            explanation={"summary": "Test explanation"},
            financial_impact={"projectedRecovery": 100.0, "currency": "USD"},
            report_id="rpt-123",
        )
        
        assert result["verdict"] == "denied"
        assert result["explanation"]["summary"] == "Test explanation"
        assert result["financialImpact"]["projectedRecovery"] == 100.0
        assert result["reportId"] == "rpt-123"

    def test_db_connection_lazy(self):
        """Test database connection is lazy-loaded"""
        model = ConcreteModel()
        assert model._db_conn is None
        
        # Accessing _get_db_connection should raise NotImplementedError
        # (since we haven't configured it)
        with pytest.raises(NotImplementedError):
            model._get_db_connection()

    def test_qdrant_client_lazy(self):
        """Test Qdrant client is lazy-loaded"""
        model = ConcreteModel()
        assert model._qdrant_client is None
        
        # Accessing _get_qdrant_client should raise NotImplementedError
        # (either because qdrant-client not installed or not configured)
        with pytest.raises(NotImplementedError):
            model._get_qdrant_client()

