"""
PrecipGen: A modular stochastic weather generation library.

This library provides tools for generating synthetic daily precipitation data
using established meteorological algorithms, with emphasis on maintaining state
between calls for seamless integration into dynamic system simulations.

Quick Start:
    import precipgen as pg
    
    # Load CSV data
    precip_data = pg.load_csv_precipitation_data("data.csv")
    
    # Analyze data
    engine = pg.AnalyticalEngine(precip_data, wet_day_threshold=0.0254)
    engine.initialize()
    
    # Generate parameters and simulate
    params = engine.generate_parameter_manifest()
    simulator = pg.PrecipitationSimulator(parameters=params)
    results = simulator.run_monte_carlo_simulation(n_realizations=100)
"""

__version__ = "0.1.4"
__author__ = "PrecipGen Development Team"

import logging
import sys

# Set up logging for import error handling
_logger = logging.getLogger(__name__)

def _handle_import_error(module_name: str, component_name: str, error: Exception) -> None:
    """Handle import errors with clear guidance."""
    error_msg = (
        f"Failed to import {component_name} from {module_name}. "
        f"This may indicate a missing dependency or installation issue.\n"
        f"Original error: {error}\n"
        f"Try: pip install precipgen[all] or check the installation guide."
    )
    _logger.error(error_msg)
    raise ImportError(error_msg) from error

# Core Engines - Essential components for precipitation analysis and simulation
try:
    from .engines.bootstrap import BootstrapEngine
    from .engines.analytical import AnalyticalEngine
    from .engines.simulation import SimulationEngine
except ImportError as e:
    _handle_import_error("precipgen.engines", "Core Engines", e)

# Simulation Components - High-level simulation interfaces
try:
    from .simulation.monte_carlo import PrecipitationSimulator
    from .simulation.ghcn_workflow import GHCNWorkflow
    from .simulation.analysis import DroughtAnalyzer, ExtremeEventAnalyzer, SeasonalAnalyzer
except ImportError as e:
    _handle_import_error("precipgen.simulation", "Simulation Components", e)

# Data Management - GHCN data handling and validation
try:
    from .data.ghcn_parser import GHCNParser
    from .data.validator import DataValidator
    from .data.ghcn_downloader import GHCNDownloader, find_nearby_stations, download_station
except ImportError as e:
    _handle_import_error("precipgen.data", "Data Management Components", e)

# Configuration Management
try:
    from .config.precipgen_config import PrecipGenConfig
    from .config.quality_config import QualityConfig
    from .config.quality_presets import QualityPresets
except ImportError as e:
    _handle_import_error("precipgen.config", "Configuration Components", e)

# Simplified API for common workflows
try:
    from .simple_api import SimplePrecipGen, quick_analysis, analyze_with_trends, load_csv_precipitation_data
    
    # Visualization utilities
    def plot_monthly_parameters(engine_or_data, save_path=None, show_plot=True, **kwargs):
        """
        Convenience function to plot monthly WGEN parameters.
        
        Args:
            engine_or_data: Either an AnalyticalEngine instance or precipitation data
            save_path: Optional path to save the plot
            show_plot: Whether to display the plot
            **kwargs: Additional arguments passed to plot_monthly_parameters
            
        Returns:
            Path where plot was saved (if save_path provided)
            
        Example:
            >>> import precipgen as pg
            >>> engine = pg.AnalyticalEngine(data)
            >>> engine.initialize()
            >>> engine.calculate_monthly_parameters()
            >>> pg.plot_monthly_parameters(engine, save_path='params.png')
        """
        if hasattr(engine_or_data, 'plot_monthly_parameters'):
            # It's an AnalyticalEngine
            return engine_or_data.plot_monthly_parameters(save_path=save_path, show_plot=show_plot, **kwargs)
        else:
            # It's data - create engine first
            engine = AnalyticalEngine(engine_or_data)
            engine.initialize()
            engine.calculate_monthly_parameters()
            return engine.plot_monthly_parameters(save_path=save_path, show_plot=show_plot, **kwargs)
    
    def plot_simulation_comparison(simulator, historical_data, save_path=None, show_plot=True, **kwargs):
        """
        Convenience function to create simulation comparison plots.
        
        Args:
            simulator: PrecipitationSimulator instance with results
            historical_data: Historical precipitation data for comparison
            save_path: Optional path to save the plot
            show_plot: Whether to display the plot
            **kwargs: Additional arguments passed to plot_simulation_comparison
            
        Returns:
            Path where plot was saved (if save_path provided)
            
        Example:
            >>> import precipgen as pg
            >>> simulator = pg.PrecipitationSimulator(parameters=manifest)
            >>> results = simulator.run_monte_carlo_simulation(n_realizations=5)
            >>> pg.plot_simulation_comparison(simulator, historical_data, save_path='comparison.png')
        """
        return simulator.plot_simulation_comparison(
            historical_data=historical_data, 
            save_path=save_path, 
            show_plot=show_plot, 
            **kwargs
        )
except ImportError as e:
    _handle_import_error("precipgen.simple_api", "Simplified API", e)

# Standardized API for external integration
try:
    from .api.standardized_api import StandardizedAPI
    from .api.workflow_integration import WorkflowIntegrator, WorkflowCache, DataFormatConverter
    from .utils.error_handling import (
        ErrorRecoveryManager, PerformanceOptimizer, GracefulDegradationManager,
        error_recovery_manager, performance_optimizer, degradation_manager
    )
except ImportError as e:
    _handle_import_error("precipgen.api", "Standardized API and Error Handling", e)

# CLI interface
try:
    from . import cli
except ImportError as e:
    _logger.warning(f"CLI interface not available: {e}")
    cli = None

# Define all publicly available components
__all__ = [
    # Core Engines
    "BootstrapEngine",
    "AnalyticalEngine", 
    "SimulationEngine",
    
    # Simulation Components
    "PrecipitationSimulator",
    "GHCNWorkflow",
    "DroughtAnalyzer",
    "ExtremeEventAnalyzer", 
    "SeasonalAnalyzer",
    
    # Data Management
    "GHCNParser",
    "DataValidator",
    "GHCNDownloader",
    "find_nearby_stations",
    "download_station",
    
    # Configuration
    "PrecipGenConfig",
    "QualityConfig",
    "QualityPresets",
    
    # Simplified API
    "SimplePrecipGen",
    "quick_analysis", 
    "analyze_with_trends",
    "load_csv_precipitation_data",
    
    # Visualization utilities
    "plot_monthly_parameters",
    "plot_simulation_comparison",
    
    # Standardized API
    "StandardizedAPI",
    
    # Workflow Integration
    "WorkflowIntegrator",
    "WorkflowCache", 
    "DataFormatConverter",
    
    # Error Handling and Performance
    "ErrorRecoveryManager",
    "PerformanceOptimizer", 
    "GracefulDegradationManager",
    "error_recovery_manager",
    "performance_optimizer",
    "degradation_manager",
    
    # CLI (if available)
    "cli",
]

# Provide helpful error messages for common import mistakes
def __getattr__(name: str):
    """Provide helpful error messages for missing attributes."""
    
    # Common import mistakes and their solutions
    suggestions = {
        'ghcn_workflow': 'Use GHCNWorkflow instead',
        'analytical_engine': 'Use AnalyticalEngine instead',
        'simulation_engine': 'Use SimulationEngine instead',
        'precipitation_simulator': 'Use PrecipitationSimulator instead',
        'load_csv': 'Use load_csv_precipitation_data instead',
        'csv_loader': 'Use load_csv_precipitation_data instead',
    }
    
    if name in suggestions:
        raise AttributeError(
            f"'{name}' is not available. {suggestions[name]}.\n"
            f"Available components: {', '.join(__all__)}"
        )
    
    # Check if it's a submodule that should be imported directly
    submodules = ['engines', 'simulation', 'data', 'config', 'api', 'utils']
    if name in submodules:
        raise AttributeError(
            f"Submodule '{name}' should be imported directly: "
            f"from precipgen.{name} import <component>\n"
            f"Available components in main module: {', '.join(__all__)}"
        )
    
    # Generic error message
    raise AttributeError(
        f"Module 'precipgen' has no attribute '{name}'.\n"
        f"Available components: {', '.join(__all__)}\n"
        f"For submodule access, use: from precipgen.<submodule> import <component>"
    )