"""Backward compatibility layer for v2 schema migration.

Provides methods to convert between v1 and v2 data formats, ensuring that
v1 clients can still work with v2 data structures.
"""

from typing import Dict, Any, Optional
from src.database.models import TranscriptionResult


class TranscriptBackwardCompatibility:
    """Provides backward compatibility for v1 clients accessing v2 data.
    
    This class handles conversion between v1 and v2 transcript formats,
    ensuring that existing v1 clients can continue to work with v2 data
    without requiring immediate updates.
    """
    
    @staticmethod
    def to_v1_format(transcript: TranscriptionResult) -> Dict[str, Any]:
        """Convert a v2 transcript to v1 format for backward compatibility.
        
        Args:
            transcript: V2 transcript object
            
        Returns:
            Dictionary in v1 format
        """
        # Start with basic v1 fields
        v1_data = {
            'id': str(transcript.id),
            'job_id': str(transcript.job_id),
            'media_file_id': str(transcript.media_file_id),
            'pipeline_version': transcript.pipeline_version,
            'content': transcript.content,
            'segments': transcript.segments,
            'confidence_scores': transcript.confidence_scores,
            'speaker_info': transcript.speaker_info,
            'accuracy': transcript.accuracy,
            'word_count': transcript.word_count,
            'processing_time': transcript.processing_time,
            'model_used': transcript.model_used,
            'model_config': transcript.model_config,
            'parent_result_id': str(transcript.parent_result_id) if transcript.parent_result_id else None,
            'version': transcript.version,
            'created_at': transcript.created_at.isoformat() if transcript.created_at else None,
            'updated_at': transcript.updated_at.isoformat() if transcript.updated_at else None,
        }
        
        # If this is a v2 transcript with diarization, merge it into content for v1 clients
        if transcript.pipeline_version == 'v2' and transcript.merged_content:
            v1_data['content'] = TranscriptBackwardCompatibility._extract_merged_content(transcript.merged_content)
        
        # Add v2 fields as additional data for v1 clients that can handle them
        v1_data['v2_enhanced_content'] = transcript.enhanced_content
        v1_data['v2_diarization_content'] = transcript.diarization_content
        v1_data['v2_merged_content'] = transcript.merged_content
        v1_data['v2_domain_used'] = transcript.domain_used
        v1_data['v2_accuracy_estimate'] = transcript.accuracy_estimate
        v1_data['v2_speaker_count'] = transcript.speaker_count
        v1_data['v2_quality_warnings'] = transcript.quality_warnings
        v1_data['v2_processing_metadata'] = transcript.processing_metadata
        
        return v1_data
    
    @staticmethod
    def update_from_v1_request(transcript: TranscriptionResult, v1_data: Dict[str, Any]) -> None:
        """Update a v2 transcript from v1 format request data.
        
        Args:
            transcript: V2 transcript object to update
            v1_data: V1 format request data
        """
        # Update basic fields
        if 'content' in v1_data:
            transcript.content = v1_data['content']
        
        if 'segments' in v1_data:
            transcript.segments = v1_data['segments']
        
        if 'confidence_scores' in v1_data:
            transcript.confidence_scores = v1_data['confidence_scores']
        
        if 'speaker_info' in v1_data:
            transcript.speaker_info = v1_data['speaker_info']
        
        if 'accuracy' in v1_data:
            transcript.accuracy = v1_data['accuracy']
        
        if 'word_count' in v1_data:
            transcript.word_count = v1_data['word_count']
        
        if 'processing_time' in v1_data:
            transcript.processing_time = v1_data['processing_time']
        
        if 'model_used' in v1_data:
            transcript.model_used = v1_data['model_used']
        
        if 'model_config' in v1_data:
            transcript.model_config = v1_data['model_config']
        
        # For v2 transcripts, also update the appropriate v2 fields
        if transcript.pipeline_version == 'v2':
            # Store original content in appropriate v2 structure
            if not transcript.processing_metadata:
                transcript.processing_metadata = {}
            transcript.processing_metadata['v1_update'] = True
            transcript.processing_metadata['v1_update_timestamp'] = transcript.updated_at.isoformat() if transcript.updated_at else None
            
            # Simple merged content representation
            if not transcript.merged_content:
                transcript.merged_content = {}
            transcript.merged_content['text'] = v1_data.get('content', {}).get('text', '')
            
            # Update v2 fields if provided in v1 data
            if 'v2_enhanced_content' in v1_data:
                transcript.enhanced_content = v1_data['v2_enhanced_content']
            
            if 'v2_diarization_content' in v1_data:
                transcript.diarization_content = v1_data['v2_diarization_content']
            
            if 'v2_domain_used' in v1_data:
                transcript.domain_used = v1_data['v2_domain_used']
            
            if 'v2_accuracy_estimate' in v1_data:
                transcript.accuracy_estimate = v1_data['v2_accuracy_estimate']
            
            if 'v2_speaker_count' in v1_data:
                transcript.speaker_count = v1_data['v2_speaker_count']
            
            if 'v2_quality_warnings' in v1_data:
                transcript.quality_warnings = v1_data['v2_quality_warnings']
    
    @staticmethod
    def _extract_merged_content(merged_content: Optional[Dict]) -> Dict[str, Any]:
        """Extract plain text content from merged_content JSON structure.
        
        Args:
            merged_content: Merged content dictionary
            
        Returns:
            Content dictionary in v1 format
        """
        if not merged_content:
            return {"text": ""}
        
        # If merged_content has a direct text field, use it
        if isinstance(merged_content, dict) and 'text' in merged_content:
            return {"text": merged_content['text']}
        
        # If merged_content has segments, extract text from them
        if isinstance(merged_content, dict) and 'segments' in merged_content:
            segments = merged_content['segments']
            if isinstance(segments, list):
                text_parts = []
                for seg in segments:
                    if isinstance(seg, dict) and 'text' in seg:
                        text_parts.append(seg['text'])
                return {"text": " ".join(text_parts)}
        
        # If merged_content is a string, wrap it
        if isinstance(merged_content, str):
            return {"text": merged_content}
        
        # Fallback: convert to string representation
        return {"text": str(merged_content)}
    
    @staticmethod
    def is_v2_transcript(transcript: TranscriptionResult) -> bool:
        """Check if a transcript is a v2 transcript.
        
        Args:
            transcript: Transcript object
            
        Returns:
            True if v2 transcript, False otherwise
        """
        return transcript.pipeline_version == 'v2'
    
    @staticmethod
    def has_v2_features(transcript: TranscriptionResult) -> bool:
        """Check if a transcript has v2 features enabled.
        
        Args:
            transcript: Transcript object
            
        Returns:
            True if v2 features are present, False otherwise
        """
        return (
            transcript.enhanced_content is not None or
            transcript.diarization_content is not None or
            transcript.merged_content is not None or
            transcript.domain_used is not None or
            transcript.accuracy_estimate is not None or
            transcript.speaker_count is not None or
            transcript.quality_warnings is not None or
            transcript.processing_metadata is not None
        )
    
    @staticmethod
    def get_v2_feature_summary(transcript: TranscriptionResult) -> Dict[str, Any]:
        """Get a summary of v2 features present in a transcript.
        
        Args:
            transcript: Transcript object
            
        Returns:
            Dictionary with v2 feature summary
        """
        return {
            'pipeline_version': transcript.pipeline_version,
            'has_enhanced_content': transcript.enhanced_content is not None,
            'has_diarization': transcript.diarization_content is not None,
            'has_merged_content': transcript.merged_content is not None,
            'has_domain_processing': transcript.domain_used is not None,
            'has_accuracy_estimate': transcript.accuracy_estimate is not None,
            'has_speaker_count': transcript.speaker_count is not None,
            'has_quality_warnings': transcript.quality_warnings is not None,
            'has_processing_metadata': transcript.processing_metadata is not None,
            'speaker_count': transcript.speaker_count,
            'domain_used': transcript.domain_used,
            'accuracy_estimate': transcript.accuracy_estimate
        }
    
    @staticmethod
    def migrate_v1_to_v2(transcript: TranscriptionResult) -> None:
        """Migrate a v1 transcript to v2 format.
        
        Args:
            transcript: V1 transcript object to migrate
        """
        if transcript.pipeline_version == 'v2':
            return  # Already v2
        
        # Set pipeline version to v2
        transcript.pipeline_version = 'v2'
        
        # Initialize v2 fields with default values
        if transcript.enhanced_content is None:
            transcript.enhanced_content = {"enhanced": False}
        
        if transcript.confidence_scores is not None:
            # Move existing confidence scores to v2 format
            transcript.confidence_scores = transcript.confidence_scores
        
        if transcript.quality_warnings is None:
            transcript.quality_warnings = []
        
        if transcript.processing_metadata is None:
            transcript.processing_metadata = {
                "migrated_from_v1": True,
                "migration_timestamp": transcript.updated_at.isoformat() if transcript.updated_at else None
            }
        
        # Set accuracy estimate based on existing accuracy
        if transcript.accuracy is not None and transcript.accuracy_estimate is None:
            transcript.accuracy_estimate = transcript.accuracy
        
        # Set model used if available
        if transcript.model_used is not None and transcript.domain_used is None:
            # Try to infer domain from model name
            model_lower = transcript.model_used.lower()
            if 'whisper' in model_lower:
                transcript.domain_used = 'general'
            elif 'distil' in model_lower:
                transcript.domain_used = 'optimized'
            else:
                transcript.domain_used = 'custom'
