"""
Simplified batch processing for PrecipGen.

Provides basic batch processing capabilities for analyzing multiple locations.
"""

import time
from concurrent.futures import ProcessPoolExecutor, as_completed
from pathlib import Path
from typing import List, Union, Optional, Dict, Any, Tuple
from dataclasses import dataclass, field
import logging

from ..utils.exceptions import BatchProcessingError
from ..config.precipgen_config import AnalysisConfig


@dataclass
class BatchProgress:
    """Simple progress tracking for batch processing."""
    total_locations: int = 0
    completed_locations: int = 0
    failed_locations: int = 0
    start_time: float = field(default_factory=time.time)
    
    @property
    def completion_percentage(self) -> float:
        """Calculate completion percentage."""
        if self.total_locations == 0:
            return 0.0
        return (self.completed_locations + self.failed_locations) / self.total_locations * 100


class SimpleBatchProcessor:
    """
    Simplified batch processor for multiple location analysis.
    
    Provides basic batch processing without the orchestration bloat.
    """
    
    def __init__(self, max_workers: Optional[int] = None):
        """Initialize batch processor."""
        self.max_workers = max_workers
        self.logger = logging.getLogger(__name__)
    
    def analyze_multiple_locations(self, 
                                 locations: List[Union[str, Tuple[float, float]]],
                                 config: Optional[AnalysisConfig] = None) -> Dict[str, Any]:
        """
        Analyze multiple locations in parallel.
        
        Args:
            locations: List of locations to analyze
            config: Optional analysis configuration
            
        Returns:
            Dictionary with results and summary
        """
        config = config or AnalysisConfig()
        progress = BatchProgress(total_locations=len(locations))
        results = {}
        errors = {}
        
        try:
            if config.parallel_execution and len(locations) > 1:
                # Parallel processing
                with ProcessPoolExecutor(max_workers=self.max_workers) as executor:
                    future_to_location = {
                        executor.submit(self._analyze_single_location, loc, config): loc 
                        for loc in locations
                    }
                    
                    for future in as_completed(future_to_location):
                        location = future_to_location[future]
                        try:
                            result = future.result()
                            results[str(location)] = result
                            progress.completed_locations += 1
                        except Exception as e:
                            errors[str(location)] = str(e)
                            progress.failed_locations += 1
                            self.logger.error(f"Failed to analyze {location}: {e}")
            else:
                # Sequential processing
                for location in locations:
                    try:
                        result = self._analyze_single_location(location, config)
                        results[str(location)] = result
                        progress.completed_locations += 1
                    except Exception as e:
                        errors[str(location)] = str(e)
                        progress.failed_locations += 1
                        self.logger.error(f"Failed to analyze {location}: {e}")
        
        except Exception as e:
            raise BatchProcessingError(f"Batch processing failed: {e}") from e
        
        return {
            'results': results,
            'errors': errors,
            'summary': {
                'total_locations': progress.total_locations,
                'successful': progress.completed_locations,
                'failed': progress.failed_locations,
                'success_rate': progress.completed_locations / progress.total_locations if progress.total_locations > 0 else 0,
                'processing_time': time.time() - progress.start_time
            }
        }
    
    def _analyze_single_location(self, location: Union[str, Tuple[float, float]], 
                               config: AnalysisConfig) -> Dict[str, Any]:
        """Analyze a single location."""
        # Import here to avoid circular imports
        from ..simple_api import SimplePrecipGen
        
        api = SimplePrecipGen()
        result = api.analyze_location(
            location=location,
            min_years=config.min_years_data,
            search_radius_km=config.search_radius_km,
            include_trends=config.trend_analysis_enabled
        )
        
        return result.to_dict()