"""
World Bank API Provider

Provides access to World Bank development indicators and data.
Supports country data, indicators, and time series queries.

API Documentation: https://datahelpdesk.worldbank.org/knowledgebase/articles/889392-about-the-indicators-api-documentation
"""

import logging
from typing import Any, Dict, List, Optional, Tuple

from aiecs.tools.apisource.providers.base import BaseAPIProvider, expose_operation

logger = logging.getLogger(__name__)

# Optional HTTP client
try:
    import requests
    REQUESTS_AVAILABLE = True
except ImportError:
    REQUESTS_AVAILABLE = False


class WorldBankProvider(BaseAPIProvider):
    """
    World Bank API provider for development indicators and country data.
    
    Provides access to:
    - Economic indicators (GDP, inflation, trade, etc.)
    - Social indicators (education, health, population)
    - Environmental data
    - Country-specific statistics
    """
    
    BASE_URL = "https://api.worldbank.org/v2"
    
    @property
    def name(self) -> str:
        return "worldbank"
    
    @property
    def description(self) -> str:
        return "World Bank API for global development indicators and country statistics"
    
    @property
    def supported_operations(self) -> List[str]:
        return [
            'get_indicator',
            'search_indicators',
            'get_country_data',
            'list_countries',
            'list_indicators'
        ]
    
    def validate_params(self, operation: str, params: Dict[str, Any]) -> Tuple[bool, Optional[str]]:
        """Validate parameters for World Bank operations"""
        
        if operation == 'get_indicator':
            if 'indicator_code' not in params:
                return False, "Missing required parameter: indicator_code"
            if 'country_code' not in params:
                return False, "Missing required parameter: country_code"
        
        elif operation == 'get_country_data':
            if 'country_code' not in params:
                return False, "Missing required parameter: country_code"
        
        elif operation == 'search_indicators':
            if 'search_text' not in params:
                return False, "Missing required parameter: search_text"
        
        return True, None

    # Exposed operations for AI agent visibility

    @expose_operation(
        operation_name='get_indicator',
        description='Get World Bank development indicator data for a specific country and indicator'
    )
    def get_indicator(
        self,
        indicator_code: str,
        country_code: str,
        start_year: Optional[int] = None,
        end_year: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        Get World Bank indicator data.

        Args:
            indicator_code: World Bank indicator code (e.g., 'NY.GDP.MKTP.CD', 'SP.POP.TOTL')
            country_code: ISO 3-letter country code (e.g., 'USA', 'CHN', 'GBR')
            start_year: Start year for data range
            end_year: End year for data range

        Returns:
            Dictionary containing indicator data and metadata
        """
        params = {
            'indicator_code': indicator_code,
            'country_code': country_code
        }
        if start_year:
            params['start_year'] = start_year
        if end_year:
            params['end_year'] = end_year

        return self.execute('get_indicator', params)

    @expose_operation(
        operation_name='search_indicators',
        description='Search for World Bank indicators by keywords'
    )
    def search_indicators(
        self,
        search_text: str,
        limit: Optional[int] = None
    ) -> Dict[str, Any]:
        """
        Search for World Bank indicators.

        Args:
            search_text: Search keywords (e.g., 'GDP', 'population', 'education')
            limit: Maximum number of results to return

        Returns:
            Dictionary containing search results and metadata
        """
        params = {'search_text': search_text}
        if limit:
            params['limit'] = limit

        return self.execute('search_indicators', params)

    @expose_operation(
        operation_name='get_country_data',
        description='Get general information and statistics about a specific country'
    )
    def get_country_data(self, country_code: str) -> Dict[str, Any]:
        """
        Get country data and metadata.

        Args:
            country_code: ISO 3-letter country code (e.g., 'USA', 'CHN')

        Returns:
            Dictionary containing country information
        """
        return self.execute('get_country_data', {'country_code': country_code})

    @expose_operation(
        operation_name='list_countries',
        description='List all available countries in the World Bank database'
    )
    def list_countries(self) -> Dict[str, Any]:
        """
        List all available countries.

        Returns:
            Dictionary containing list of countries
        """
        return self.execute('list_countries', {})

    @expose_operation(
        operation_name='list_indicators',
        description='List all available World Bank indicators'
    )
    def list_indicators(self, limit: Optional[int] = None) -> Dict[str, Any]:
        """
        List all available indicators.

        Args:
            limit: Maximum number of indicators to return

        Returns:
            Dictionary containing list of indicators
        """
        params = {}
        if limit:
            params['limit'] = limit

        return self.execute('list_indicators', params)

    def fetch(self, operation: str, params: Dict[str, Any]) -> Dict[str, Any]:
        """Fetch data from World Bank API"""
        
        if not REQUESTS_AVAILABLE:
            raise ImportError("requests library is required for World Bank provider")
        
        # World Bank API doesn't require API key for most operations
        timeout = self.config.get('timeout', 30)
        
        # Build endpoint based on operation
        if operation == 'get_indicator':
            country = params['country_code']
            indicator = params['indicator_code']
            endpoint = f"{self.BASE_URL}/country/{country}/indicator/{indicator}"
            query_params = {'format': 'json'}
            
            # Optional parameters
            if 'date' in params:
                query_params['date'] = params['date']
            if 'per_page' in params:
                query_params['per_page'] = params['per_page']
        
        elif operation == 'get_country_data':
            country = params['country_code']
            endpoint = f"{self.BASE_URL}/country/{country}"
            query_params = {'format': 'json'}
        
        elif operation == 'list_countries':
            endpoint = f"{self.BASE_URL}/country"
            query_params = {'format': 'json', 'per_page': params.get('per_page', 100)}
        
        elif operation == 'list_indicators':
            endpoint = f"{self.BASE_URL}/indicator"
            query_params = {'format': 'json', 'per_page': params.get('per_page', 100)}
        
        elif operation == 'search_indicators':
            # World Bank doesn't have direct search, so we list and filter
            endpoint = f"{self.BASE_URL}/indicator"
            query_params = {'format': 'json', 'per_page': 1000}
        
        else:
            raise ValueError(f"Unknown operation: {operation}")
        
        # Make API request
        try:
            response = requests.get(
                endpoint,
                params=query_params,
                timeout=timeout
            )
            response.raise_for_status()
            
            data = response.json()
            
            # World Bank API returns [metadata, data]
            if isinstance(data, list) and len(data) > 1:
                result_data = data[1]
            else:
                result_data = data
            
            # Filter for search operation
            if operation == 'search_indicators' and result_data:
                search_text = params['search_text'].lower()
                filtered = [
                    item for item in result_data
                    if search_text in str(item.get('name', '')).lower() or
                       search_text in str(item.get('sourceNote', '')).lower()
                ]
                result_data = filtered[:params.get('limit', 20)]
            
            return self._format_response(
                operation=operation,
                data=result_data,
                source=f"World Bank API - {endpoint}"
            )
            
        except requests.exceptions.RequestException as e:
            self.logger.error(f"World Bank API request failed: {e}")
            raise Exception(f"World Bank API request failed: {str(e)}")

    def get_operation_schema(self, operation: str) -> Optional[Dict[str, Any]]:
        """Get detailed schema for World Bank operations"""

        schemas = {
            'get_indicator': {
                'description': 'Get World Bank development indicator data',
                'parameters': {
                    'indicator_code': {
                        'type': 'string',
                        'required': True,
                        'description': 'World Bank indicator code',
                        'examples': ['NY.GDP.MKTP.CD', 'SP.POP.TOTL', 'SE.PRM.ENRR']
                    },
                    'country_code': {
                        'type': 'string',
                        'required': True,
                        'description': 'ISO 3-letter country code',
                        'examples': ['USA', 'CHN', 'GBR', 'IND']
                    },
                    'start_year': {
                        'type': 'integer',
                        'required': False,
                        'description': 'Start year for data range',
                        'examples': [2010, 2015, 2020]
                    },
                    'end_year': {
                        'type': 'integer',
                        'required': False,
                        'description': 'End year for data range',
                        'examples': [2020, 2023, 2025]
                    }
                }
            },
            'search_indicators': {
                'description': 'Search for World Bank indicators by keywords',
                'parameters': {
                    'search_text': {
                        'type': 'string',
                        'required': True,
                        'description': 'Search keywords',
                        'examples': ['GDP', 'population', 'education', 'health']
                    },
                    'limit': {
                        'type': 'integer',
                        'required': False,
                        'description': 'Maximum number of results',
                        'examples': [10, 20, 50],
                        'default': 20
                    }
                }
            },
            'get_country_data': {
                'description': 'Get country information and metadata',
                'parameters': {
                    'country_code': {
                        'type': 'string',
                        'required': True,
                        'description': 'ISO 3-letter country code',
                        'examples': ['USA', 'CHN', 'GBR']
                    }
                }
            },
            'list_countries': {
                'description': 'List all available countries',
                'parameters': {}
            },
            'list_indicators': {
                'description': 'List all available indicators',
                'parameters': {
                    'limit': {
                        'type': 'integer',
                        'required': False,
                        'description': 'Maximum number of indicators',
                        'examples': [50, 100, 200],
                        'default': 100
                    }
                }
            }
        }

        return schemas.get(operation)

