"""
Simplified ConvenienceAPI interface for PrecipGen.

This module provides a streamlined interface focusing on the two core requirements
without the orchestration bloat of the original convenience API.
"""

from typing import Union, Optional, List, Tuple, Dict, Any
from pathlib import Path
import logging

from ..config.precipgen_config import AnalysisConfig, StationRequirements
from ..api.data_exchange import StationInfo, ValidationReport
from ..utils.exceptions import ConvenienceAPIError, StationDiscoveryError
from .simple_station_discovery import SimpleStationDiscovery
from .batch_processor import SimpleBatchProcessor


class SimpleConvenienceAPI:
    """
    Simplified convenience API for PrecipGen.
    
    Provides the two core requirements without bloat:
    1. Single function for location → parameter generation
    2. Comprehensive trend analysis and visualization
    """
    
    def __init__(self, default_config: Optional[AnalysisConfig] = None):
        """Initialize the simplified convenience API."""
        self.logger = logging.getLogger(__name__)
        self.default_config = default_config or AnalysisConfig()
        self.station_discovery = SimpleStationDiscovery()
        self.batch_processor = SimpleBatchProcessor()
    
    def analyze_precipitation(self, 
                            location: Union[str, Tuple[float, float]], 
                            station_id: Optional[str] = None,
                            analysis_config: Optional[AnalysisConfig] = None) -> Dict[str, Any]:
        """
        Complete workflow from location to parameter generation.
        
        This single function replaces 350+ lines of custom code.
        
        Args:
            location: City name, address, or (lat, lon) coordinates
            station_id: Optional specific GHCN station ID
            analysis_config: Optional analysis configuration
            
        Returns:
            Complete analysis results with parameter manifest
        """
        config = analysis_config or self.default_config
        
        try:
            # Use the simplified API
            from ..simple_api import SimplePrecipGen
            
            api = SimplePrecipGen()
            result = api.analyze_location(
                location=location,
                station_id=station_id,
                min_years=config.min_years_data,
                search_radius_km=config.search_radius_km,
                include_trends=config.trend_analysis_enabled
            )
            
            return result.to_dict()
            
        except Exception as e:
            self.logger.error(f"Analysis failed for location {location}: {e}")
            raise ConvenienceAPIError(f"Analysis failed: {e}") from e
    
    def discover_stations(self, 
                         location: Union[str, Tuple[float, float]],
                         requirements: Optional[StationRequirements] = None) -> List[StationInfo]:
        """
        Discover suitable GHCN stations for a location.
        
        Args:
            location: City name, address, or coordinates
            requirements: Station requirements
            
        Returns:
            List of suitable stations
        """
        try:
            station = self.station_discovery.find_station(location, requirements)
            return [station]  # Simplified - return single best station
            
        except Exception as e:
            self.logger.error(f"Station discovery failed for {location}: {e}")
            raise StationDiscoveryError(f"Station discovery failed: {e}") from e
    
    def analyze_multiple_locations(self, 
                                 locations: List[Union[str, Tuple[float, float]]],
                                 analysis_config: Optional[AnalysisConfig] = None) -> Dict[str, Any]:
        """
        Analyze multiple locations in batch.
        
        Args:
            locations: List of locations to analyze
            analysis_config: Optional analysis configuration
            
        Returns:
            Batch analysis results
        """
        config = analysis_config or self.default_config
        
        try:
            return self.batch_processor.analyze_multiple_locations(locations, config)
            
        except Exception as e:
            self.logger.error(f"Batch analysis failed: {e}")
            raise ConvenienceAPIError(f"Batch analysis failed: {e}") from e
    
    def create_trend_plots(self, 
                          analysis_result: Dict[str, Any], 
                          output_dir: Optional[Path] = None) -> Dict[str, Path]:
        """
        Create trend analysis plots from analysis results.
        
        Args:
            analysis_result: Results from analyze_precipitation()
            output_dir: Directory to save plots
            
        Returns:
            Dictionary mapping plot names to file paths
        """
        try:
            from ..simple_api import SimplePrecipGen, SimpleAnalysisResult
            
            # Convert dict back to SimpleAnalysisResult
            result = SimpleAnalysisResult(**analysis_result)
            
            api = SimplePrecipGen()
            return api.create_trend_plots(result, output_dir=output_dir)
            
        except Exception as e:
            self.logger.error(f"Plot creation failed: {e}")
            raise ConvenienceAPIError(f"Plot creation failed: {e}") from e


# Convenience functions for backward compatibility
def analyze_precipitation(location: Union[str, Tuple[float, float]], 
                        station_id: Optional[str] = None) -> Dict[str, Any]:
    """Quick analysis function for backward compatibility."""
    api = SimpleConvenienceAPI()
    return api.analyze_precipitation(location, station_id=station_id)
    def analyze_precipitation(
        self,
        location: Union[str, Tuple[float, float]],
        analysis_config: Optional[AnalysisConfig] = None,
        output_config: Optional[OutputConfig] = None,
        station_id: Optional[str] = None,
        interactive_station_selection: bool = False
    ) -> AnalysisResult:
        """
        Complete precipitation analysis from location to publication-ready results.
        
        This is the primary method that implements the "one-function workflow"
        approach, handling the complete pipeline from location input to final
        publication-ready results.
        
        Args:
            location: City name, address, or (latitude, longitude) tuple
            analysis_config: Optional configuration for analysis parameters
            output_config: Optional configuration for output generation
            station_id: Optional specific station ID to use (bypasses discovery)
            interactive_station_selection: If True, prompts user to select from candidates
            
        Returns:
            AnalysisResult containing all analysis outputs and metadata
            
        Raises:
            ConvenienceAPIError: If analysis fails at any stage
            StationDiscoveryError: If no suitable stations found
            GeocodingError: If location cannot be geocoded
            WorkflowError: If workflow orchestration fails
        """
        start_time = time.time()
        
        # Validate and merge configuration
        config = self._prepare_analysis_config(analysis_config)
        output_cfg = output_config or OutputConfig()
        
        # Convert location to string for logging
        location_str = self._location_to_string(location)
        
        # Log workflow start
        log_workflow_start(location_str, config.__dict__)
        
        try:
            # Validate configuration
            config_errors = config.validate()
            if config_errors:
                raise ConfigurationError("analysis", config_errors)
            
            # Initialize result structure
            result = self._create_empty_result(location_str, station_id)
            
            # Execute workflow using WorkflowManager with comprehensive error handling
            if self._workflow_manager is None:
                raise WorkflowError(
                    "initialization", 
                    "WorkflowManager",
                    "WorkflowManager not properly initialized"
                )
            
            # Pre-execution validation and setup
            self._validate_component_availability(config)
            
            # Execute the complete workflow with integrated error handling
            result = self._workflow_manager.execute_workflow(
                location=location,
                config=config,
                output_config=output_cfg,
                station_id=station_id,
                interactive_station_selection=interactive_station_selection
            )
            
            # Post-execution validation and enhancement
            result = self._enhance_analysis_result(result, config, output_cfg)
            
            # Update processing time
            result.metadata.processing_time = time.time() - start_time
            
            log_workflow_complete(location_str, result.success, result.metadata.processing_time)
            
            return result
            
        except Exception as e:
            # Log error and create failed result
            log_component_error('api', 'analyze_precipitation', e, location_str)
            
            result = self._create_empty_result(location_str, station_id)
            result.success = False
            result.error_message = str(e)
            result.metadata.processing_time = time.time() - start_time
            
            log_workflow_complete(location_str, False, result.metadata.processing_time)
            
            # Re-raise for user handling
            raise ConvenienceAPIError(
                f"Analysis failed for {location_str}: {str(e)}",
                details={'location': location_str, 'error_type': type(e).__name__},
                guidance="Check the error details and verify location and configuration parameters"
            )
    
    @cached(cache_key="discover_stations", ttl=1800)  # Cache for 30 minutes
    def discover_stations(
        self,
        location: Union[str, Tuple[float, float]],
        requirements: Optional[StationRequirements] = None
    ) -> List[StationCandidate]:
        """
        Discover and rank candidate stations without running full analysis.
        
        This method allows users to explore available stations before committing
        to a full analysis, supporting the semi-interactive workflow pattern.
        
        Args:
            location: City name, address, or (latitude, longitude) tuple
            requirements: Optional requirements for station selection
            
        Returns:
            List of ranked station candidates with metadata for manual selection
            
        Raises:
            StationDiscoveryError: If no suitable stations found
            GeocodingError: If location cannot be geocoded
        """
        location_str = self._location_to_string(location)
        self.logger.info(f"Discovering stations for {location_str}")
        
        try:
            # Validate requirements
            reqs = requirements or StationRequirements()
            req_errors = reqs.validate()
            if req_errors:
                raise ConfigurationError("station_requirements", req_errors)
            
            # Use station discovery component if available
            if self._station_discovery is None:
                raise StationDiscoveryError(
                    location_str, 
                    reqs.max_distance_km,
                    requirements=reqs.__dict__,
                    candidates_found=0,
                    issues=["StationDiscovery component not available"]
                )
            
            # Discover candidate stations
            candidates = self._station_discovery.discover_candidate_stations(
                location=location,
                requirements=reqs
            )
            
            self.logger.info(f"Found {len(candidates)} candidate stations for {location_str}")
            
            return candidates
            
        except Exception as e:
            log_component_error('api', 'discover_stations', e, location_str)
            raise
    
    def preview_station_data(
        self,
        station_id: str,
        show_plots: bool = True
    ) -> StationPreview:
        """
        Preview station data quality and characteristics before analysis.
        
        Provides detailed preview information to help users assess whether
        a station is suitable for their analysis needs.
        
        Args:
            station_id: GHCN station ID to preview
            show_plots: Whether to generate preview plots
            
        Returns:
            StationPreview with data summary, quality metrics, and optional plots
            
        Raises:
            ConvenienceAPIError: If station preview fails
        """
        self.logger.info(f"Previewing station data for {station_id}")
        
        try:
            # Validate station ID format
            if not station_id or len(station_id) != 11:
                raise ConvenienceAPIError(
                    f"Invalid station ID format: {station_id}",
                    details={'station_id': station_id},
                    guidance="Station ID must be 11 characters (e.g., 'USW00024233')"
                )
            
            # Use station discovery component if available
            if self._station_discovery is None:
                raise ConvenienceAPIError(
                    f"Station preview not available for {station_id}",
                    details={'station_id': station_id, 'reason': 'component_not_available'},
                    guidance="StationDiscovery component not available"
                )
            
            # Generate station preview
            preview = self._station_discovery.preview_station_data(
                station_id=station_id,
                show_plots=show_plots
            )
            
            self.logger.info(f"Generated preview for station {station_id}: {preview.recommendation}")
            
            return preview
            
        except Exception as e:
            log_component_error('api', 'preview_station_data', e, context={'station_id': station_id})
            raise
    
    def _prepare_analysis_config(self, user_config: Optional[AnalysisConfig]) -> AnalysisConfig:
        """
        Prepare and validate analysis configuration.
        
        Args:
            user_config: User-provided configuration
            
        Returns:
            Merged and validated configuration
        """
        if user_config is None:
            return self.default_config
        
        # For now, just return user config or default
        # In future, implement proper merging logic
        return user_config
    
    def _location_to_string(self, location: Union[str, Tuple[float, float]]) -> str:
        """
        Convert location input to string representation for logging.
        
        Args:
            location: Location input
            
        Returns:
            String representation of location
        """
        if isinstance(location, str):
            return location
        elif isinstance(location, (tuple, list)) and len(location) == 2:
            return f"({location[0]:.4f}, {location[1]:.4f})"
        else:
            return str(location)
    
    def _create_empty_result(self, location: str, station_id: Optional[str] = None) -> AnalysisResult:
        """
        Create an empty analysis result structure for initialization.
        
        Args:
            location: Location string
            station_id: Optional station ID
            
        Returns:
            Empty AnalysisResult structure
        """
        from .models import create_empty_analysis_result
        return create_empty_analysis_result(location, station_id)
    
    def get_version_info(self) -> Dict[str, str]:
        """
        Get version information for the convenience API and dependencies.
        
        Returns:
            Dictionary with version information
        """
        return {
            'convenience_api': '0.1.3',
            'precipgen_core': '0.1.3',
            'python_version': f"{__import__('sys').version_info.major}.{__import__('sys').version_info.minor}"
        }
    
    def validate_configuration(self, config: AnalysisConfig) -> List[str]:
        """
        Validate an analysis configuration and return any errors.
        
        Args:
            config: Configuration to validate
            
        Returns:
            List of validation error messages
        """
        return config.validate()
    
    def get_supported_locations(self) -> Dict[str, Any]:
        """
        Get information about supported location formats and geocoding.
        
        Returns:
            Dictionary with supported location information
        """
        return {
            'coordinate_formats': [
                '(latitude, longitude) tuple',
                '[latitude, longitude] list'
            ],
            'text_formats': [
                'City, State (e.g., "Seattle, WA")',
                'City, Country (e.g., "Vancouver, Canada")', 
                'Full address (e.g., "123 Main St, Seattle, WA")'
            ],
            'coordinate_ranges': {
                'latitude': [-90, 90],
                'longitude': [-180, 180]
            },
            'geocoding_service': 'OpenStreetMap Nominatim',
            'supported_countries': ['US', 'Canada', 'Mexico']  # Initial support
        }
    
    def get_default_config(self) -> AnalysisConfig:
        """
        Get the current default configuration.
        
        Returns:
            Copy of the default configuration
        """
        # Return a copy to prevent modification
        import copy
        return copy.deepcopy(self.default_config)
    
    def set_default_config(self, config: AnalysisConfig) -> None:
        """
        Set a new default configuration for all analyses.
        
        Args:
            config: New default configuration
            
        Raises:
            ConfigurationError: If configuration is invalid
        """
        errors = config.validate()
        if errors:
            raise ConfigurationError("default_config", errors)
        
        self.default_config = config
        self.logger.info("Default configuration updated")
    
    def configure_workflow(self, **config_options) -> None:
        """
        Configure workflow behavior.
        
        Args:
            **config_options: Workflow configuration options
        """
        if self._workflow_manager:
            self._workflow_manager.configure_workflow(**config_options)
        else:
            raise WorkflowError("configuration", "workflow_manager", "WorkflowManager not initialized")
    
    def set_expert_mode(self, enabled: bool = True) -> None:
        """
        Enable or disable expert mode for enhanced control.
        
        Args:
            enabled: Whether to enable expert mode
        """
        if self._workflow_manager:
            self._workflow_manager.set_expert_mode(enabled)
        else:
            raise WorkflowError("configuration", "workflow_manager", "WorkflowManager not initialized")
    
    def set_interactive_mode(self, enabled: bool = True) -> None:
        """
        Enable or disable interactive mode for user prompts.
        
        Args:
            enabled: Whether to enable interactive mode
        """
        if self._workflow_manager:
            self._workflow_manager.set_interactive_mode(enabled)
        else:
            raise WorkflowError("configuration", "workflow_manager", "WorkflowManager not initialized")
    
    def set_batch_mode(self, enabled: bool = True) -> None:
        """
        Enable or disable batch processing mode.
        
        Args:
            enabled: Whether to enable batch mode
        """
        if self._workflow_manager:
            self._workflow_manager.set_batch_mode(enabled)
        else:
            raise WorkflowError("configuration", "workflow_manager", "WorkflowManager not initialized")
    
    def validate_workflow_setup(
        self,
        location: Union[str, Tuple[float, float]],
        config: Optional[AnalysisConfig] = None
    ) -> Dict[str, Any]:
        """
        Perform pre-flight validation of workflow setup.
        
        Args:
            location: Location to analyze
            config: Optional analysis configuration
            
        Returns:
            Validation results with errors, warnings, and recommendations
        """
        analysis_config = config or self.default_config
        
        if self._workflow_manager:
            return self._workflow_manager.validate_workflow_setup(location, analysis_config)
        else:
            raise WorkflowError("validation", "workflow_manager", "WorkflowManager not initialized")
    
    def get_workflow_configuration(self) -> Dict[str, Any]:
        """
        Get current workflow configuration.
        
        Returns:
            Dictionary with workflow configuration details
        """
        if self._workflow_manager:
            return self._workflow_manager.export_workflow_configuration()
        else:
            return {}
    
    def get_analysis_recommendations(
        self,
        location: Union[str, Tuple[float, float]],
        user_requirements: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """
        Get analysis recommendations based on location and user requirements.
        
        Provides intelligent recommendations for analysis configuration
        based on location characteristics and user needs.
        
        Args:
            location: Location to analyze
            user_requirements: Optional user requirements and preferences
            
        Returns:
            Dictionary with recommended configuration and explanations
        """
        location_str = self._location_to_string(location)
        self.logger.info(f"Generating analysis recommendations for {location_str}")
        
        try:
            # Basic recommendations structure
            recommendations = {
                'location': location_str,
                'recommended_config': {},
                'station_requirements': {},
                'analysis_options': {},
                'explanations': [],
                'warnings': [],
                'estimated_processing_time': 'Unknown'
            }
            
            # Use workflow manager for intelligent recommendations if available
            if self._workflow_manager:
                workflow_recommendations = self._workflow_manager.get_location_recommendations(
                    location, user_requirements or {}
                )
                recommendations.update(workflow_recommendations)
            else:
                # Provide basic recommendations
                recommendations['recommended_config'] = asdict(self.default_config)
                recommendations['explanations'].append(
                    "Using default configuration - workflow manager not available for intelligent recommendations"
                )
            
            return recommendations
            
        except Exception as e:
            self.logger.error(f"Failed to generate recommendations for {location_str}: {e}")
            return {
                'location': location_str,
                'error': str(e),
                'fallback_config': asdict(self.default_config)
            }
    
    def estimate_processing_time(
        self,
        location: Union[str, Tuple[float, float]],
        config: Optional[AnalysisConfig] = None
    ) -> Dict[str, Any]:
        """
        Estimate processing time for analysis based on configuration.
        
        Args:
            location: Location to analyze
            config: Optional analysis configuration
            
        Returns:
            Dictionary with time estimates and factors
        """
        analysis_config = config or self.default_config
        location_str = self._location_to_string(location)
        
        # Base estimates (in seconds)
        base_estimates = {
            'station_discovery': 5,
            'data_acquisition': 10,
            'trend_analysis': 15,
            'parameter_generation': 5,
            'validation': 30,  # Depends on n_realizations
            'visualization': 10,
            'report_generation': 5
        }
        
        # Adjust based on configuration
        if analysis_config.validation_realizations > 100:
            base_estimates['validation'] *= (analysis_config.validation_realizations / 100)
        
        if analysis_config.trend_window_years > 30:
            base_estimates['trend_analysis'] *= 1.5
        
        if analysis_config.parallel_execution:
            # Reduce validation time with parallelization
            base_estimates['validation'] *= 0.6
        
        total_estimate = sum(base_estimates.values())
        
        return {
            'location': location_str,
            'total_estimate_seconds': total_estimate,
            'total_estimate_minutes': total_estimate / 60,
            'stage_estimates': base_estimates,
            'factors': {
                'validation_realizations': analysis_config.validation_realizations,
                'trend_window_years': analysis_config.trend_window_years,
                'parallel_execution': analysis_config.parallel_execution
            },
            'confidence': 'medium'  # Estimates are approximate
        }
    
    def get_location_characteristics(
        self,
        location: Union[str, Tuple[float, float]]
    ) -> Dict[str, Any]:
        """
        Get characteristics and metadata about a location for analysis planning.
        
        Args:
            location: Location to characterize
            
        Returns:
            Dictionary with location characteristics and analysis implications
        """
        location_str = self._location_to_string(location)
        
        try:
            # Use station discovery for location analysis if available
            if self._station_discovery:
                return self._station_discovery.analyze_location_characteristics(location)
            else:
                # Provide basic location information
                if isinstance(location, str):
                    return {
                        'location': location_str,
                        'type': 'text_location',
                        'geocoding_required': True,
                        'estimated_coordinates': None,
                        'analysis_implications': [
                            'Geocoding will be performed to determine coordinates',
                            'Station search will be performed around geocoded location'
                        ]
                    }
                else:
                    lat, lon = location
                    return {
                        'location': location_str,
                        'type': 'coordinates',
                        'coordinates': (lat, lon),
                        'geocoding_required': False,
                        'analysis_implications': [
                            'Direct coordinate-based station search will be performed'
                        ]
                    }
                    
        except Exception as e:
            self.logger.error(f"Failed to analyze location characteristics for {location_str}: {e}")
            return {
                'location': location_str,
                'error': str(e),
                'type': 'unknown'
            }
    
    def get_available_workflow_options(self) -> Dict[str, Dict[str, Any]]:
        """
        Get information about available workflow configuration options.
        
        Returns:
            Dictionary describing all available configuration options
        """
        if self._workflow_manager:
            return self._workflow_manager.get_available_configurations()
        else:
            return {}
    
    def _validate_component_availability(self, config: AnalysisConfig) -> None:
        """
        Validate that required components are available for the requested analysis.
        
        Args:
            config: Analysis configuration to validate against
            
        Raises:
            WorkflowError: If required components are not available
        """
        missing_components = []
        
        # Check station discovery (always required)
        if self._station_discovery is None:
            missing_components.append("StationDiscovery")
        
        # Check trend analyzer if trend analysis is requested
        if config.trend_window_years > 0 and self._trend_analyzer is None:
            missing_components.append("TrendAnalyzer")
        
        # Check validation suite if validation is requested
        if config.validation_realizations > 0 and self._validation_suite is None:
            missing_components.append("ValidationSuite")
        
        # Check article generator for report generation
        if self._article_generator is None:
            missing_components.append("ArticleGenerator")
        
        if missing_components:
            raise WorkflowError(
                "component_validation",
                "api_integration",
                f"Required components not available: {', '.join(missing_components)}",
                recovery_attempted=False
            )
    
    def _enhance_analysis_result(
        self,
        result: AnalysisResult,
        config: AnalysisConfig,
        output_config: OutputConfig
    ) -> AnalysisResult:
        """
        Enhance analysis result with additional metadata and validation.
        
        Args:
            result: Analysis result to enhance
            config: Analysis configuration used
            output_config: Output configuration used
            
        Returns:
            Enhanced analysis result
        """
        try:
            # Add API-level metadata
            result.metadata.convenience_api_version = "0.3.0"
            result.metadata.analysis_config = asdict(config)
            
            # Add component availability information
            result.metadata.software_environment.update({
                'station_discovery_available': self._station_discovery is not None,
                'trend_analyzer_available': self._trend_analyzer is not None,
                'validation_suite_available': self._validation_suite is not None,
                'article_generator_available': self._article_generator is not None
            })
            
            # Validate result completeness
            validation_issues = self._validate_result_completeness(result, config)
            if validation_issues:
                result.metadata.warnings.extend(validation_issues)
            
            # Add user guidance based on results
            guidance = self._generate_user_guidance(result, config)
            if guidance:
                result.metadata.recommendations = guidance
            
            return result
            
        except Exception as e:
            self.logger.warning(f"Failed to enhance analysis result: {e}")
            # Return original result if enhancement fails
            return result
    
    def _validate_result_completeness(
        self,
        result: AnalysisResult,
        config: AnalysisConfig
    ) -> List[str]:
        """
        Validate that the analysis result is complete based on configuration.
        
        Args:
            result: Analysis result to validate
            config: Configuration that was used
            
        Returns:
            List of validation issues found
        """
        issues = []
        
        if result.success:
            # Check for expected components
            if result.parameter_manifest is None:
                issues.append("Parameter manifest missing despite successful analysis")
            
            if config.trend_window_years > 0 and result.trend_analysis is None:
                issues.append("Trend analysis requested but not performed")
            
            if config.validation_realizations > 0 and not result.validation_report.passes_validation:
                issues.append("Validation requested but did not pass minimum criteria")
            
            if result.html_report is None:
                issues.append("HTML report generation requested but not completed")
        
        return issues
    
    def _generate_user_guidance(
        self,
        result: AnalysisResult,
        config: AnalysisConfig
    ) -> List[str]:
        """
        Generate user guidance based on analysis results.
        
        Args:
            result: Analysis result
            config: Configuration used
            
        Returns:
            List of guidance recommendations
        """
        guidance = []
        
        if not result.success:
            guidance.append("Analysis failed - check error message and consider adjusting configuration")
            return guidance
        
        # Guidance based on data quality
        if result.station_info.data_quality_score < 0.7:
            guidance.append("Station data quality is below optimal - consider using a different station")
        
        # Guidance based on trend analysis
        if result.trend_analysis and result.trend_analysis.has_significant_trends:
            guidance.append("Significant trends detected - consider using non-stationary simulation mode")
        elif result.trend_analysis and not result.trend_analysis.has_significant_trends:
            guidance.append("No significant trends detected - stationary simulation mode is appropriate")
        
        # Guidance based on validation
        if not result.validation_report.passes_validation:
            guidance.append("Model validation indicates potential issues - review validation report for details")
        
        # Guidance based on data completeness
        if result.station_info.data_completeness < 0.8:
            guidance.append("Data completeness is below optimal - results may be less reliable")
        
        return guidance
    
    def get_component_status(self) -> Dict[str, Dict[str, Any]]:
        """
        Get detailed status of all convenience API components.
        
        Returns:
            Dictionary with component status and capabilities
        """
        status = {
            'workflow_manager': {
                'available': self._workflow_manager is not None,
                'capabilities': ['workflow_orchestration', 'error_handling', 'fallback_strategies'] if self._workflow_manager else []
            },
            'station_discovery': {
                'available': self._station_discovery is not None,
                'capabilities': ['geocoding', 'station_ranking', 'interactive_selection'] if self._station_discovery else []
            },
            'trend_analyzer': {
                'available': self._trend_analyzer is not None,
                'capabilities': ['seasonal_trends', 'significance_testing', 'future_projections'] if self._trend_analyzer else []
            },
            'validation_suite': {
                'available': self._validation_suite is not None,
                'capabilities': ['statistical_validation', 'parallel_execution', 'diagnostics'] if self._validation_suite else []
            },
            'article_generator': {
                'available': self._article_generator is not None,
                'capabilities': ['template_rendering', 'plot_embedding', 'multiple_formats'] if self._article_generator else []
            }
        }
        
        # Add overall API status
        all_available = all(comp['available'] for comp in status.values())
        status['overall'] = {
            'all_components_available': all_available,
            'ready_for_production': all_available,
            'missing_components': [name for name, comp in status.items() if name != 'overall' and not comp['available']]
        }
        
        return status
    
    def diagnose_configuration(self, config: AnalysisConfig) -> Dict[str, Any]:
        """
        Diagnose potential issues with analysis configuration.
        
        Args:
            config: Configuration to diagnose
            
        Returns:
            Dictionary with diagnostic information and recommendations
        """
        diagnosis = {
            'configuration_valid': True,
            'errors': [],
            'warnings': [],
            'recommendations': [],
            'estimated_impact': {}
        }
        
        # Validate configuration
        config_errors = config.validate()
        if config_errors:
            diagnosis['configuration_valid'] = False
            diagnosis['errors'] = config_errors
        
        # Check for potential performance issues
        if config.validation_realizations > 500:
            diagnosis['warnings'].append(
                f"High validation realizations ({config.validation_realizations}) may cause long processing times"
            )
            diagnosis['estimated_impact']['processing_time'] = 'significantly_increased'
        
        if config.trend_window_years > 50:
            diagnosis['warnings'].append(
                f"Large trend window ({config.trend_window_years} years) may reduce trend detection sensitivity"
            )
        
        if config.search_radius_km > 200:
            diagnosis['warnings'].append(
                f"Large search radius ({config.search_radius_km} km) may include climatologically different stations"
            )
        
        # Generate recommendations
        if config.min_years_data < 15:
            diagnosis['recommendations'].append(
                "Consider increasing min_years_data to 15+ for more reliable parameter estimation"
            )
        
        if not config.parallel_execution and config.validation_realizations > 100:
            diagnosis['recommendations'].append(
                "Enable parallel execution for faster validation with high realization counts"
            )
        
        return diagnosis
    
    def create_analysis_summary(self, result: AnalysisResult) -> Dict[str, Any]:
        """
        Create a comprehensive summary of analysis results.
        
        Args:
            result: Analysis result to summarize
            
        Returns:
            Dictionary with analysis summary
        """
        summary = {
            'location': result.metadata.input_location,
            'success': result.success,
            'processing_time': result.metadata.processing_time,
            'station_info': {
                'id': result.station_info.id,
                'name': result.station_info.name,
                'distance_km': result.station_info.distance_km,
                'data_years': result.station_info.data_years,
                'quality_score': result.station_info.data_quality_score
            }
        }
        
        if result.success:
            # Add trend analysis summary
            if result.trend_analysis:
                summary['trends'] = {
                    'significant_trends_found': result.trend_analysis.has_significant_trends,
                    'significant_parameters': result.trend_analysis.significant_parameters,
                    'analysis_method': result.trend_analysis.analysis_method
                }
            
            # Add validation summary
            summary['validation'] = {
                'overall_performance': result.validation_report.overall_performance,
                'validation_score': result.validation_report.validation_score,
                'passes_validation': result.validation_report.passes_validation,
                'n_realizations': result.validation_report.n_realizations
            }
            
            # Add output summary
            summary['outputs'] = {
                'parameter_manifest_available': result.parameter_manifest is not None,
                'html_report_available': result.html_report is not None,
                'plots_generated': len(result.plots),
                'plot_types': list(result.plots.keys())
            }
        else:
            summary['error'] = result.error_message
        
        # Add metadata summary
        summary['metadata'] = {
            'warnings_count': len(result.metadata.warnings),
            'fallbacks_used_count': len(result.metadata.fallbacks_used),
            'precipgen_version': result.metadata.precipgen_version
        }
        
        return summary


# Convenience functions for common use cases
def analyze_location(location: Union[str, Tuple[float, float]], 
                    **kwargs) -> AnalysisResult:
    """
    Convenience function for quick analysis of a single location.
    
    Args:
        location: Location to analyze
        **kwargs: Additional arguments passed to analyze_precipitation
        
    Returns:
        AnalysisResult from the analysis
    """
    api = ConvenienceAPI()
    return api.analyze_precipitation(location, **kwargs)


def discover_nearby_stations(location: Union[str, Tuple[float, float]],
                           max_distance_km: float = 50) -> List[StationCandidate]:
    """
    Convenience function to discover stations near a location.
    
    Args:
        location: Location to search around
        max_distance_km: Maximum search distance
        
    Returns:
        List of candidate stations
    """
    api = ConvenienceAPI()
    requirements = StationRequirements(max_distance_km=max_distance_km)
    return api.discover_stations(location, requirements)


def quick_station_preview(station_id: str) -> StationPreview:
    """
    Convenience function for quick station preview.
    
    Args:
        station_id: Station ID to preview
        
    Returns:
        StationPreview with basic information
    """
    api = ConvenienceAPI()
    return api.preview_station_data(station_id, show_plots=False)


# API Documentation and Usage Examples
"""
PrecipGen Convenience API - Complete Usage Guide

The PrecipGen Convenience API provides a unified interface for precipitation analysis
that transforms the existing PrecipGen core library into a complete analysis platform.

## Quick Start Examples

### 1. Fully Automated Analysis
```python
from precipgen.convenience.api import ConvenienceAPI

# Initialize API
api = ConvenienceAPI()

# Analyze a location with automatic station selection
result = api.analyze_precipitation("Seattle, WA")

# Check results
if result.success:
    print(f"Analysis completed for station {result.station_info.id}")
    print(f"Data quality score: {result.station_info.data_quality_score:.2f}")
    if result.trend_analysis and result.trend_analysis.has_significant_trends:
        print("Significant climate trends detected!")
    print(f"HTML report: {result.html_report}")
else:
    print(f"Analysis failed: {result.error_message}")
```

### 2. Semi-Interactive Workflow
```python
# Discover candidate stations
candidates = api.discover_stations("Portland, OR")

# Review candidates and select one
for i, candidate in enumerate(candidates[:3]):
    print(f"{i+1}. {candidate.name} ({candidate.id})")
    print(f"   Distance: {candidate.distance_km:.1f} km")
    print(f"   Quality: {candidate.recommendation}")
    print(f"   Data: {candidate.first_year}-{candidate.last_year}")

# Use specific station
result = api.analyze_precipitation("Portland, OR", station_id=candidates[0].id)
```

### 3. Expert Configuration
```python
from precipgen.convenience.config import AnalysisConfig, ValidationConfig

# Custom configuration
config = AnalysisConfig(
    min_years_data=25,
    trend_window_years=40,
    validation_realizations=200,
    parallel_execution=True
)

# Analyze with custom settings
result = api.analyze_precipitation(
    location=(47.6062, -122.3321),  # Seattle coordinates
    analysis_config=config,
    station_id="USW00024233"  # Sea-Tac Airport
)
```

### 4. Batch Processing
```python
from precipgen.convenience.batch_processor import BatchProcessor

# Multiple locations
locations = [
    "Seattle, WA",
    "Portland, OR", 
    "San Francisco, CA",
    "Los Angeles, CA"
]

# Batch analysis
batch_processor = BatchProcessor()
batch_results = batch_processor.analyze_multiple_locations(
    locations,
    generate_summary=True
)

print(f"Success rate: {batch_results.success_rate:.1f}%")
print(f"Index report: {batch_results.index_report_path}")
```

## Configuration Options

### AnalysisConfig
- `min_years_data`: Minimum years of data required (default: 15)
- `search_radius_km`: Maximum search radius for stations (default: 50)
- `wet_day_threshold`: Precipitation threshold for wet days (default: 0.1 mm)
- `trend_window_years`: Window for trend analysis (default: 30)
- `validation_realizations`: Number of validation simulations (default: 100)
- `parallel_execution`: Enable parallel processing (default: True)

### StationRequirements
- `max_distance_km`: Maximum distance from target location
- `min_years_data`: Minimum data years required
- `min_data_completeness`: Minimum data completeness fraction
- `required_elements`: Required GHCN data elements

### OutputConfig
- `output_directory`: Directory for output files
- `generate_plots`: Whether to generate visualization plots
- `plot_formats`: List of plot formats ('png', 'pdf', 'svg')
- `embed_plots_in_html`: Whether to embed plots in HTML reports

## Error Handling

The API provides comprehensive error handling with specific exception types:

```python
from precipgen.convenience.exceptions import (
    ConvenienceAPIError, StationDiscoveryError, 
    GeocodingError, WorkflowError
)

try:
    result = api.analyze_precipitation("Invalid Location")
except GeocodingError as e:
    print(f"Location not found: {e}")
except StationDiscoveryError as e:
    print(f"No suitable stations: {e}")
except WorkflowError as e:
    print(f"Analysis workflow failed: {e}")
except ConvenienceAPIError as e:
    print(f"API error: {e}")
    print(f"Guidance: {e.guidance}")
```

## Advanced Features

### Component Status Checking
```python
status = api.get_component_status()
if not status['overall']['all_components_available']:
    print("Missing components:", status['overall']['missing_components'])
```

### Configuration Diagnosis
```python
config = AnalysisConfig(validation_realizations=1000)  # High value
diagnosis = api.diagnose_configuration(config)

if diagnosis['warnings']:
    for warning in diagnosis['warnings']:
        print(f"Warning: {warning}")

for rec in diagnosis['recommendations']:
    print(f"Recommendation: {rec}")
```

### Processing Time Estimation
```python
estimate = api.estimate_processing_time("Denver, CO")
print(f"Estimated time: {estimate['total_estimate_minutes']:.1f} minutes")
```

### Analysis Summary
```python
result = api.analyze_precipitation("Chicago, IL")
summary = api.create_analysis_summary(result)

print(f"Location: {summary['location']}")
print(f"Success: {summary['success']}")
print(f"Processing time: {summary['processing_time']:.1f}s")
if 'trends' in summary:
    print(f"Trends found: {summary['trends']['significant_trends_found']}")
```

## Integration with Core PrecipGen

The convenience API seamlessly integrates with core PrecipGen components:

```python
# Access core components through the result
if result.success:
    # Parameter manifest for simulation
    manifest = result.parameter_manifest
    
    # Use with core simulation engine
    from precipgen.engines.simulation import SimulationEngine
    
    engine = SimulationEngine()
    synthetic_data = engine.generate_synthetic_precipitation(
        manifest, 
        years=10,
        trend_mode=result.has_trends
    )
```

## Best Practices

1. **Start Simple**: Begin with fully automated analysis, then customize as needed
2. **Check Component Status**: Verify all components are available before production use
3. **Validate Configuration**: Use `diagnose_configuration()` to check settings
4. **Handle Errors Gracefully**: Implement proper exception handling
5. **Review Results**: Always check `result.success` and validation reports
6. **Use Batch Processing**: For multiple locations, use BatchProcessor for efficiency
7. **Monitor Performance**: Use time estimation for planning large analyses

## Troubleshooting

### Common Issues

1. **No Stations Found**: Increase search radius or check location spelling
2. **Poor Data Quality**: Try different stations or adjust quality thresholds  
3. **Long Processing Times**: Reduce validation realizations or enable parallelization
4. **Trend Analysis Fails**: Check if sufficient historical data is available
5. **Validation Fails**: Review station data quality and consider different station

### Getting Help

```python
# Get supported location formats
location_info = api.get_supported_locations()
print(location_info['text_formats'])

# Get version information
version_info = api.get_version_info()
print(f"API version: {version_info['convenience_api']}")

# Get workflow options
workflow_options = api.get_available_workflow_options()
```

For more detailed information, see the individual component documentation
and the PrecipGen core library documentation.
"""