"""Gap analysis for finding missing provider/month combinations between stages."""

from dataclasses import dataclass
from typing import Dict, List, Set
from src.log_context.core import get_logger


@dataclass
class ProcessingGap:
    """Represents a provider/month combination that needs processing from metadata stage."""
    provider: str
    month: str
    source: str = "metadata"  # Indicates this needs metadata stage processing


class GapAnalyzer:
    """Analyzes gaps between usage and metadata stage availability."""
    
    def __init__(self):
        self.logger = get_logger(__name__)
    
    def find_processing_gaps(
        self, 
        dataset_name: str,
        usage_processed: Dict[str, List[str]],
        metadata_available: Dict[str, List[str]]
    ) -> List[ProcessingGap]:
        """
        Find months/providers available in metadata but not processed from src.usage.
        
        Args:
            dataset_name: Dataset identifier for logging
            usage_processed: Dict[provider, List[months]] successfully processed from usage
            metadata_available: Dict[provider, List[months]] available in metadata stage
            
        Returns:
            List of ProcessingGap objects for metadata stage processing
        """
        gaps = []
        
        # Find gaps for each provider
        for provider, metadata_months in metadata_available.items():
            usage_months = usage_processed.get(provider, [])
            missing_months = set(metadata_months) - set(usage_months)
            
            for month in sorted(missing_months):  # Sort for consistent ordering
                gaps.append(ProcessingGap(provider=provider, month=month))
        
        # Log gap analysis results
        if gaps:
            gap_summary = {}
            for gap in gaps:
                gap_summary.setdefault(gap.provider, []).append(gap.month)
            
            self.logger.info(
                "Found processing gaps between usage and metadata stages",
                dataset_name=dataset_name,
                total_gaps=len(gaps),
                gaps_by_provider=gap_summary
            )
        else:
            self.logger.info(
                "No processing gaps found - all providers covered by usage stage",
                dataset_name=dataset_name
            )
        
        return gaps
    
    def analyze_coverage(
        self, 
        usage_processed: Dict[str, List[str]],
        metadata_available: Dict[str, List[str]]
    ) -> Dict[str, any]:
        """
        Analyze coverage statistics between usage and metadata stages.
        
        Args:
            usage_processed: Dict[provider, List[months]] successfully processed from usage
            metadata_available: Dict[provider, List[months]] available in metadata stage
            
        Returns:
            Dictionary with coverage statistics
        """
        total_usage_months = sum(len(months) for months in usage_processed.values())
        total_metadata_months = sum(len(months) for months in metadata_available.values())
        
        # Calculate gaps
        gaps = self.find_processing_gaps("", usage_processed, metadata_available)
        total_gap_months = len(gaps)
        
        # Coverage by provider
        provider_coverage = {}
        all_providers = set(usage_processed.keys()) | set(metadata_available.keys())
        
        for provider in all_providers:
            usage_months = set(usage_processed.get(provider, []))
            metadata_months = set(metadata_available.get(provider, []))
            total_provider_months = len(metadata_months)
            covered_months = len(usage_months)
            gap_months = len(metadata_months - usage_months)
            
            coverage_pct = (covered_months / total_provider_months * 100) if total_provider_months > 0 else 0
            
            provider_coverage[provider] = {
                "total_months": total_provider_months,
                "usage_covered": covered_months,
                "metadata_gaps": gap_months,
                "coverage_percentage": coverage_pct
            }
        
        return {
            "total_metadata_months": total_metadata_months,
            "usage_covered_months": total_usage_months,
            "metadata_gap_months": total_gap_months,
            "overall_coverage_percentage": (total_usage_months / total_metadata_months * 100) if total_metadata_months > 0 else 0,
            "provider_coverage": provider_coverage
        }