#!/usr/bin/env python3
"""
PrecipGen Batch Processing Examples

This module demonstrates various batch processing scenarios using the PrecipGen
Convenience API, including regional analysis, multi-site studies, and large-scale
climate assessments.

Author: PrecipGen Development Team
Version: 0.1.3
"""

import os
from pathlib import Path
from typing import List, Dict, Any
from precipgen.convenience import BatchProcessor
from precipgen.convenience.config import BatchConfig, AnalysisConfig, TemplateConfig
from precipgen.convenience.templates.template_examples import get_template_config

def example_1_regional_climate_study():
    """
    Example 1: Regional Climate Study
    
    Analyze precipitation patterns across multiple cities in the Pacific Northwest
    to identify regional climate trends and patterns.
    """
    print("=" * 70)
    print("Example 1: Pacific Northwest Regional Climate Study")
    print("=" * 70)
    
    # Define study locations
    pacific_northwest = [
        "Seattle, WA",
        "Portland, OR",
        "Vancouver, BC",
        "Spokane, WA",
        "Eugene, OR",
        "Bellingham, WA",
        "Olympia, WA",
        "Salem, OR"
    ]
    
    # Configure analysis for climate research
    analysis_config = AnalysisConfig(
        min_years_data=25,              # Require substantial record
        search_radius_km=50,            # Moderate search radius
        trend_window_years=30,          # Long-term trend analysis
        validation_realizations=150,    # Thorough validation
        parallel_execution=True
    )
    
    # Configure batch processing for research
    batch_config = BatchConfig(
        parallel_execution=True,
        max_workers=4,
        continue_on_error=True,
        save_intermediate_results=True,
        generate_summary_report=True,
        parallelism_strategy="by_location"
    )
    
    # Use scientific template for research output
    template_config = get_template_config("scientific")
    template_config.custom_variables.update({
        "study_title": "Pacific Northwest Regional Climate Analysis",
        "institution": "Regional Climate Research Center",
        "study_period": "1990-2024",
        "methodology": "WGEN Algorithm with Trend Analysis"
    })
    
    # Initialize batch processor
    processor = BatchProcessor()
    
    print(f"Analyzing {len(pacific_northwest)} locations in the Pacific Northwest...")
    print("Study objectives:")
    print("  - Characterize regional precipitation patterns")
    print("  - Identify climate trends across the region")
    print("  - Generate parameters for regional climate models")
    print()
    
    try:
        # Run regional analysis
        batch_results = processor.analyze_multiple_locations(
            locations=pacific_northwest,
            analysis_config=analysis_config,
            batch_config=batch_config,
            template_config=template_config
        )
        
        print(f"✅ Regional study completed!")
        print(f"   Locations analyzed: {batch_results.batch_summary.successful_analyses}")
        print(f"   Failed locations: {batch_results.batch_summary.failed_analyses}")
        print(f"   Processing time: {batch_results.batch_summary.processing_time:.1f} seconds")
        
        # Analyze regional patterns
        if batch_results.successful_results:
            print(f"\n🔍 Regional Climate Insights:")
            
            # Calculate regional statistics
            annual_precip = []
            trend_counts = []
            
            for result in batch_results.successful_results:
                # Extract annual precipitation (example calculation)
                if hasattr(result, 'climate_summary'):
                    annual_precip.append(result.climate_summary.annual_mean)
                
                # Count trends
                if result.has_trends:
                    trend_counts.append(len(result.trend_analysis.significant_parameters))
                else:
                    trend_counts.append(0)
            
            if annual_precip:
                avg_annual = sum(annual_precip) / len(annual_precip)
                print(f"   Average annual precipitation: {avg_annual:.0f} mm")
            
            trend_locations = sum(1 for count in trend_counts if count > 0)
            print(f"   Locations with trends: {trend_locations}/{len(trend_counts)}")
            
            if batch_results.batch_summary.recommendations:
                print(f"   Key findings:")
                for rec in batch_results.batch_summary.recommendations[:3]:
                    print(f"     - {rec}")
        
        return batch_results
        
    except Exception as e:
        print(f"❌ Regional study failed: {e}")
        return None

def example_2_infrastructure_assessment():
    """
    Example 2: Infrastructure Design Assessment
    
    Generate precipitation parameters for multiple infrastructure sites
    to support engineering design and planning decisions.
    """
    print("\n" + "=" * 70)
    print("Example 2: Infrastructure Design Parameter Assessment")
    print("=" * 70)
    
    # Define infrastructure project sites
    project_sites = [
        ("Site A - Highway Expansion", "Denver, CO"),
        ("Site B - Airport Development", "Phoenix, AZ"),
        ("Site C - Water Treatment Plant", "Albuquerque, NM"),
        ("Site D - Industrial Complex", "Salt Lake City, UT"),
        ("Site E - Residential Development", "Las Vegas, NV")
    ]
    
    # Extract just the locations for analysis
    locations = [site[1] for site in project_sites]
    
    # Configure for engineering applications
    analysis_config = AnalysisConfig(
        min_years_data=20,              # Engineering standard
        search_radius_km=75,            # Allow wider search for projects
        wet_day_threshold=0.1,          # Standard threshold
        validation_realizations=200,    # Thorough validation for design
        parallel_execution=True
    )
    
    batch_config = BatchConfig(
        parallel_execution=True,
        max_workers=3,                  # Conservative for engineering work
        continue_on_error=True,
        save_intermediate_results=True,
        generate_summary_report=True
    )
    
    # Use engineering template
    template_config = get_template_config("engineering")
    template_config.custom_variables.update({
        "project_name": "Multi-Site Infrastructure Assessment",
        "client": "Regional Development Authority",
        "project_number": "RDA-2024-PRECIP",
        "engineer": "Climate Engineering Consultants"
    })
    
    processor = BatchProcessor()
    
    print("Infrastructure Assessment Parameters:")
    print(f"  - Minimum data requirement: {analysis_config.min_years_data} years")
    print(f"  - Search radius: {analysis_config.search_radius_km} km")
    print(f"  - Validation runs: {analysis_config.validation_realizations}")
    print()
    
    print("Project Sites:")
    for i, (site_name, location) in enumerate(project_sites, 1):
        print(f"  {i}. {site_name}: {location}")
    print()
    
    try:
        # Run infrastructure assessment
        batch_results = processor.analyze_multiple_locations(
            locations=locations,
            analysis_config=analysis_config,
            batch_config=batch_config,
            template_config=template_config
        )
        
        print(f"✅ Infrastructure assessment completed!")
        print(f"   Sites analyzed: {batch_results.batch_summary.successful_analyses}")
        print(f"   Sites failed: {batch_results.batch_summary.failed_analyses}")
        
        # Generate engineering summary
        if batch_results.successful_results:
            print(f"\n🔧 Engineering Design Summary:")
            
            for i, result in enumerate(batch_results.successful_results):
                site_name = project_sites[i][0] if i < len(project_sites) else f"Site {i+1}"
                
                print(f"   {site_name}:")
                print(f"     Station: {result.station_info.name}")
                print(f"     Data quality: {result.station_info.data_quality_score:.1%}")
                print(f"     Validation: {result.validation_report.overall_performance}")
                
                if result.has_trends:
                    print(f"     ⚠️  Trends detected - consider non-stationary design")
                else:
                    print(f"     ✅ Stationary conditions - standard design appropriate")
        
        return batch_results
        
    except Exception as e:
        print(f"❌ Infrastructure assessment failed: {e}")
        return None

def example_3_climate_change_study():
    """
    Example 3: Climate Change Impact Study
    
    Analyze historical trends across multiple locations to assess
    climate change impacts on precipitation patterns.
    """
    print("\n" + "=" * 70)
    print("Example 3: Climate Change Impact Study")
    print("=" * 70)
    
    # Define study locations across different climate zones
    climate_study_locations = [
        # Arid Southwest
        "Phoenix, AZ",
        "Las Vegas, NV",
        "Tucson, AZ",
        
        # Mediterranean California
        "Los Angeles, CA",
        "San Francisco, CA",
        "San Diego, CA",
        
        # Continental Interior
        "Denver, CO",
        "Salt Lake City, UT",
        "Albuquerque, NM",
        
        # Great Plains
        "Oklahoma City, OK",
        "Kansas City, MO",
        "Omaha, NE"
    ]
    
    # Configure for climate change research
    analysis_config = AnalysisConfig(
        min_years_data=30,              # Long record for trend detection
        search_radius_km=100,           # Wider search for climate studies
        trend_window_years=40,          # Long-term trend analysis
        validation_realizations=100,    # Balanced validation
        parallel_execution=True
    )
    
    batch_config = BatchConfig(
        parallel_execution=True,
        max_workers=6,                  # Higher parallelism for research
        continue_on_error=True,
        save_intermediate_results=True,
        generate_summary_report=True,
        parallelism_strategy="by_location"
    )
    
    # Scientific template for climate research
    template_config = get_template_config("scientific")
    template_config.custom_variables.update({
        "study_title": "Regional Climate Change Impact Assessment",
        "research_group": "Climate Change Research Consortium",
        "funding_agency": "National Science Foundation",
        "study_objectives": "Quantify precipitation trend patterns across climate zones"
    })
    
    processor = BatchProcessor()
    
    print("Climate Change Study Design:")
    print(f"  - Study period: Focus on {analysis_config.trend_window_years}-year trends")
    print(f"  - Minimum record: {analysis_config.min_years_data} years")
    print(f"  - Climate zones: Arid, Mediterranean, Continental, Great Plains")
    print(f"  - Total locations: {len(climate_study_locations)}")
    print()
    
    try:
        # Run climate change study
        batch_results = processor.analyze_multiple_locations(
            locations=climate_study_locations,
            analysis_config=analysis_config,
            batch_config=batch_config,
            template_config=template_config
        )
        
        print(f"✅ Climate change study completed!")
        print(f"   Locations analyzed: {batch_results.batch_summary.successful_analyses}")
        print(f"   Processing time: {batch_results.batch_summary.processing_time:.1f} seconds")
        
        # Analyze climate change patterns
        if batch_results.successful_results:
            print(f"\n🌡️ Climate Change Analysis:")
            
            trend_summary = {
                'locations_with_trends': 0,
                'total_trends': 0,
                'increasing_trends': 0,
                'decreasing_trends': 0
            }
            
            for result in batch_results.successful_results:
                if result.has_trends:
                    trend_summary['locations_with_trends'] += 1
                    
                    if hasattr(result.trend_analysis, 'seasonal_slopes'):
                        for season, params in result.trend_analysis.seasonal_slopes.items():
                            for param, slope in params.items():
                                # Check if trend is significant
                                p_value = result.trend_analysis.significance_tests.get(season, {}).get(param, 1.0)
                                if p_value < 0.05:
                                    trend_summary['total_trends'] += 1
                                    if slope > 0:
                                        trend_summary['increasing_trends'] += 1
                                    else:
                                        trend_summary['decreasing_trends'] += 1
            
            print(f"   Locations with significant trends: {trend_summary['locations_with_trends']}")
            print(f"   Total significant trends: {trend_summary['total_trends']}")
            print(f"   Increasing trends: {trend_summary['increasing_trends']}")
            print(f"   Decreasing trends: {trend_summary['decreasing_trends']}")
            
            # Calculate trend percentage
            total_locations = len(batch_results.successful_results)
            trend_percentage = (trend_summary['locations_with_trends'] / total_locations) * 100
            print(f"   Percentage of locations with trends: {trend_percentage:.1f}%")
        
        return batch_results
        
    except Exception as e:
        print(f"❌ Climate change study failed: {e}")
        return None

def example_4_water_resources_planning():
    """
    Example 4: Water Resources Planning Study
    
    Generate precipitation parameters for water resource planning across
    a river basin or water management region.
    """
    print("\n" + "=" * 70)
    print("Example 4: Water Resources Planning Study")
    print("=" * 70)
    
    # Define water resource planning locations (Colorado River Basin example)
    basin_locations = [
        # Upper Basin
        "Grand Junction, CO",
        "Durango, CO",
        "Moab, UT",
        "Flagstaff, AZ",
        
        # Lower Basin
        "Las Vegas, NV",
        "Phoenix, AZ",
        "Yuma, AZ",
        
        # Tributary areas
        "Santa Fe, NM",
        "Cheyenne, WY"
    ]
    
    # Configure for water resources applications
    analysis_config = AnalysisConfig(
        min_years_data=25,              # Water planning standard
        search_radius_km=60,            # Moderate radius for basin studies
        trend_window_years=30,          # Climate planning horizon
        validation_realizations=150,    # Thorough validation for planning
        parallel_execution=True
    )
    
    batch_config = BatchConfig(
        parallel_execution=True,
        max_workers=4,
        continue_on_error=True,
        save_intermediate_results=True,
        generate_summary_report=True
    )
    
    # Engineering template for water resources
    template_config = get_template_config("engineering")
    template_config.custom_variables.update({
        "project_name": "Basin-Wide Water Resources Assessment",
        "client": "Regional Water Management Authority",
        "study_purpose": "Long-term water supply planning and drought preparedness",
        "planning_horizon": "2025-2055"
    })
    
    processor = BatchProcessor()
    
    print("Water Resources Planning Study:")
    print(f"  - Basin: Colorado River Basin (example)")
    print(f"  - Planning horizon: 30-year projections")
    print(f"  - Applications: Reservoir operations, drought planning, supply forecasting")
    print(f"  - Locations: {len(basin_locations)} key sites")
    print()
    
    try:
        # Run water resources study
        batch_results = processor.analyze_multiple_locations(
            locations=basin_locations,
            analysis_config=analysis_config,
            batch_config=batch_config,
            template_config=template_config
        )
        
        print(f"✅ Water resources study completed!")
        print(f"   Sites analyzed: {batch_results.batch_summary.successful_analyses}")
        print(f"   Study duration: {batch_results.batch_summary.processing_time:.1f} seconds")
        
        # Water resources summary
        if batch_results.successful_results:
            print(f"\n💧 Water Resources Planning Summary:")
            
            # Categorize sites by data quality and trends
            high_quality_sites = []
            trend_sites = []
            
            for result in batch_results.successful_results:
                if result.station_info.data_quality_score >= 0.8:
                    high_quality_sites.append(result.station_info.name)
                
                if result.has_trends:
                    trend_sites.append(result.station_info.name)
            
            print(f"   High-quality data sites: {len(high_quality_sites)}")
            print(f"   Sites with climate trends: {len(trend_sites)}")
            
            if trend_sites:
                print(f"   ⚠️  Trend locations require non-stationary analysis:")
                for site in trend_sites[:3]:  # Show first 3
                    print(f"     - {site}")
            
            print(f"   📊 Parameters suitable for:")
            print(f"     - Reservoir inflow modeling")
            print(f"     - Drought risk assessment") 
            print(f"     - Water supply reliability analysis")
            print(f"     - Climate change impact studies")
        
        return batch_results
        
    except Exception as e:
        print(f"❌ Water resources study failed: {e}")
        return None

def example_5_custom_batch_workflow():
    """
    Example 5: Custom Batch Workflow
    
    Demonstrates advanced batch processing with custom error handling,
    quality filtering, and adaptive configuration.
    """
    print("\n" + "=" * 70)
    print("Example 5: Custom Batch Workflow with Adaptive Configuration")
    print("=" * 70)
    
    # Define test locations with varying data availability
    test_locations = [
        "Chicago, IL",      # Major city - good data expected
        "Bismarck, ND",     # Smaller city - moderate data
        "Fairbanks, AK",    # Remote location - challenging data
        "Honolulu, HI",     # Island location - unique climate
        "Key West, FL"      # Extreme location - limited options
    ]
    
    processor = BatchProcessor()
    
    print("Custom Batch Workflow Features:")
    print("  - Adaptive configuration based on data availability")
    print("  - Quality-based filtering and fallbacks")
    print("  - Custom error handling and recovery")
    print("  - Progressive relaxation of requirements")
    print()
    
    def adaptive_batch_analysis(locations: List[str]) -> Dict[str, Any]:
        """
        Custom batch analysis with adaptive configuration.
        
        This function demonstrates how to implement custom batch processing
        logic with fallback strategies and quality-based decisions.
        """
        results = {
            'successful': [],
            'failed': [],
            'warnings': [],
            'adaptations': []
        }
        
        for i, location in enumerate(locations):
            print(f"Processing {i+1}/{len(locations)}: {location}")
            
            # Progressive configuration relaxation
            attempts = [
                # Attempt 1: High standards
                AnalysisConfig(
                    min_years_data=30,
                    search_radius_km=50,
                    validation_realizations=200
                ),
                # Attempt 2: Moderate standards
                AnalysisConfig(
                    min_years_data=20,
                    search_radius_km=75,
                    validation_realizations=150
                ),
                # Attempt 3: Relaxed standards
                AnalysisConfig(
                    min_years_data=15,
                    search_radius_km=100,
                    validation_realizations=100
                )
            ]
            
            success = False
            
            for attempt_num, config in enumerate(attempts, 1):
                try:
                    print(f"  Attempt {attempt_num}: {config.min_years_data} years, {config.search_radius_km} km radius")
                    
                    # Use convenience API for individual analysis
                    from precipgen.convenience import ConvenienceAPI
                    api = ConvenienceAPI()
                    
                    result = api.analyze_precipitation(
                        location=location,
                        analysis_config=config
                    )
                    
                    # Quality check
                    if result.station_info.data_quality_score >= 0.6:
                        results['successful'].append(result)
                        print(f"  ✅ Success: {result.station_info.name} (Quality: {result.station_info.data_quality_score:.1%})")
                        
                        if attempt_num > 1:
                            results['adaptations'].append(f"{location}: Required {attempt_num} attempts")
                        
                        success = True
                        break
                    else:
                        print(f"  ⚠️  Low quality data: {result.station_info.data_quality_score:.1%}")
                        results['warnings'].append(f"{location}: Low quality data")
                        
                except Exception as e:
                    print(f"  ❌ Attempt {attempt_num} failed: {e}")
                    continue
            
            if not success:
                results['failed'].append((location, "All attempts failed"))
                print(f"  🚫 All attempts failed for {location}")
            
            print()
        
        return results
    
    try:
        # Run custom adaptive batch analysis
        custom_results = adaptive_batch_analysis(test_locations)
        
        print(f"✅ Custom batch workflow completed!")
        print(f"   Successful analyses: {len(custom_results['successful'])}")
        print(f"   Failed analyses: {len(custom_results['failed'])}")
        print(f"   Warnings: {len(custom_results['warnings'])}")
        print(f"   Adaptations required: {len(custom_results['adaptations'])}")
        
        if custom_results['adaptations']:
            print(f"\n🔄 Adaptive Configuration Results:")
            for adaptation in custom_results['adaptations']:
                print(f"   - {adaptation}")
        
        if custom_results['warnings']:
            print(f"\n⚠️  Quality Warnings:")
            for warning in custom_results['warnings']:
                print(f"   - {warning}")
        
        return custom_results
        
    except Exception as e:
        print(f"❌ Custom batch workflow failed: {e}")
        return None

def main():
    """
    Run all batch processing examples.
    
    This function demonstrates the full range of batch processing capabilities
    for different use cases and applications.
    """
    print("PrecipGen Batch Processing Examples")
    print("Version 0.1.3")
    print("=" * 70)
    print()
    print("This module demonstrates batch processing for various applications:")
    print("1. Regional climate studies")
    print("2. Infrastructure design assessments") 
    print("3. Climate change impact studies")
    print("4. Water resources planning")
    print("5. Custom adaptive workflows")
    print()
    
    # Create output directory
    output_dir = Path("./batch_examples_output")
    output_dir.mkdir(exist_ok=True)
    print(f"Batch processing outputs will be saved to: {output_dir.absolute()}")
    print()
    
    # Run examples
    examples = [
        ("Regional Climate Study", example_1_regional_climate_study),
        ("Infrastructure Assessment", example_2_infrastructure_assessment),
        ("Climate Change Study", example_3_climate_change_study),
        ("Water Resources Planning", example_4_water_resources_planning),
        ("Custom Batch Workflow", example_5_custom_batch_workflow)
    ]
    
    results = {}
    
    for example_name, example_func in examples:
        try:
            print(f"Running {example_name}...")
            result = example_func()
            results[example_name] = result
            
        except KeyboardInterrupt:
            print(f"\n{example_name} interrupted by user.")
            break
        except Exception as e:
            print(f"❌ {example_name} failed with error: {e}")
            results[example_name] = None
    
    # Summary
    print("\n" + "=" * 70)
    print("Batch Processing Examples Summary")
    print("=" * 70)
    
    successful_examples = sum(1 for result in results.values() if result is not None)
    total_examples = len(examples)
    
    print(f"Examples completed: {successful_examples}/{total_examples}")
    
    for example_name, result in results.items():
        if result is not None:
            print(f"✅ {example_name}: Success")
        else:
            print(f"❌ {example_name}: Failed")
    
    print()
    print("Key Takeaways:")
    print("- Batch processing enables regional and multi-site studies")
    print("- Different applications require different analysis configurations")
    print("- Error handling and fallback strategies are essential")
    print("- Template customization supports various output requirements")
    print("- Parallel processing significantly improves performance")
    print()
    print("For more information:")
    print("- Batch Processing API: precipgen.convenience.BatchProcessor")
    print("- Configuration Options: precipgen.convenience.config")
    print("- Template Customization: precipgen/convenience/templates/")

if __name__ == "__main__":
    main()