"""
Base CXR Model Implementation

Provides base class for all CXR kernel model variants.
"""

from abc import ABC, abstractmethod
from typing import Dict, Optional, Any
import structlog

logger = structlog.get_logger(__name__)


class BaseCXRModel(ABC):
    """
    Base class for all CXR kernel models.
    
    All model variants should inherit from this class and implement:
    - _analyze_claim(): Core analysis logic
    - _get_fusion_engine(): Return appropriate fusion engine
    - _get_context_collector(): Return context collector (if needed)
    """
    
    def __init__(
        self,
        model_id: str,
        fusion_planes: int = 3,
        use_monte_carlo: bool = False,
        use_all_contexts: bool = True,
    ):
        """
        Initialize base model.
        
        Args:
            model_id: Unique identifier for this model
            fusion_planes: Number of evidence planes to use (3 or 7)
            use_monte_carlo: Whether to use Monte Carlo simulation
            use_all_contexts: Whether to use all 7 context types
        """
        self.model_id = model_id
        self.fusion_planes = fusion_planes
        self.use_monte_carlo = use_monte_carlo
        self.use_all_contexts = use_all_contexts
        self._db_conn = None
        self._qdrant_client = None
        
    def analyze(self, claim: Dict, tenant_id: str) -> Dict:
        """
        Public interface for claim analysis.
        
        Args:
            claim: Claim payload dictionary
            tenant_id: Tenant identifier
            
        Returns:
            Analysis result dictionary
        """
        logger.info(
            "model.analysis_start",
            model_id=self.model_id,
            claim_id=claim.get("claimId"),
            tenant_id=tenant_id,
        )
        
        try:
            result = self._analyze_claim(claim, tenant_id)
            
            logger.info(
                "model.analysis_complete",
                model_id=self.model_id,
                claim_id=claim.get("claimId"),
                verdict=result.get("verdict"),
            )
            
            return result
            
        except Exception as e:
            logger.error(
                "model.analysis_failed",
                model_id=self.model_id,
                claim_id=claim.get("claimId"),
                error=str(e),
            )
            raise
    
    @abstractmethod
    def _analyze_claim(self, claim: Dict, tenant_id: str) -> Dict:
        """
        Core analysis logic - must be implemented by subclasses.
        
        Returns:
            Dictionary with:
            - verdict: str
            - explanation: Dict
            - financialImpact: Dict
            - reportId: Optional[str]
        """
        pass
    
    def _get_db_connection(self):
        """Get database connection (lazy initialization)"""
        if self._db_conn is None:
            from .config import create_db_connection
            self._db_conn = create_db_connection()
        return self._db_conn
    
    def _get_qdrant_client(self):
        """Get Qdrant client (lazy initialization)"""
        if self._qdrant_client is None:
            from .config import create_qdrant_client
            self._qdrant_client = create_qdrant_client()
        return self._qdrant_client
    
    def _format_result(
        self,
        verdict: str,
        explanation: Dict[str, Any],
        financial_impact: Dict[str, Any],
        report_id: Optional[str] = None,
    ) -> Dict:
        """Format analysis result to standard structure"""
        return {
            "verdict": verdict,
            "explanation": explanation,
            "financialImpact": financial_impact,
            "reportId": report_id,
        }

